Gap between CardViews increases on scrolling - android

I'm using CarViews with RecyclerView and it looks fine when loaded but once when the list is scrolled the gap between the CardViews increases and there shows only one card in the view at a time.
Here is my CardView.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.CardView
android:id="#+id/conversationCard"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:id="#+id/sender"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/abstractConvo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="35dp"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
and here is how I'm using that view
public class ConversationsListAdapter extends RecyclerView.Adapter<ConversationsListAdapter.ConversationsListViewHolder> {
List<Conversation> conversationList;
public ConversationsListAdapter(List<Conversation> conversationList) {
this.conversationList = conversationList;
}
#Override
public int getItemCount() {
return conversationList.size();
}
#Override
public ConversationsListViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.conversation_card, viewGroup, false);
ConversationsListViewHolder listViewHolder = new ConversationsListViewHolder(view);
return listViewHolder;
}
#Override
public void onBindViewHolder(ConversationsListViewHolder holder, int position) {
holder.sender.setText(conversationList.get(position).getSenderPhNo());
holder.abstractConvo.setText(conversationList.get(position).getAbstractConvo());
}
public static class ConversationsListViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView abstractConvo, sender;
public ConversationsListViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.conversationCard);
sender = (TextView) itemView.findViewById(R.id.sender);
abstractConvo = (TextView) itemView.findViewById(R.id.abstractConvo);
}
}
}
Here is the screenshot before the list is scrolled
and after scrolling
Thanks in advance.

the root layout use wrap_content
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">

Related

RecyclerView items not in center with GridLayoutManager

i have a RecyclerView with a GridLayoutManager which load items like this:
as you can see there is a margin to left. I didn't add any sort of ItemDecoration to recyclerview and didn't add any margin to any of the layouts here.
i've already tried:
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
and using LinearSnapHelper but none of them fixed it.
item layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="#dimen/_130sdp"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="#dimen/_130sdp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal">
<androidx.cardview.widget.CardView
app:cardPreventCornerOverlap="true"
app:cardElevation="#dimen/_5sdp"
app:cardCornerRadius="#dimen/_3sdp"
android:layout_width="#dimen/_60sdp"
android:layout_height="#dimen/_90sdp"
android:layout_marginTop="#dimen/_20sdp">
<com.makeramen.roundedimageview.RoundedImageView
android:id="#+id/choosestorycoverimage"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:riv_corner_radius="#dimen/_3sdp"
android:scaleType="fitXY"
android:src="#drawable/test"/>
<com.makeramen.roundedimageview.RoundedImageView
android:id="#+id/choosestorycoverimagelayer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:riv_corner_radius="#dimen/_3sdp"
android:visibility="gone"
android:scaleType="fitXY"
android:src="#drawable/choosen_story_layer"/>
</androidx.cardview.widget.CardView>
<TextView
android:id="#+id/choosestorynametext"
android:layout_marginTop="#dimen/_3sdp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/_15sdp"
android:text="text"/>
</LinearLayout>
</RelativeLayout>
activity layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ChooseStoryActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/choosestoryrecyclerview"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_gravity="center_horizontal"
android:layout_height="match_parent" />
</RelativeLayout>
recyclerview adapter:
public class ChooseStoryRecyclerViewAdapter extends RecyclerView.Adapter<ChooseStoryRecyclerViewAdapter.ViewHolder> {
private static final String TAG = "LibraryRecyclerViewAdap";
private ArrayList<String> coverImageUrlList = new ArrayList<>();
private ArrayList<String> nameTextList = new ArrayList<>();
private ArrayList<String> shelfNameList = new ArrayList<>();
private ArrayList<HashSet<String>> shelfStoryIDList = new ArrayList<>();
private HashSet<String> shelfStoryIDSet = new HashSet<>();
private Context context;
public ChooseStoryRecyclerViewAdapter(ArrayList<String> coverImageUrlList, ArrayList<String> nameTextList,Context context) {
this.coverImageUrlList = coverImageUrlList;
this.nameTextList = nameTextList;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.choose_story_item,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
//***********the main method***********
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Glide.with(context)
.asBitmap()
.load(coverImageUrlList.get(position))
.into(holder.coverImage);
holder.coverImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.coverImageLayer.getVisibility() == View.VISIBLE){
holder.coverImageLayer.setVisibility(View.GONE);
}
else{
holder.coverImageLayer.setVisibility(View.VISIBLE);
}
}
});
holder.nameText.setText(nameTextList.get(position));
}
#Override
public int getItemCount() {
return coverImageUrlList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
RoundedImageView coverImage;
TextView nameText;
RoundedImageView coverImageLayer;
public ViewHolder(#NonNull View itemView) {
super(itemView);
coverImage = itemView.findViewById(R.id.choosestorycoverimage);
nameText =itemView.findViewById(R.id.choosestorynametext);
coverImageLayer = itemView.findViewById(R.id.choosestorycoverimagelayer);
}
}
}
Remove these unnecessary attributes from your recyclerView tag:
android:layout_alignParentTop="true"
android:layout_gravity="center_horizontal"
You should change the width of the parent RelativeLayout of your item layout to use match_parent instead of a fixed width and then play with the spanCount attribute of your GridLayoutManager if you want smaller item layout
You should also add the GridLayoutManager directly in your activity_main.xml if you don't really need any Custom GridLayoutManager.
For that, remove the GridLayoutManager from MainActivity.java if you have one and add these two new lines in your recyclerView tag
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="3"

