Reputation: 181
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;
}
}
Upvotes: 8
Views: 12373
Reputation: 31
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>
Upvotes: 1
Reputation: 95
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
Upvotes: 1
Reputation: 119
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]));
Upvotes: 1
Reputation: 5025
Since you are updating the Layout size, you need to refresh the UI, try to call this line after the layout size update:
holder.parentLayout.requestLayout(); //It is necesary to refresh the screen
Upvotes: 0
Reputation: 252
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];
}
Upvotes: 3