Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set different height for each items in recycler View

I want to set a different height for each item in a recycler view. Normally we are getting the same height for every row. But I need different heights, for instance, if the first three rows are 70 in height then I need the remaining with height 0. My code is as follows. In this code its not set properly. Please suggest me an edit

public class MainActivity extends AppCompatActivity {

private RecyclerView rvListProfiles;
private ListProfileAdapter listProfileAdapter;
private String[] list = new String[]{"ABC","DEF","GHI","JKL","MNO"};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    rvListProfiles = findViewById(R.id.rvListProfiles);

    listProfileAdapter = new ListProfileAdapter(list, this);
    RecyclerView.LayoutManager mLayoutManager = new 
    LinearLayoutManager(getApplicationContext());
    rvListProfiles.setLayoutManager(mLayoutManager);
    rvListProfiles.setItemAnimator(new DefaultItemAnimator());
    rvListProfiles.setAdapter(listProfileAdapter);
    String listString = Arrays.toString(list);
    System.out.println("List "+listString);
}
}

item xml

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="70dp"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:background="@android:color/darker_gray"
    android:padding="10dp"
    android:id="@+id/parentLayout">

<ImageView
    android:id="@+id/profileImage"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignParentStart="true"
    android:layout_centerVertical="true"
    android:src="@mipmap/love"
    android:transitionName="imageTransition" />

<TextView
    android:id="@+id/profileName"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_marginStart="23dp"
    android:layout_toEndOf="@+id/profileImage"
    android:padding="2dp"
    android:text="TextView"
    android:textColor="@android:color/background_light"
    android:textSize="18sp"
    android:transitionName="nameTransition" />

<TextView
    android:id="@+id/profileDesc"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/profileImage"
    android:layout_alignStart="@+id/profileName"
    android:layout_marginTop="5dp"
    android:maxLines="1"
    android:padding="2dp"
    android:text="@string/dummy_data"
    android:textColor="@android:color/background_light"
    android:textSize="12sp"
    android:transitionName="descTransition" />

   </RelativeLayout>

ViewHolder class

public class ListProfileViewHolder extends RecyclerView.ViewHolder {

public ImageView profileImage;
public TextView profileName;
public TextView profileDesc;
public RelativeLayout parentLayout;
public Context context;

public ListProfileViewHolder(View itemView, Context mContext) {
    super(itemView);
    this.context = mContext;
    profileImage = itemView.findViewById(R.id.profileImage);
    profileName = itemView.findViewById(R.id.profileName);
    profileDesc = itemView.findViewById(R.id.profileDesc);
    parentLayout = itemView.findViewById(R.id.parentLayout);
}

}

Adapter Class

public class ListProfileAdapter extends 
RecyclerView.Adapter<ListProfileViewHolder> {

private String[] list;
private Context mContext;
private int height[] = {70,70,70,
                        0,0,0,0};

public ListProfileAdapter(String[] list, Context mContext) {
    this.list = list;
    this.mContext = mContext;
}

@Override
public ListProfileViewHolder onCreateViewHolder(ViewGroup parent, int 
viewType) {
    View layoutView = 
LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, 
null);
    return new ListProfileViewHolder(layoutView, mContext);
}

@Override
public void onBindViewHolder(final ListProfileViewHolder holder, int 
position) {


    holder.parentLayout.setLayoutParams(new 
RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
            height[position]));
    holder.profileName.setText(list[position]);
    holder.profileImage.setOnClickListener(new View.OnClickListener() 
{
     @Override
     public void onClick(View view) {
         Intent sharedIntent = new 
Intent(mContext,SharedActivity.class);
         sharedIntent.putExtra("name",holder.profileName.getText());
         sharedIntent.putExtra("desc",holder.profileDesc.getText());
         Pair[] pairs = new Pair[3];
         pairs[0] = new Pair<View,String> 
(holder.profileImage,"imageTransition");
         pairs[1] = new Pair<View,String> 
(holder.profileName,"nameTransition");
         pairs[2] = new Pair<View,String> 
(holder.profileDesc,"descTransition");

         ActivityOptions options = 
ActivityOptions.makeSceneTransitionAnimation((Activity) 
mContext,pairs);
         mContext.startActivity(sharedIntent,options.toBundle());
     }
 });
    holder.parentLayout.setOnClickListener(new View.OnClickListener() 
{
        @Override
        public void onClick(View view) {
            height = new int[]{0,0,0,
                    70,70,70,70,};
            notifyDataSetChanged();
        }
    });
}

