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;
}
}
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.
Try to use cardElevation=0dp. This should remove the extra spacing between recyclerview items.
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? 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.
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.
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.
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];
}
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]));
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
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With