Bug in recycle grid. Changing UI without click randomly

I have a recycler inside fragment in view pager.
The problem that it put likes on user accounts in UI randomly but in DB everything is fine.
In logs, I see that random is not influence on BD. So the bug is only in UI part. After the refresh of the list, it can appear again and after that disappear.
I would like to share code but I already don't have an I idea where the problem could be. It might be in adapter/refresh list listener / XML or any other places. Please let me know what part of the code you need and I will provide it. Maybe it is a bug of recycler as itself and I can't fix it.
Adapter class code:
public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.UserViewHolder>{
private List<FsUser> fsUserList = new ArrayList<>();
private OnItemClickListener.OnItemClickCallback onItemClickCallback;
private OnItemClickListener.OnItemClickCallback onChatClickCallback;
private OnItemClickListener.OnItemClickCallback onLikeClickCallback;
private Context context;
public SearchAdapter(OnItemClickListener.OnItemClickCallback onItemClickCallback,
OnItemClickListener.OnItemClickCallback onChatClickCallback,
OnItemClickListener.OnItemClickCallback onLikeClickCallback) {
this.onItemClickCallback = onItemClickCallback;
this.onChatClickCallback = onChatClickCallback;
this.onLikeClickCallback = onLikeClickCallback;
}
public void addUsers(List<FsUser> userList) {
fsUserList.addAll(userList);
notifyItemRangeInserted(fsUserList.size() - userList.size(), fsUserList.size());
}
public void clearData(){
fsUserList.clear();
notifyDataSetChanged();
}
#NonNull
#Override
public UserViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user, parent, false);
return new UserViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull UserViewHolder holder, int position) {
FsUser fsUser = fsUserList.get(position);
holder.bind(fsUser, position);
}
#Override
public int getItemCount() {
return fsUserList.size();
}
public String getLastItemId(){
return fsUserList.get(fsUserList.size() - 1).getUid();
}
class UserViewHolder extends RecyclerView.ViewHolder {
RelativeLayout container;
ImageView imageView, like, chat;
TextView name, country;
private LottieAnimationView animationView;
UserViewHolder(View itemView) {
super(itemView);
context = itemView.getContext();
container = itemView.findViewById(R.id.item_user_container);
imageView = itemView.findViewById(R.id.user_img);
like = itemView.findViewById(R.id.search_btn_like);
chat = itemView.findViewById(R.id.search_btn_chat);
name = itemView.findViewById(R.id.user_name);
country = itemView.findViewById(R.id.user_country);
animationView = itemView.findViewById(R.id.lottieAnimationView);
}
void bind(FsUser fsUser, int position){
ViewCompat.setTransitionName(imageView, fsUser.getName());
if (FirebaseUtils.isUserExist() && fsUser.getUid() != null) {
new FriendRepository().isLiked(fsUser.getUid(), flag -> {
if (flag) {
like.setBackground(ContextCompat.getDrawable(context, R.drawable.ic_favorite));
animationView.setVisibility(View.VISIBLE);
}
});
}
if(fsUser.getUid() != null) {
chat.setOnClickListener(new OnItemClickListener(position, onChatClickCallback));
like.setOnClickListener(new OnItemClickListener(position, onLikeClickCallback));
}
imageView.setOnClickListener(new OnItemClickListener(position, onItemClickCallback));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
if(fsUser.getImage().equals("default")){
Glide.with(context).load(context.getResources().getDrawable(R.drawable.default_avatar)).into(imageView);
} else {
Glide.with(context).load(fsUser.getImage()).thumbnail(0.5f).into(imageView);
}
name.setText(fsUser.getName());
country.setText(fsUser.getCountry());
ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f).setDuration(500);
animator.addUpdateListener(valueAnimator ->
animationView.setProgress((Float) valueAnimator.getAnimatedValue()));
if (animationView.getProgress() == 0f) {
animator.start();
} else {
animationView.setProgress(0f);
}
}
}
}
And xml file of RecyclerView item:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/item_user_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="#dimen/user_cv_width"
android:layout_height="#dimen/user_cv_height"
android:layout_margin="#dimen/dp4"
android:elevation="#dimen/dp4">
<RelativeLayout
android:id="#+id/item_user_main_relative_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/item_user_top_relative_container"
android:layout_width="#dimen/user_rl_width"
android:layout_height="#dimen/user_rl_height">
<ImageView
android:id="#+id/user_img"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="#drawable/default_avatar" />
<RelativeLayout
android:id="#+id/item_user_top_relative"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/user_item_bg"
android:orientation="vertical">
<TextView
android:id="#+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/dp4"
android:textColor="#android:color/white"
android:textSize="#dimen/medium_text_size" />
<TextView
android:id="#+id/user_country"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:layout_marginStart="#dimen/dp4"
android:textSize="#dimen/medium_text_size" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="#+id/item_user_bottom_relative_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/dp12">
<ImageView
android:id="#+id/search_btn_like"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/heart_outline"
android:contentDescription="#string/search_btn_like_desc"/>
<com.airbnb.lottie.LottieAnimationView
android:id="#+id/lottieAnimationView"
android:visibility="gone"
android:layout_width="#dimen/lottie_animation_view_size"
android:layout_height="#dimen/lottie_animation_view_size"
app:lottie_loop="true"
app:lottie_autoPlay="true"
app:lottie_fileName="like.json"/>
</RelativeLayout>
<ImageView
android:id="#+id/search_btn_chat"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="#dimen/dp12"
android:layout_weight="1"
android:src="#drawable/message_outline" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
Override this two methods inside your adapter
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}