@Override
public int getItemCount() {
    return list.length;
}
}
like image 465
Rahul Surendran Avatar asked Sep 24 '18 06:09

Rahul Surendran


People also ask

How do I change the size of the RecyclerView?

If you just want your recycler view to size automatically as per number of items then, why don't you put RecyclerView height as wrap_content. If you have multiple ScrollView in layout then try wrapping RecyclerView in NestScrollView and set it's height as wrap_content too.

How do I reduce space between items in RecyclerView?

Try to use cardElevation=0dp. This should remove the extra spacing between recyclerview items.

What if recyclerview have only 30% of screen width and 40% height?

will not works if RecyclerView contains NOT whole screen. What if RecyclerView have only 30% of screen width and 40% of screen height (for sample)? for those who want to do it in the xml layout (recyclerView item) file you can use a ConstraintLayout by combining and don't forget to provide all the constraint that way you can set

How to add dividers and spaces between items in recyclerview?

How to add dividers and spaces between items in RecyclerView? This example demonstrate about How to add dividers and spaces between items in RecyclerView Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project.

How to draw top margin in recyclerview?

Use decorator item. Add the below class below. There’s a logic that draw margin on left, right and bottom. The top margin would only be drawn for the first cell. Now you have your custom decorator, then add it to your recyclerView as below. You would do it when you setup your recyclerView layout manager etc. That’s it. All done.

Can a recyclerview have multiple viewTypes?

This list can have either all similar layouts or multiple distinct layouts. Here, such a RecyclerView with multiple ViewTypes is developed. Following is an example of Android RecyclerView with multiple views.


4 Answers

try like this.

holder.parentLayout.requestLayout();
            if (position == 0 || position==1 || position==2) {
                holder.parentLayout.getLayoutParams().height = height[position];
            } else {
                holder.parentLayout.getLayoutParams().height = height[position];
            }
like image 110
Harshil kakadiya Avatar answered Sep 28 '22 14:09

Harshil kakadiya


The height in .xml is in dp(70dp), while in coding is in pixel. So, to get the the size correctly, you need to convert dp to px then apply it programmatically:

Convert dp to px:

public int DpToPx(Activity activity, int dp){
    Resources r  = activity.getResources();
    int px    = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
    return px;

}

then apply to your layout param:

holder.parentLayout.setLayoutParams(newRelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
        DPToPx(activity, height[position]));
like image 20
Alvin Tom Avatar answered Sep 28 '22 13:09

Alvin Tom


You can try StaggeredGridLayoutManager for asymmetric items.

try change this

RecyclerView.LayoutManager mLayoutManager = new 
    LinearLayoutManager(getApplicationContext());

to this

RecyclerView.LayoutManager mLayoutManager = new 
    StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);

Some of the examples:

1: Staggered GridView

2: StaggeredGridLayout

like image 25
oztrna Avatar answered Sep 28 '22 14:09

oztrna


In my case, I added views to FlowLayout, but items have all the same height.

solution: In the item layout xml, use RelativeLayout as root only and ensure the layout whose child view be dynamically added is surrounded with RelativeLayout too.

just like this:

<RelativeLayout>
  ...
  <FlowLayout />

</RelativeLayout>
like image 37
fat eagle Avatar answered Sep 28 '22 12:09

fat eagle