Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Horizontal RecyclerView with items that have dynamic height

So I need a horizontal RecyclerView. However, the items in them have dynamic heights based on what's returned from the backend.

The RecyclerView and its items have the height of "wrap_content"

The problem is if the first visible items in the RecyclerView are small, then when the user scrolls to the larger items, they appear cut off.

Ideally, we want the RecyclerView to be large enough to hold the largest item in the group (but only the largest existing item... not the hypothetically largest item). The RecyclerView dynamically changing its height is also acceptable.

I wrote an example app to illustrate the problem. In this app, we have a horizontal list. The first 33 items should show 1 line of text, while the next should show 3 lines of text, and the last 34 should show 2 lines. However, they all show 1 line, because the height of the RecyclerView doesn't change.

I've tried calling requestLayout() on the RecyclerView (and on the TextView) from onBindViewHolder(), but it doesn't seem to do anything.

MainActivity:

public class MainActivity extends AppCompatActivity {      private RecyclerView mRecyclerView;     private RecyclerView.Adapter mAdapter;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);          mAdapter = createAdapter();          mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);         mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));         mRecyclerView.setAdapter(mAdapter);     }      private RecyclerView.Adapter<ViewHolder> createAdapter() {         RecyclerView.Adapter adapter = new RecyclerView.Adapter<ViewHolder>() {             @Override             public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {                 View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);                 return new ViewHolder(v);             }              @Override             public void onBindViewHolder(ViewHolder holder, int position) {                 if (position < 33) {                     holder.mText.setText("1 line");                 } else if (position > 66) {                     holder.mText.setText("2 lines\n2 lines");                 } else {                     holder.mText.setText("3 lines\n3 lines\n3 lines");                 }             }              @Override             public int getItemCount() {                 return 100;             }         };         return adapter;     }      private static class ViewHolder extends RecyclerView.ViewHolder {         TextView mText;         public ViewHolder(View itemView) {             super(itemView);             mText = (TextView) itemView.findViewById(R.id.text);         }     } } 

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:id="@+id/activity_main"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:paddingBottom="@dimen/activity_vertical_margin"     android:paddingLeft="@dimen/activity_horizontal_margin"     android:paddingRight="@dimen/activity_horizontal_margin"     android:paddingTop="@dimen/activity_vertical_margin">      <android.support.v7.widget.RecyclerView         android:id="@+id/recycler_view"         android:layout_width="wrap_content"         android:layout_height="wrap_content" /> </RelativeLayout> 

item.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:orientation="vertical" android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:background="#888888">     <TextView         android:id="@+id/text"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="Hi"         android:textSize="30sp" />  </LinearLayout> 
like image 400
Gak2 Avatar asked Feb 16 '17 22:02

Gak2


1 Answers

Change your item.xml layout content with the below code. It will solve your issue.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:orientation="vertical" android:layout_width="160dp"     android:layout_height="match_parent"     android:background="#888888">     <TextView         android:id="@+id/text"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="Hi"         android:textSize="30sp" />  </LinearLayout> 
like image 177
Yahya M Avatar answered Sep 21 '22 14:09

Yahya M