RecyclerView strange behaviour inflating cells

I have this layout in two apps, one inside a RecyclerView and the other in a root activity layout.
Here the layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:orientation="vertical"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:background="#CFCFCF"
android:minHeight="250dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_red_dark"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_bright"
android:layout_above="#+id/commerceTextView"
>
<ImageView
android:src="#drawable/imagen"
android:id="#+id/commerceImageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/commerceTextView"
android:gravity="center"
android:textStyle="bold"
android:textSize="24sp"
android:textColor="#F1F1F1"
android:background="#color/colorPrimary"
android:layout_alignParentBottom="true"
android:paddingTop="10dp"
android:text="Best food ever"
android:paddingBottom="10dp"/>
</RelativeLayout>
</FrameLayout>
Here the adapter
public class CommercesAdapter extends RecyclerView.Adapter<CommercesAdapter.CommercesViewHolder> {
private final Context context;
private final ImageLoader loader;
private List<CommerceEntity> commercesList;
#Inject
public CommercesAdapter(Context context, ImageLoader loader) {
this.context = context;
this.loader = loader;
}
public void setData(List<CommerceEntity> commercesList) {
this.commercesList = commercesList;
}
#Override
public CommercesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context)
.inflate(R.layout.list_comerces_item, parent, false);
return new CommercesViewHolder(view);
}
#Override
public void onBindViewHolder(CommercesViewHolder holder, int position) {
CommerceEntity commerce = commercesList.get(position);
String imageUri = commerce.getImageUri();
String name = commerce.getName();
// holder.commerceTypeName.setText(name);
//loader.bind(holder.commerceImage, imageUri);
}
#Override
public int getItemCount() {
return commercesList.size();
}
public static class CommercesViewHolder extends RecyclerView.ViewHolder {
public ImageView commerceImage;
public TextView commerceTypeName;
public CommercesViewHolder(View itemView) {
super(itemView);
commerceImage = (ImageView) itemView.findViewById(R.id.commerceImageView);
commerceTypeName = (TextView) itemView.findViewById(R.id.commerceTextView);
}
}
Here the RecyclerView
And here in a root activity layout
Someone knows why this happen? if I add android:centerInParent"true" to the nested FrameLayout the image appears but i don't understand why.
In your adapter, uncomment the two lines that you have commented out;
`
// holder.commerceTypeName.setText(name);
//loader.bind(holder.commerceImage, imageUri);
`

Populate RecyclerView and CardView with ArrayList<String>

I have a cardview with 2 textviews inside. The first textview displays the name of a contact and the second displays the phone number. I want to use an ArrayList to populate the recyclerview.
I'm still new to Android programming so I don't know how to implement RecyclerView or make an adapter that will alternate between name and number filling in the textview. How can I achieve this?
My CardView (card_row.xml)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:clickable="true"
android:orientation="horizontal"
card_view:cardCornerRadius="0dp"
card_view:cardUseCompatPadding="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:selectableItemBackground"
android:orientation="vertical">
<TextView
android:id="#+id/text1"
android:layout_width="match_parent"
android:layout_height="38dp"
android:layout_margin="5dp"
android:gravity="left"
android:textColor="#android:color/black"
android:textSize="24sp" />
<TextView
android:id="#+id/text2"
android:layout_width="match_parent"
android:layout_height="37dp"
android:layout_margin="5dp"
android:layout_below="#id/text1"
android:textColor="#android:color/darker_gray"
android:textSize="18sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
EDIT:
I made 2 arraylists, one for names and the other for numbers. Now I how do I populate the recyclerview?
OK First make a inner class. This will be your adapter change all the id:
class Adapter extends RecyclerView.Adapter<LibraryAdapter.MyViewHolder>{
LayoutInflater inflater;
public LibraryAdapter(Context context){
inflater = LayoutInflater.from(context);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view =inflater.inflate(R.layout.main_exerciselibrary_fragment_singlerow,parent,false);
MyViewHolder holder=new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Exercises exercises = new Exercises(getActivity());
ArrayList<String> arrayList1 = new ArrayList<String>();
ArrayList<String> arrayList2 = new ArrayList<String>();
holder.Name.setText(arrayList1.get(position));
holder.PhoneNumber.setText(arrayList2.get(position));
}
#Override
public int getItemCount() {
return array.lenght;
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView Name, PhoneNumber;
CardView card;
public MyViewHolder(View itemView) {
super(itemView);
PhoneNumber= (TextView) itemView.findViewById(R.id.imageViewPicLibrary);//change Here
Name = (TextView) itemView.findViewById(R.id.textViewExerciseLibraryExerciseName);//change Here
card= (CardView) itemView.findViewById(R.id.card_view_ex_lib);//change Here
card.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//OnClick
}
});
}
}
}
I think this is all.

RecyclerView Showing weird behavior on expanding CardView Android

<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingTop="#dimen/activity_horizontal_margin"
android:background="#android:color/transparent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/string_for_newsletter"
android:paddingLeft="16dp"
android:id="#+id/textQuestion"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/bookmark_star"
android:layout_alignParentRight="true"
android:background="#android:color/transparent"
android:layout_alignParentBottom="true"
android:id="#+id/bookmarkButton"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/textQuestion"
android:text="answer"
android:paddingLeft="16dp"
android:paddingTop="16dp"
android:textColor="#00ff00"
android:visibility="gone"
android:id="#+id/textAnswer"/>
</RelativeLayout>
this is my layout for card view
and below is the code for RecyclerView Adapter
package com.example.user_2.tcc_app.QuestionAnswer;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
import com.example.user_2.tcc_app.R;
/**
* Created by USER-2 on 23-Feb-15.
*/
public class QuestionAnswerAdapter extends RecyclerView.Adapter<QuestionAnswerAdapter.QuestionAnswerAdapterViewHolder>{
int length;
int layout_id;
public long item_id;
public QuestionAnswerAdapter(int length, int id_for_layout){
this.length = length;
this.layout_id = id_for_layout;
}
#Override
public QuestionAnswerAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View root = LayoutInflater.from(parent.getContext()).inflate(layout_id, parent, false);
QuestionAnswerAdapterViewHolder questionAnswerAdapterViewHolder = new QuestionAnswerAdapterViewHolder(root);
return questionAnswerAdapterViewHolder;
}
#Override
public void onBindViewHolder(final QuestionAnswerAdapterViewHolder holder, int position) {
}
#Override
public int getItemCount() {
return length;
}
public class QuestionAnswerAdapterViewHolder extends RecyclerView.ViewHolder{
TextView textQuestion;
ImageButton bookmarkButton;
TextView textAnswer;
public QuestionAnswerAdapterViewHolder(View v){
super(v);
textQuestion = (TextView)v.findViewById(R.id.textQuestion);
bookmarkButton = (ImageButton)v.findViewById(R.id.bookmarkButton);
textAnswer = (TextView)v.findViewById(R.id.textAnswer);
textQuestion.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
textAnswer.setVisibility(View.GONE);
}
});
}
}
}
I have 10 Items in the recyclerview. I want to show the textview with id textAnswer when textQuestion is clicked and every thing is working fine till now but when i scroll down i can see that ninth item also has the textAnswer field visible. I can understand that this is happening due to onBindViewHolder Method as recyclerView while recycling its item uses previously visible items which are not visible any more. But i have no clue on how to sort it out. Some one please help
The RecyclerView re-uses the ViewHolders so the trick is to set the expandable area to VISIBLE/GONE inside the onBindViewHolder() method. Hopefully you solved your problem by now but for those who run into similar issues like me, a functional example:
An example of an adapter with expendable cardViews:
public class FooAdapter extends RecyclerView.Adapter<FooAdapter.ViewHolder> {
List<LightGroup> mFoos;
List<Boolean> mExpandedFoos;
public GroupAdapter(List<Foo> Foos) {
mFoos = foos;
mExpandedFoos = new ArrayList<>(mFoos.size());
for(int i = 0; i < mGroups.size(); i++){
mExpandedFoos.add(false);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.foo_row, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
if(mExpandedFoos.get(position)) {
holder.expandableLayout.setVisibility(View.VISIBLE);
} else {
holder.expandableLayout.setVisibility(View.GONE);
}
Foo foo = mFoos.get(position);
holder.fooName.setText(foo.getName());
//Setup the rest of your row views from your Foo object
}
#Override
public int getItemCount() {
return mFoos == null ? 0 : mFoos.size();
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView fooName;
ViewGroup expandableLayout;
ImageButton expandButton;
public ViewHolder(View itemView) {
super(itemView);
fooName = (TextView) itemView.findViewById(R.id.foo_name_textview);
expandableLayout = (ViewGroup) itemView.findViewById(R.id.expandable_part_layout);
expandButton = (ImageButton) itemView.findViewById(R.id.foo_row_expand_button);
expandButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int position = getAdapterPosition();
if(v.getId() == expandButton.getId()){
if(mExpandedFoos.get(position)) {
expandableLayout.setVisibility(View.GONE);
} else {
expandableLayout.setVisibility(View.VISIBLE);
}
mExpandedFoos.set(position, !mExpandedFoos.get(position));
}
}
}
}
With layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="4dp"
app:cardPreventCornerOverlap="false"
android:background="#android:color/background_dark"
android:layout_marginBottom="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/top_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="false"
android:layout_alignParentTop="true">
<TextView
android:id="#+id/foo_name_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="#dimen/activity_horizontal_margin"
android:paddingEnd="#dimen/activity_horizontal_margin"
android:gravity="center"/>
<ImageButton
android:id="#+id/foo_row_expand_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="?android:selectableItemBackground"
android:clickable="true"
android:padding="6dp"
android:rotation="90"
android:src="#drawable/ic_play_light" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/expandable_part_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/top_layout"
android:animateLayoutChanges="true"
android:clickable="false"
android:visibility="gone">
<!-- Your expanded content views go here -->
</RelativeLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>

Categories

Resources