After implementing a custom animation for these CardViews, the first two are not behaving in the way they are supposed to. Item A and Item B won't expand upon the 2nd click, but yet Item C works perfectly fine.
public class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private Context mContext;
RecyclerViewHeader header;
List<MyRecyclerViewItem> listItems;
ValueAnimator mAnimator;
public MyRecyclerAdapter(Context context, RecyclerViewHeader header, List<MyRecyclerViewItem> listItems)
{
this.mContext = context;
this.header = header;
this.listItems = listItems;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == TYPE_HEADER)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_header, parent, false);
return new MyRecyclerAdapter.VHHeader(v);
}
else if(viewType == TYPE_ITEM)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item, parent, false);
return new MyRecyclerAdapter.VHItem(v);
}
throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}
private MyRecyclerViewItem getItem(int position)
{
return listItems.get(position);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Typeface iconFont = FontManager.getTypeface(mContext, FontManager.FONTAWESOME);
if (holder instanceof VHHeader)
{
final VHHeader vhHeader = (VHHeader)holder;
}
else if (holder instanceof VHItem)
{
MyRecyclerViewItem currentItem = getItem(position-1);
final VHItem vhItem = (VHItem)holder;
vhItem.txtA.setText(currentItem.getContinent());
vhItem.txtB.setText(currentItem.getCountry());
vhItem.txtB.setVisibility(View.GONE);
vhItem.txtExpandCollapse.setText(R.string.fa_icon_chevron_down);
vhItem.txtExpandCollapse.setTypeface(iconFont);
//Add onPreDrawListener
vhItem.txtB.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
vhItem.txtB.getViewTreeObserver().removeOnPreDrawListener(this);
vhItem.txtB.setVisibility(View.GONE);
final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
vhItem.txtB.measure(widthSpec, heightSpec);
mAnimator = vhItem.slideAnimator(0, vhItem.txtB.getMeasuredHeight());
return true;
}
});
vhItem.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(vhItem.txtB.getVisibility() == View.GONE){
vhItem.expand();
} else {
vhItem.collapse();
}
}
});
}
}
#Override
public int getItemViewType(int position) {
if(isPositionHeader(position))
return TYPE_HEADER;
return TYPE_ITEM;
}
private boolean isPositionHeader(int position)
{
return position == 0;
}
// increasing getItemcount to 1. This will be the row of header.
#Override
public int getItemCount() {
return listItems.size()+1;
}
class VHHeader extends RecyclerView.ViewHolder{
Button btnCollapseAll, btnExpandAll;
public VHHeader(View headerView) {
super(headerView);
this.btnCollapseAll = headerView.findViewById(R.id.btn_collapseall);
this.btnExpandAll = headerView.findViewById(R.id.btn_expandall);
}
}
public class VHItem extends RecyclerView.ViewHolder{
CardView cardView;
RelativeLayout mRelativeLayout;
TextView txtExpandCollapse, txtA, txtB;
public VHItem(View itemView) {
super(itemView);
this.cardView = itemView.findViewById(R.id.cv);
this.mRelativeLayout = itemView.findViewById(R.id.tv_rv_relativelayout);
this.txtExpandCollapse = itemView.findViewById(R.id.tv_rv_expandcollapse);
this.txtA = itemView.findViewById(R.id.tv_rv_A);
this.txtB = itemView.findViewById(R.id.tv_rv_B);
}
private void expand() {
// set Visible
txtB.setVisibility(View.VISIBLE);
// change direction of chevron to 'up'
txtExpandCollapse.setText(R.string.fa_icon_chevron_up);
mAnimator.start();
}
private void collapse() {
// change direction of chevron to 'down'
txtExpandCollapse.setText(R.string.fa_icon_chevron_down);
int finalHeight = txtB.getHeight();
ValueAnimator mAnimator = slideAnimator(finalHeight, 0);
mAnimator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationEnd(Animator animator) {
//Height=0, but it set visibility to GONE
txtB.setVisibility(View.GONE);
}
#Override
public void onAnimationStart(Animator animator) {
}
#Override
public void onAnimationCancel(Animator animator) {
}
#Override
public void onAnimationRepeat(Animator animator) {
}
});
mAnimator.start();
}
public ValueAnimator slideAnimator(int start, int end) {
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
//Update Height
int value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = txtB.getLayoutParams();
layoutParams.height = value;
txtB.setLayoutParams(layoutParams);
}
});
return animator;
}
}
}
You need to re-initialize mAnimator object.
Try below,
Defind one more member variable in VHItem class to keep the textB height
public class VHItem extends RecyclerView.ViewHolder{
CardView cardView;
RelativeLayout mRelativeLayout;
TextView txtExpandCollapse, txtA, txtB;
int textBHeight; // new variable
}
Then initialize it from onPreDraw method
public boolean onPreDraw() {
vhItem.txtB.getViewTreeObserver().removeOnPreDrawListener(this);
vhItem.txtB.setVisibility(View.GONE);
final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
vhItem.txtB.measure(widthSpec, heightSpec);
vhItem.textBHeight = vhItem.txtB.getMeasuredHeight();
return true;
}
Then initialize the animator before starting
private void expand() {
txtB.setVisibility(View.VISIBLE);
txtExpandCollapse.setText(R.string.fa_icon_chevron_up);
mAnimator = slideAnimator(0,textBHeight);
mAnimator.start();
}
Change the object CardView for View.
Instead of generating the event on the cardview try to do the following on the inner class VHItem:
View view;
RelativeLayout mRelativeLayout;
TextView txtExpandCollapse, txtA, txtB;
public VHItem(View itemView) {
super(itemView);
this.view = itemView;
this.mRelativeLayout = itemView.findViewById(R.id.tv_rv_relativelayout);
this.txtExpandCollapse = itemView.findViewById(R.id.tv_rv_expandcollapse);
this.txtA = itemView.findViewById(R.id.tv_rv_A);
this.txtB = itemView.findViewById(R.id.tv_rv_B);
}
now, on the method onBindViewHolder:
vhItem.view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(vhItem.txtB.getVisibility() == View.GONE){
vhItem.expand();
} else {
vhItem.collapse();
}
}
});
Related
i used multiple viewholder in DataListAdapter.
each holder have a adapter.
my adapter :
public class DataListAdapter extends BaseAdapter<HomeListItem> {
private RecyclerView.RecycledViewPool pool;
public static final int ADS = 10, DATA = 11, PIC = 13, QUE=14;
public DataListAdapter(ArrayList<HomeListItem> dataList, AdapterListener<HomeListItem> listener) {
this.dataList = dataList;
this.listener = listener;
pool = new RecyclerView.RecycledViewPool();
}
#Override
public void onViewRecycled(#NonNull BaseViewHolder holder) {
super.onViewRecycled(holder);
}
#NonNull
#Override
public BaseViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == ADS){
return new ADSDataHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_home_ads, parent, false));
}else if (viewType == PIC) {
return new PictureHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_home, parent, false));
}else if (viewType == QUE) {
return new QuestionHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_home, parent, false));
}else
return new DataHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_home, parent, false));
}
#Override
public int getItemViewType(int position) {
if (dataList.get(position).getType() == ContentType.ADS)
return ADS;
if (dataList.get(position).getType() == ContentType.GALLERY)
return PIC;
if (dataList.get(position).getType() == ContentType.LIBS )
return DATA;
return QUE;
}
#Override
public void onBindViewHolder(#NonNull BaseViewHolder holder, int position) {
if (holder instanceof DataHolder){
((DataHolder) holder).bind(dataList.get(position));
} else if (holder instanceof ADSDataHolder) {
((ADSDataHolder) holder).bind(dataList.get(position));
} else if (holder instanceof PictureHolder) {
((PictureHolder) holder).bind(dataList.get(position));
}else if (holder instanceof QuestionHolder) {
((QuestionHolder) holder).bind(dataList.get(position));
}
}
class ADSDataHolder extends BaseViewHolder {
...
}
class PictureHolder extends BaseViewHolder {
...
}
class QuestionHolder extends BaseViewHolder{
private RecyclerView recyclerView;
private TextView title;
private View more;
public QuestionHolder(View itemView) {
super(itemView);
setType(QUE);
more = itemView.findViewById(R.id.more);
title = itemView.findViewById(R.id.title);
recyclerView = itemView.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(itemView.getContext(),RecyclerView.HORIZONTAL,false));
recyclerView.hasFixedSize();
recyclerView.setRecycledViewPool(pool);
}
public void bind(HomeListItem data) {
Collections.reverse(data.getData());
title.setText(data.getType().getVisibleName());
HomeQuestionAdapter adapter = new HomeQuestionAdapter((ArrayList<MainPageItem>) (ArrayList<?>) data.getData(),
new AdapterListener<MainPageItem>() {
#Override
public void onItemClick(MainPageItem item) {
onListItemClick(itemView.getContext(), data.getType(), item.getItemId());
}
});
recyclerView.setAdapter(adapter);
more.setOnClickListener(v -> listener.onItemClick(data));
}
}
class DataHolder extends BaseViewHolder {
private RecyclerView recyclerView;
private TextView title;
private View more;
DataHolder(View itemView) {
super(itemView);
setType(DATA);
more = itemView.findViewById(R.id.more);
title = itemView.findViewById(R.id.title);
recyclerView = itemView.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(itemView.getContext(),
LinearLayoutManager.HORIZONTAL, true));
recyclerView.hasFixedSize();
recyclerView.setRecycledViewPool(pool);
}
public void bind(HomeListItem data) {
Collections.reverse(data.getData());
title.setText(data.getType().getVisibleName());
SmallItemAdapter adapter = new SmallItemAdapter((ArrayList<MainPageItem>)
(ArrayList<?>) data.getData(),
new AdapterListener<MainPageItem>() {
#Override
public void onItemClick(MainPageItem item) {
onListItemClick(itemView.getContext(), data.getType(), item.getItemId());
}
});
recyclerView.setAdapter(adapter);
recyclerView.scrollToPosition(data.getData().size() - 1);
more.setOnClickListener(v -> listener.onItemClick(data));
}
}
private void onListItemClick(Context context, ContentType contentType, long id) {
// click
}
}
BaseAdapter:
public abstract class BaseAdapter<T> extends RecyclerView.Adapter<BaseViewHolder> {
protected List<T> dataList;
protected final int DATA_TYPE = 1;
protected boolean isLoading = false, isMoreDataAvailable = false;
protected AdapterListener<T> listener;
#Override
public int getItemViewType(int position) {
if (dataList.get(position) == null)
return -1;
else return DATA_TYPE;
}
#Override
public int getItemCount() {
return dataList.size();
}
public void setMoreDataAvailable(boolean isMoreDataAvailable) {
this.isMoreDataAvailable = isMoreDataAvailable;
}
public void removeLoadingItem() {
if (dataList.size() > 0 && dataList.get(dataList.size() - 1) == null) {
dataList.remove(dataList.size() - 1);
notifyItemRemoved(dataList.size() - 1);
}
}
public void notifyDataChanged() {
isLoading = false;
notifyDataSetChanged();
}
}
and BaseViewHolder:
public class BaseViewHolder extends RecyclerView.ViewHolder {
private int type;
public BaseViewHolder(View itemView) {
super(itemView);
}
}
when i scroll the recyclerview gives me an error
my error:
:00:26.247 4194-4194/ir.hnfadak.shahidezendeh E/PushPole:Exception caught
java.lang.ClassCastException: ir.hfadak.fadakmedia.UI.Main.Home.Picture.SmallItemAdapter$DataHolder cannot be cast to ir.hfadak.fadakmedia.UI.Main.Question.HomeQuestionAdapter$DataQueHolder
at ir.hfadak.fadakmedia.UI.Main.Question.HomeQuestionAdapter.onBindViewHolder(HomeQuestionAdapter.java:31)
at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288)
at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345)
at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361)
at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368)
at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6238)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:933)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
and my HomeQuestionAdapter
public class HomeQuestionAdapter extends RecyclerView.Adapter<HomeQuestionAdapter.DataQueHolder> {
private RoundedCorners roundedCorners;
protected List<MainPageItem> dataList;
protected final int DATA_TYPE = 1;
protected boolean isLoading = false, isMoreDataAvailable = false;
protected AdapterListener<MainPageItem> listener;
public HomeQuestionAdapter(ArrayList<MainPageItem> dataList, AdapterListener<MainPageItem> listener) {
this.dataList = dataList;
this.listener = listener;
roundedCorners = new RoundedCorners(16);
}
#Override
public int getItemViewType(int position) {
if (dataList.get(position) == null)
return -1;
else return DATA_TYPE;
}
#Override
public int getItemCount() {
return dataList.size();
}
public void setMoreDataAvailable(boolean isMoreDataAvailable) {
this.isMoreDataAvailable = isMoreDataAvailable;
}
public void removeLoadingItem() {
if (dataList.size() > 0 && dataList.get(dataList.size() - 1) == null) {
dataList.remove(dataList.size() - 1);
notifyItemRemoved(dataList.size() - 1);
}
}
public void notifyDataChanged() {
isLoading = false;
notifyDataSetChanged();
}
#NonNull
#Override
public HomeQuestionAdapter.DataQueHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new DataQueHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list_simple_question, parent, false));
}
#Override
public void onBindViewHolder(#NonNull HomeQuestionAdapter.DataQueHolder holder, int position) {
if (!isLoading && isMoreDataAvailable && position >= getItemCount() - 1) {
isLoading = true;
listener.onLoadMore();
} else {
holder.bind(dataList.get(position));
}
}
class DataQueHolder extends RecyclerView.ViewHolder {
private ImageView image;
private ImageView share,faivorid;
private TextView question,answer,view;
DataQueHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.imageQue);
question = itemView.findViewById(R.id.titleQue);
answer = itemView.findViewById(R.id.answerQue);
share = itemView.findViewById(R.id.share);
faivorid = itemView.findViewById(R.id.favorite);
view = itemView.findViewById(R.id.viewtxt);
}
void bind(MainPageItem data) {
Glide.with(itemView)
.load(data.getItemSmallImageAddress())
.apply(bitmapTransform(roundedCorners))
.apply(new RequestOptions().error(R.drawable.img_list_def)
.placeholder(R.drawable.img_list_def))
.into(image);
question.setText(data.getItemTitle());
answer.setText(data.getItemDescription());
share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ContextUtil.share(itemView.getContext(),
data.getItemTitle() + "\n\n"
+ data.getItemDescription() + "\n\n"
+ data.getItemSmallImageAddress());
}
});
itemView.setOnClickListener(v -> listener.onItemClick(data));
}
}
}
Where does the code is wrong?
Your are type casting instance of super class to a reference of sub class which is causing this error.
Instead create something like this:-
public void onBindViewHolder(#NonNull BaseViewHolder holder, int position) {
if (holder instanceof DataQueHolder){
((DataQueHolder) holder).bind(dataList.get(position));
}else if (holder instanceof DataHolder){
((DataHolder) holder).bind(dataList.get(position));
}else if (holder instanceof ADSDataHolder) {
((ADSDataHolder) holder).bind(dataList.get(position));
} else if (holder instanceof PictureHolder) {
((PictureHolder) holder).bind(dataList.get(position));
}else if (holder instanceof QuestionHolder) {
((QuestionHolder) holder).bind(dataList.get(position));
}
}
Please remove this below line from DataListAdapter
recyclerView.setRecycledViewPool(pool);
It works for me..
I want to make data from RecyclerView1 Activity1 can be passed to RecyclerView2 Activity2
//SectionAdapter.java
public class AdapterSectionHotTrendingNews extends RecyclerView.Adapter{
private Context mContext;
private ArrayList<ModelSectionHotTrendingNews> modelSectionHotTrendingNews;
public AdapterSectionHotTrendingNews(Context mContext, ArrayList<ModelSectionHotTrendingNews> modelSectionHotTrendingNews) {
this.mContext = mContext;
this.modelSectionHotTrendingNews = modelSectionHotTrendingNews;
}
#Override
public SectionHotTrendingNewsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_section_hottrendingnews, null);
return new SectionHotTrendingNewsViewHolder(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final SectionHotTrendingNewsViewHolder sectionHotTrendingNewsViewHolder = (SectionHotTrendingNewsViewHolder) holder;
ModelSectionHotTrendingNews modelSectionHotTrendingNewsX = modelSectionHotTrendingNews.get(position);
//Set
sectionHotTrendingNewsViewHolder.TVSectionTitle.setText(modelSectionHotTrendingNewsX.getHeaderTitle());
ArrayList singleSectionItems = modelSectionHotTrendingNewsX.getAllItemsInSection();
/*AdapterSingleHotLatestNews.RecyclerViewClickListener listenerLatestNews;
listenerLatestNews = new AdapterSingleHotLatestNews.RecyclerViewClickListener() {
#Override
public void onRowHotLatestNewsClick(View view, int position) {
}
#Override
public void onIconHotLatestNewsClick(View view, int position) {
}
};*/
AdapterSingleHotTrendingNews itemListDataAdapter = new AdapterSingleHotTrendingNews(mContext, singleSectionItems);
/*itemRowHolder.recycler_view_list.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
//Allow ScrollView to intercept touch events once again.
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
// Handle RecyclerView touch events.
v.onTouchEvent(event);
return true;
}
});*/
sectionHotTrendingNewsViewHolder.BTNHotTrendingNewsMore.setOnClickListener(
new View.OnClickListener() { #Override public void onClick(View v) {
Intent intent = new Intent(mContext, TabMoreHotActivity.class);
// here you create put extra in new intent not the intent that you created
intent.putExtra("MoreNews", modelSectionHotTrendingNews.get(position).getAllItemsInSection());
mContext.startActivity(intent);
} });
/*Glide.with(mContext)
.load(feedItem.getImageURL())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.error(R.drawable.bg)
.into(feedListRowHolder.thumbView);*/
//SetRecyclerView
sectionHotTrendingNewsViewHolder.RecyclerViewSectionHotTrendingNews.setHasFixedSize(true);
sectionHotTrendingNewsViewHolder.RecyclerViewSectionHotTrendingNews.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
sectionHotTrendingNewsViewHolder.RecyclerViewSectionHotTrendingNews.setAdapter(itemListDataAdapter);
sectionHotTrendingNewsViewHolder.RecyclerViewSectionHotTrendingNews.setNestedScrollingEnabled(false);
}
#Override
public int getItemCount() {
int itemCount = modelSectionHotTrendingNews.size();
return itemCount;
}
public class SectionHotTrendingNewsViewHolder extends RecyclerView.ViewHolder {
protected TextView TVSectionTitle;
protected ImageView BTNHotTrendingNewsMore;
protected RecyclerView RecyclerViewSectionHotTrendingNews;
protected RecyclerView RecyclerViewMoreSectionHotTrendingNews;
public SectionHotTrendingNewsViewHolder(View itemView) {
super(itemView);
TVSectionTitle = (TextView) itemView.findViewById(R.id.TV_SectionTitle);
BTNHotTrendingNewsMore= (ImageView) itemView.findViewById(R.id.BTN_HotTrendingNewsMore);
RecyclerViewSectionHotTrendingNews = (RecyclerView) itemView.findViewById(R.id.RecyclerView_Section_HotTrendingNews);
RecyclerViewMoreSectionHotTrendingNews = (RecyclerView) itemView.findViewById(R.id.RecyclerViewMore_Section_HotTrendingNews);
}
}
}
//SingleAdapter.java
public class AdapterSingleHotTrendingNews extends RecyclerView.Adapter{
private Context mContext;
private ArrayList<ModelSingleHotTrendingNews> modelSingleHotTrendingNews;
public AdapterSingleHotTrendingNews(Context mContext, ArrayList<ModelSingleHotTrendingNews> modelSingleHotTrendingNews) {
this.mContext = mContext;
this.modelSingleHotTrendingNews = modelSingleHotTrendingNews;
}
//Container
#Override
public SingleHotTrendingNewsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_single_hottrendingnews, null);
return new SingleHotTrendingNewsViewHolder(v);
}
//Fill Container with Model Setter Getter
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final SingleHotTrendingNewsViewHolder singleHotTrendingNewsViewHolder = (SingleHotTrendingNewsViewHolder) holder;
final ModelSingleHotTrendingNews modelSingleHotTrendingNewsX = modelSingleHotTrendingNews.get(position);
//Set
singleHotTrendingNewsViewHolder.TVGameDate.setText(modelSingleHotTrendingNewsX.getGamedate());
singleHotTrendingNewsViewHolder.TVGameDescription.setText(modelSingleHotTrendingNewsX.getGamedescription());
singleHotTrendingNewsViewHolder.IMGGameImage.setImageResource(modelSingleHotTrendingNewsX.getGameimage());
singleHotTrendingNewsViewHolder.ICONHotTrendingNewsSaving.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Boolean booltrendingnewssaving = modelSingleHotTrendingNewsX.getTrendingnewssaving();
final int id = modelSingleHotTrendingNewsX.getId();
if (booltrendingnewssaving == true){
Toast.makeText(v.getContext(), "Turn Off Saved News " + id, Toast.LENGTH_SHORT).show();
singleHotTrendingNewsViewHolder.ICONHotTrendingNewsSaving.setImageResource(R.drawable.saved_off);
modelSingleHotTrendingNewsX.setTrendingnewssaving(false);
/*updateSavedNewsSaving("update_newssaving", id, false);*/
} else if(booltrendingnewssaving == false) {
Toast.makeText(v.getContext(), "Turn On Saved News " + id, Toast.LENGTH_SHORT).show();
singleHotTrendingNewsViewHolder.ICONHotTrendingNewsSaving.setImageResource(R.drawable.saved_on);
modelSingleHotTrendingNewsX.setTrendingnewssaving(true);
/*updateSavedNewsSaving("update_newssaving", id, true);*/
}
}
});
/* Glide.with(mContext)
.load(feedItem.getImageURL())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.error(R.drawable.bg)
.into(feedListRowHolder.thumbView);*/
singleHotTrendingNewsViewHolder.ROWHotTrendingNewsContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), modelSingleHotTrendingNews.get(position).getGamedescription(), Toast.LENGTH_SHORT).show();
//Passing Data to GameDescriptionActivity
Intent intent = new Intent(mContext, GameDetailActivity.class);
intent.putExtra("ImagePKG", modelSingleHotTrendingNews.get(position).getGameimage());
intent.putExtra("NamePKG", modelSingleHotTrendingNews.get(position).getGamedate());
intent.putExtra("UrlPKG", modelSingleHotTrendingNews.get(position).getId());
intent.putExtra("DescriptionPKG", modelSingleHotTrendingNews.get(position).getGamedescription());
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
int itemCount = modelSingleHotTrendingNews.size();
return itemCount;
}
public class SingleHotTrendingNewsViewHolder extends RecyclerView.ViewHolder{
TextView TVGameDate;
TextView TVGameDescription;
ImageView IMGGameImage;
ImageView ICONHotTrendingNewsSaving;
private RelativeLayout ROWHotTrendingNewsContainer;
public SingleHotTrendingNewsViewHolder(View itemView) {
super(itemView);
TVGameDate = itemView.findViewById(R.id.TV_GameDate);
TVGameDescription = itemView.findViewById(R.id.TV_GameDescription);
IMGGameImage = itemView.findViewById(R.id.IMG_GameImage);
ICONHotTrendingNewsSaving = itemView.findViewById(R.id.ICON_HotTrendingNewsSaving);
ROWHotTrendingNewsContainer = itemView.findViewById(R.id.ROW_HotTrendingNewsContainer);
}
}
}
//ModelSection.java
public class ModelSectionHotTrendingNews implements Serializable {
private String headerTitle;
private ArrayList<ModelSingleHotTrendingNews> allItemsInSection;
public ModelSectionHotTrendingNews() {
}
public String getHeaderTitle() {
return headerTitle;
}
public void setHeaderTitle(String headerTitle) {
this.headerTitle = headerTitle;
}
public ArrayList<ModelSingleHotTrendingNews> getAllItemsInSection() {
return allItemsInSection;
}
public void setAllItemsInSection(ArrayList<ModelSingleHotTrendingNews> allItemsInSection) {
this.allItemsInSection = allItemsInSection;
}
}
//ModelSingle.java
public class ModelSingleHotTrendingNews implements Serializable {
private int id;
private String gamedate;
private String gamedescription;
private int gameimage;
private Boolean trendingnewssaving;
private String value;
private String message;
public ModelSingleHotTrendingNews(int id, String gamedate, String gamedescription, int gameimage, Boolean trendingnewssaving, String value, String message) {
this.id = id;
this.gamedate = gamedate;
this.gamedescription = gamedescription;
this.gameimage = gameimage;
this.trendingnewssaving = trendingnewssaving;
this.value = value;
this.message = message;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getGamedate() {
return gamedate;
}
public void setGamedate(String gamedate) {
this.gamedate = gamedate;
}
public String getGamedescription() {
return gamedescription;
}
public void setGamedescription(String gamedescription) {
this.gamedescription = gamedescription;
}
public int getGameimage() {
return gameimage;
}
public void setGameimage(int gameimage) {
this.gameimage = gameimage;
}
public Boolean getTrendingnewssaving() {
return trendingnewssaving;
}
public void setTrendingnewssaving(Boolean trendingnewssaving) {
this.trendingnewssaving = trendingnewssaving;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
//AdapterMoreSection.java
public class AdapterMoreSectionHotTrendingNews extends RecyclerView.Adapter {
private Context mContext;
private ArrayList<ModelSectionHotTrendingNews> modelSectionHotTrendingNews;
public AdapterMoreSectionHotTrendingNews(Context mContext, ArrayList<ModelSectionHotTrendingNews> modelSectionHotTrendingNews) {
this.mContext = mContext;
this.modelSectionHotTrendingNews = modelSectionHotTrendingNews;
}
#Override
public SectionMoreHotTrendingNewsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemmore_section_hottrendingnews, null);
return new SectionMoreHotTrendingNewsViewHolder(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final SectionMoreHotTrendingNewsViewHolder sectionMoreHotTrendingNewsViewHolder = (SectionMoreHotTrendingNewsViewHolder) holder;
ModelSectionHotTrendingNews modelSectionHotTrendingNewsX = modelSectionHotTrendingNews.get(position);
//Set
sectionMoreHotTrendingNewsViewHolder.TVSectionTitle.setText(modelSectionHotTrendingNewsX.getHeaderTitle());
ArrayList singleMoreSectionItems = modelSectionHotTrendingNewsX.getAllItemsInSection();
/*AdapterSingleHotLatestNews.RecyclerViewClickListener listenerLatestNews;
listenerLatestNews = new AdapterSingleHotLatestNews.RecyclerViewClickListener() {
#Override
public void onRowHotLatestNewsClick(View view, int position) {
}
#Override
public void onIconHotLatestNewsClick(View view, int position) {
}
};*/
AdapterMoreSingleHotTrendingNews itemListDataAdapter = new AdapterMoreSingleHotTrendingNews(mContext, singleMoreSectionItems);
/*itemRowHolder.recycler_view_list.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
//Allow ScrollView to intercept touch events once again.
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
// Handle RecyclerView touch events.
v.onTouchEvent(event);
return true;
}
});*/
final String sectionTitle = modelSectionHotTrendingNewsX.getHeaderTitle();
sectionMoreHotTrendingNewsViewHolder.BTNHotTrendingNewsMore.setOnClickListener(
new View.OnClickListener() {
#Override public void onClick(View v) {
//More IN RecyclerViewMore
}
});
/*Glide.with(mContext)
.load(feedItem.getImageURL())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.error(R.drawable.bg)
.into(feedListRowHolder.thumbView);*/
//SetRecyclerView
sectionMoreHotTrendingNewsViewHolder.RecyclerViewMoreSectionHotTrendingNews.setHasFixedSize(true);
sectionMoreHotTrendingNewsViewHolder.RecyclerViewMoreSectionHotTrendingNews.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
sectionMoreHotTrendingNewsViewHolder.RecyclerViewMoreSectionHotTrendingNews.setAdapter(itemListDataAdapter);
sectionMoreHotTrendingNewsViewHolder.RecyclerViewMoreSectionHotTrendingNews.setNestedScrollingEnabled(false);
}
#Override
public int getItemCount() {
int itemCount = modelSectionHotTrendingNews.size();
return itemCount;
}
public class SectionMoreHotTrendingNewsViewHolder extends RecyclerView.ViewHolder {
protected TextView TVSectionTitle;
protected ImageView BTNHotTrendingNewsMore;
protected RecyclerView RecyclerViewMoreSectionHotTrendingNews;
public SectionMoreHotTrendingNewsViewHolder(View itemView) {
super(itemView);
TVSectionTitle = (TextView) itemView.findViewById(R.id.TV_SectionTitle);
BTNHotTrendingNewsMore= (ImageView) itemView.findViewById(R.id.BTN_HotTrendingNewsMore);
RecyclerViewMoreSectionHotTrendingNews = (RecyclerView) itemView.findViewById(R.id.RecyclerViewMore_Section_HotTrendingNews);
}
}
}
//AdapterMoreSingle.java
public class AdapterMoreSingleHotTrendingNews extends RecyclerView.Adapter{
private Context mContext;
private ArrayList<ModelSingleHotTrendingNews> modelSingleHotTrendingNews;
public AdapterMoreSingleHotTrendingNews(Context mContext, ArrayList<ModelSingleHotTrendingNews> modelSingleHotTrendingNews) {
this.mContext = mContext;
this.modelSingleHotTrendingNews = modelSingleHotTrendingNews;
}
//Container
#Override
public SingleMoreHotTrendingNewsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.itemmore_single_hottrendingnews, null);
return new SingleMoreHotTrendingNewsViewHolder(v);
}
//Fill Container with Model Setter Getter
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final SingleMoreHotTrendingNewsViewHolder singleMoreHotTrendingNewsViewHolder = (SingleMoreHotTrendingNewsViewHolder) holder;
final ModelSingleHotTrendingNews modelSingleHotTrendingNewsX = modelSingleHotTrendingNews.get(position);
//Set
singleMoreHotTrendingNewsViewHolder.TVGameDate.setText(modelSingleHotTrendingNewsX.getGamedate());
singleMoreHotTrendingNewsViewHolder.TVGameDescription.setText(modelSingleHotTrendingNewsX.getGamedescription());
singleMoreHotTrendingNewsViewHolder.IMGGameImage.setImageResource(modelSingleHotTrendingNewsX.getGameimage());
singleMoreHotTrendingNewsViewHolder.ICONHotTrendingNewsSaving.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Boolean booltrendingnewssaving = modelSingleHotTrendingNewsX.getTrendingnewssaving();
final int id = modelSingleHotTrendingNewsX.getId();
if (booltrendingnewssaving == true){
Toast.makeText(v.getContext(), "Turn Off Saved News " + id, Toast.LENGTH_SHORT).show();
singleMoreHotTrendingNewsViewHolder.ICONHotTrendingNewsSaving.setImageResource(R.drawable.saved_off);
modelSingleHotTrendingNewsX.setTrendingnewssaving(false);
/*updateSavedNewsSaving("update_newssaving", id, false);*/
} else if(booltrendingnewssaving == false) {
Toast.makeText(v.getContext(), "Turn On Saved News " + id, Toast.LENGTH_SHORT).show();
singleMoreHotTrendingNewsViewHolder.ICONHotTrendingNewsSaving.setImageResource(R.drawable.saved_on);
modelSingleHotTrendingNewsX.setTrendingnewssaving(true);
/*updateSavedNewsSaving("update_newssaving", id, true);*/
}
}
});
/* Glide.with(mContext)
.load(feedItem.getImageURL())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.error(R.drawable.bg)
.into(feedListRowHolder.thumbView);*/
singleMoreHotTrendingNewsViewHolder.ROWHotTrendingNewsContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), modelSingleHotTrendingNews.get(position).getGamedescription(), Toast.LENGTH_SHORT).show();
//Passing Data to GameDescriptionActivity
Intent intent = new Intent(mContext, GameDetailActivity.class);
intent.putExtra("ImagePKG", modelSingleHotTrendingNews.get(position).getGameimage());
intent.putExtra("NamePKG", modelSingleHotTrendingNews.get(position).getGamedate());
intent.putExtra("UrlPKG", modelSingleHotTrendingNews.get(position).getId());
intent.putExtra("DescriptionPKG", modelSingleHotTrendingNews.get(position).getGamedescription());
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
int itemCount = modelSingleHotTrendingNews.size();
return itemCount;
}
public class SingleMoreHotTrendingNewsViewHolder extends RecyclerView.ViewHolder{
TextView TVGameDate;
TextView TVGameDescription;
ImageView IMGGameImage;
ImageView ICONHotTrendingNewsSaving;
private RelativeLayout ROWHotTrendingNewsContainer;
public SingleMoreHotTrendingNewsViewHolder(View itemView) {
super(itemView);
TVGameDate = itemView.findViewById(R.id.TV_GameDate);
TVGameDescription = itemView.findViewById(R.id.TV_GameDescription);
IMGGameImage = itemView.findViewById(R.id.IMG_GameImage);
ICONHotTrendingNewsSaving = itemView.findViewById(R.id.ICON_HotTrendingNewsSaving);
ROWHotTrendingNewsContainer = itemView.findViewById(R.id.ROW_HotTrendingNewsContainer);
}
}
}
//Activity2More.java
public class TabMoreHotActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragmentmore_tabhot);
AdapterMoreSectionHotTrendingNews adapterMoreSectionHotTrendingNews;
ArrayList<ModelSectionHotTrendingNews> modelSectionHotTrendingNews = new ArrayList<>();
Bundle bundle = getIntent().getExtras();
if(bundle!=null)
{
modelSectionHotTrendingNews = (ArrayList<ModelSectionHotTrendingNews>) bundle.getSerializable("MoreNews");
}
//1
RecyclerView RecyclerViewMoreSingleHotTrendingNews = findViewById(R.id.RecyclerViewMore_Single_HotTrendingNews);
RecyclerViewMoreSingleHotTrendingNews.setHasFixedSize(true);
adapterMoreSectionHotTrendingNews = new AdapterMoreSectionHotTrendingNews(this, modelSectionHotTrendingNews);
RecyclerViewMoreSingleHotTrendingNews.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
RecyclerViewMoreSingleHotTrendingNews.setAdapter(adapterMoreSectionHotTrendingNews);
//Optimized
RecyclerViewMoreSingleHotTrendingNews.setHasFixedSize(true);
RecyclerViewMoreSingleHotTrendingNews.setItemViewCacheSize(20);
}
}
//Error
Process: com.indofun.android.indojoy, PID: 18827
java.lang.ClassCastException: com.indofun.android.indojoy.Models.Model_HotTrendingNews.ModelSingleHotTrendingNews cannot be cast to com.indofun.android.indojoy.Models.Model_HotTrendingNews.ModelSectionHotTrendingNews
at com.indofun.android.indojoy.Adapters.AdapterMore_HotTrendingNews.AdapterMoreSectionHotTrendingNews.onBindViewHolder(AdapterMoreSectionHotTrendingNews.java:39)
//NOTE
//RecyclerView1 using AdapterSection.java,AdapterSingle.java,ModelSection.java,ModelSingle.java
//RecyclerView2 using AdapterMoreSection.java,AdapterMoreSingle.java,ModelSection.java,ModelSingle.java
Inside TabMoreHotActivity use like this:
ArrayList<ModelSingleHotTrendingNews> modelSingleHotTrendingNews = new ArrayList<>();
Bundle bundle = getIntent().getExtras();
if(bundle!=null {
modelSingleHotTrendingNews = ArrayList<ModelSingleHotTrendingNews>) bundle.getSerializable("MoreNews");
}
Is it possible to expand and collapse multiple CardViews within a RecyclerView at the same time? I created a header (for my RecyclerView) with two buttons but I'm not sure what needs to go in the click event.
RecyclerView adapter class
public class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
public boolean isSupposedToBeCollapsed;
private Context mContext;
RecyclerViewHeader header;
List<RecyclerViewItem> listItems;
ValueAnimator mAnimator;
public MyRecyclerAdapter(Context context, RecyclerViewHeader header, List<RecyclerViewItem> listItems)
{
this.mContext = context;
this.header = header;
this.listItems = listItems;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == TYPE_HEADER)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_header, parent, false);
return new MyRecyclerAdapter.VHHeader(v);
}
else if(viewType == TYPE_ITEM)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item, parent, false);
return new MyRecyclerAdapter.VHItem(v);
}
throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}
private RecyclerViewItem getItem(int position)
{
return listItems.get(position);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Typeface iconFont = FontManager.getTypeface(mContext, FontManager.FONTAWESOME);
if (holder instanceof VHHeader)
{
final VHHeader vhHeader = (VHHeader)holder;
vhHeader.btnExpandAll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(isSupposedToBeCollapsed){
// change visibility to 'VISIBLE'
txtB.setVisibility(View.VISIBLE);
// change direction of chevron to 'up'
txtExpandCollapse.setText(R.string.fa_icon_chevron_up);
// apply animation to the height of 'txtB'
mAnimator = slideAnimator(0, textBHeight);
// start the animation
mAnimator.start();
}
else{
}
}
});
vhHeader.btnCollapseAll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(isSupposedToBeCollapsed){
// change visibility to 'VISIBLE'
txtB.setVisibility(View.VISIBLE);
// change direction of chevron to 'up'
txtExpandCollapse.setText(R.string.fa_icon_chevron_up);
// apply animation to the height of 'txtB'
mAnimator = slideAnimator(0, textBHeight);
// start the animation
mAnimator.start();
}
else{
}
}
});
}
else if (holder instanceof VHItem)
{
RecyclerViewItem currentItem = getItem(position-1);
final VHItem vhItem = (VHItem)holder;
vhItem.txtA.setText(currentItem.getTitle());
vhItem.txtB.setText(currentItem.getDescription());
vhItem.txtB.setVisibility(View.GONE);
vhItem.txtExpandCollapse.setText(R.string.fa_icon_chevron_down);
vhItem.txtExpandCollapse.setTypeface(iconFont);
//Add onPreDrawListener
vhItem.txtB.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
vhItem.txtB.getViewTreeObserver().removeOnPreDrawListener(this);
vhItem.txtB.setVisibility(View.GONE);
final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
vhItem.txtB.measure(widthSpec, heightSpec);
vhItem.textBHeight = vhItem.txtB.getMeasuredHeight();
return true;
}
});
vhItem.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(vhItem.txtB.getVisibility() == View.GONE){
vhItem.expand();
} else {
vhItem.collapse();
}
}
});
vhItem.mLinearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(vhItem.txtB.getVisibility() == View.GONE){
vhItem.expand();
} else {
vhItem.collapse();
}
}
});
vhItem.txtExpandCollapse.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(vhItem.txtB.getVisibility() == View.GONE){
vhItem.expand();
} else {
vhItem.collapse();
}
}
});
}
}
// need to override this method
#Override
public int getItemViewType(int position) {
if(isPositionHeader(position))
return TYPE_HEADER;
return TYPE_ITEM;
}
private boolean isPositionHeader(int position)
{
return position == 0;
}
// increasing getItemcount to 1. This will be the row of header.
#Override
public int getItemCount() {
return listItems.size()+1;
}
class VHHeader extends RecyclerView.ViewHolder{
Button btnCollapseAll, btnExpandAll;
public VHHeader(View headerView) {
super(headerView);
this.btnCollapseAll = headerView.findViewById(R.id.btn_collapseall);
this.btnExpandAll = headerView.findViewById(R.id.btn_expandall);
}
}
public class VHItem extends RecyclerView.ViewHolder{
CardView cardView;
LinearLayout mLinearLayout;
RecyclerView mRecyclerView;
RelativeLayout mRelativeLayout;
TextView txtExpandCollapse, txtA, txtB;
public int textBHeight;
public VHItem(View itemView) {
super(itemView);
this.cardView = itemView.findViewById(R.id.cv);
this.mLinearLayout = itemView.findViewById(R.id.cardview_tconnections_titlerow);
this.mRelativeLayout = itemView.findViewById(R.id.my_relativelayout);
this.mRecyclerView = itemView.findViewById(R.id.my_recyclerview);
this.txtExpandCollapse = itemView.findViewById(R.id.tv_expandcollapse);
this.txtA = itemView.findViewById(R.id.tv_A);
this.txtB = itemView.findViewById(R.id.tv_B);
}
private void expand() {
// change visibility to 'VISIBLE'
txtB.setVisibility(View.VISIBLE);
// change direction of chevron to 'up'
txtExpandCollapse.setText(R.string.fa_icon_chevron_up);
// apply animation to the height of 'txtB'
mAnimator = slideAnimator(0, textBHeight);
// start the animation
mAnimator.start();
}
private void collapse() {
// change direction of chevron to 'down'
txtExpandCollapse.setText(R.string.fa_icon_chevron_down);
int finalHeight = txtB.getHeight();
ValueAnimator mAnimator = slideAnimator(finalHeight, 0);
mAnimator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationEnd(Animator animator) {
txtB.setVisibility(View.GONE);
}
#Override
public void onAnimationStart(Animator animator) {
}
#Override
public void onAnimationCancel(Animator animator) {
}
#Override
public void onAnimationRepeat(Animator animator) {
}
});
mAnimator.start();
}
public ValueAnimator slideAnimator(int start, int end) {
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
// update height
int value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = txtB.getLayoutParams();
layoutParams.height = value;
txtB.setLayoutParams(layoutParams);
}
});
return animator;
}
}
}
Fragment class
public class MyFragment extends android.support.v4.app.Fragment {
private MyRecyclerAdapter adapter;
public MyFragment() {}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_rv, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
View v = getView();
assert v != null;
recyclerView = v.findViewById(R.id.my_recyclerview);
linearLayoutManager = new LinearLayoutManager(getActivity());
MyRecyclerAdapter adapter = new MyRecyclerAdapter(getContext(), getHeader(), getListItems());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapter);
super.onActivityCreated(savedInstanceState);
}
RecyclerView recyclerView;
LinearLayoutManager linearLayoutManager;
public RecyclerViewHeader getHeader()
{
return new RecyclerViewHeader();
}
public List<RecyclerViewItem> getListItems()
{
List<RecyclerViewItem> rvItems = new ArrayList<>();
RecyclerViewItem itemA = new RecyclerViewItem();
itemA.setConnectionMode("Item A");
itemA.setConnectionName("Feature A1");
rvItems.add(itemA);
RecyclerViewItem itemB = new RecyclerViewItem();
itemB.setConnectionMode("Item B");
itemB.setConnectionName("Feature B1\nFeature B2");
rvItems.add(itemB);
RecyclerViewItem itemC = new RecyclerViewItem();
itemC.setConnectionMode("Item C");
itemC.setConnectionName("Feature C1\nFeature C2\nFeature C3");
rvItems.add(itemC);
return rvItems;
}
}
What you can do is, set a variable(boolean) that stores the state of the card (expanded/collapsed) in the RecyclerAdapter code.
Then, in your onBindViewHolder code block, write a piece of code to check if the card should be expanded or collapsed using the above-mentioned variable and the required display code.
Example:
if(isSuppossedToBeCollapsed){
textView.setVisibility = false;
}
else{
textView.setVisibility = true;
}
You can then call notifyDatasetChanged in your RecyclerAdapter code to update the recycler views when you click the button which will redraw the views and reflect the state of the cards(expanded/collapsed) accordingly.
NotifyDatasetChanged Documentation
I have a little bit problem.In my activity there is two Adapter one is for color selection and another is for size selection. While i clicked one of the item of color then recently the available size adapter should be change but i got problem in size adapter. it changes only when i click the size item. I research and try to solve problem but it doesnt works for me.
Here is my code.
AddToCartActivity.java
public class AddToCartActivity extends BaseActivity{
#Override
protected int getLayout() {
return R.layout.activity_add_to_cart;
}
#Override
protected void init() {
//api called here
}
// response of api
#Override
public void productDetail(ProductCommonModel productCommonModel,
ArrayList<ProductChildModel> productChildModels, HashMap<Integer,
ArrayList<ChildAttributeModel>> childWithAttribute, HashMap<Integer,
ArrayList<ChildImageModel>> childWithImages,
ArrayList<com.hazesoft.dokan.singleproductdetail.model.ColorModel>
colorModels, ArrayList<SizeModel> sizeModels,
ArrayList<RelatedProductModel> relatedProductModels) {
this.productCommonModel = productCommonModel;
this.productChildModels = productChildModels;
this.childWithAttribute = childWithAttribute;
this.childWithImages = childWithImages;
this.colorModels = colorModels;
this.sizeModels = sizeModels;
this.relatedProductModels = relatedProductModels;
tvProductName.setText(productCommonModel.getName());
if (productCommonModel.getSpecialPrice() == 0) {
tvSellingPrice.setText(getString(R.string.rs) + productCommonModel.getSellingPrice());
tvDiscount.setVisibility(View.GONE);
tvSpecialPrice.setVisibility(View.GONE);
} else {
tvSpecialPrice.setText(getString(R.string.rs) + productCommonModel.getSpecialPrice());
tvSellingPrice.setText(getString(R.string.rs) + productCommonModel.getSellingPrice());
tvSellingPrice.setPaintFlags(tvSellingPrice.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
tvDiscount.setText(productCommonModel.getDiscount() + getString(R.string.percentage));
}
setChildDetail(childWithAttribute, productChildModels);
setColorModel(colorModels);
setSizeModel(sizeModels);
quantity = Integer.parseInt(tvQuantityCart.getText().toString());
}
// setcolor adapter
private void setColorModel(ArrayList<ColorModel> colorModels) {
MyColorGridViewAdapter adapter = new MyColorGridViewAdapter(this, colorModels);
gvColor.setAdapter(adapter);
gvColor.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
adapter.setSelectedPostion(position);
adapter.notifyDataSetChanged();
}
});
}
// set size adapter
private void setSizeModel(ArrayList<SizeModel> sizeModels) {
sizeCustomModels = new ArrayList<>();
for(int i=0;i<sizeModels.size();i++){
sizeCustomModels.add(new SizeCustomModel(sizeModels.get(i).getAttName(),0));
}
setCustomSizeModelToAdapter(sizeCustomModels);
}
// this is code when i click color and change the size adapter but size doesnt change recently only changes when i click any item of the size
public void getSelectedC0lor(String color) {
selectedColor = color;
selectedSize=null;
sizeCustomModels = new ArrayList<>();
availableSize = new ArrayList<>();
for (int i = 0; i < skuColorSIzeList.size(); i++) {
if (skuColorSIzeList.get(i).getColor().equals(selectedColor)) {
availableSize.add(skuColorSIzeList.get(i).getSize());
}
}
for(int i=0;i<sizeModels.size();i++){
String size = null;
int status=0;
for(int j=0;j<availableSize.size();j++){
if(sizeModels.get(i).getAttName().equals(availableSize.get(j))){
size = sizeModels.get(i).getAttName();
status = 1;
break;
}else {
size = sizeModels.get(i).getAttName();
status = 0;
}
}
sizeCustomModels.add(new SizeCustomModel(size,status));
}
sizeRecylerAdapter.getNewModel(sizeCustomModels);
/*sizeRecylerAdapter = new MyCustomSizeRecylerAdapter(sizeCustomModels,this);
rvSize.setAdapter(sizeRecylerAdapter);
sizeRecylerAdapter.notifyDataSetChanged();*/
/*setCustomSizeModelToAdapter(sizeCustomModels);*/
}
}
MyColorGridViewAdapter.java
public class MyColorGridViewAdapter extends BaseAdapter {
Context context;
List<ColorModel> colorModelList;
String select_color;
boolean ch =false;
int checkPosition = -1;
public MyColorGridViewAdapter(Context context, List<ColorModel> colorModelList) {
this.context = context;
this.colorModelList = colorModelList;
}
public void setSelectedPostion(int postion){
this.checkPosition = postion;
}
#Override
public int getCount() {
return colorModelList.size();
}
#Override
public Object getItem(int position) {
return colorModelList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView==null){
convertView = LayoutInflater.from(context).inflate(R.layout.custom_color_list_item,null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
Picasso.with(context).load(colorModelList.get(position).getImage()).into(holder.ivImage);
holder.tvColorName.setText(colorModelList.get(position).getAttName());
if(checkPosition==position){
holder.ivChecked.setVisibility(View.VISIBLE);
select_color = colorModelList.get(position).getAttName();
if( context instanceof AddToCartActivity){
((AddToCartActivity) context).getSelectedC0lor(select_color);
}
}else {
holder.ivChecked.setVisibility(View.GONE);
}
if(colorModelList.size()==1){
holder.ivChecked.setVisibility(View.VISIBLE);
select_color = colorModelList.get(position).getAttName();
if( context instanceof AddToCartActivity){
((AddToCartActivity) context).getSelectedC0lor(select_color);
}
}
return convertView;
}
class ViewHolder{
#BindView(R.id.view)
LinearLayout view;
#BindView(R.id.tv_color_name)
TextViewHelper tvColorName;
#BindView(R.id.iv_image)
ImageView ivImage;
#BindView(R.id.iv_checked)
ImageView ivChecked;
public ViewHolder(View view) {
ButterKnife.bind(this,view);
}
}
}
MyCustomSizeRecylerAdapter.java
public class MyCustomSizeRecylerAdapter extends RecyclerView.Adapter<MyCustomSizeRecylerAdapter.MyViewHolder> {
ArrayList<SizeCustomModel> sizeModels;
Context context;
int checkPosition = -1;
String selectedSize;
public MyCustomSizeRecylerAdapter(ArrayList<SizeCustomModel> sizeModels, Context context) {
this.sizeModels = sizeModels;
this.context = context;
}
public void getNewModel(ArrayList<SizeCustomModel> customModels) {
sizeModels.clear();
this.sizeModels = customModels;
selectedSize = null;
Log.d("sizemodel", "getNewModel: " + new Gson().toJson(sizeModels));
notifyDataSetChanged();
}
public void getSelectedPosition(int position) {
checkPosition = position;
notifyDataSetChanged();
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.size_adapter, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.tv_sizeName.setText(sizeModels.get(position).getSize());
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_register);
if (sizeModels.get(position).getStock_Status() == 0) {
holder.ll_mainview.setClickable(false);
holder.ll_sizeAdapter.setBackgroundResource(R.color.blue_700);
} else if (sizeModels.get(position).getStock_Status() == 1) {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_register);
if (checkPosition == position) {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_green);
holder.tv_sizeName.setTextColor(context.getResources().getColor(R.color.white));
selectedSize = sizeModels.get(position).getSize();
if (context instanceof AddToCartActivity) {
((AddToCartActivity) context).getSelectSize(selectedSize);
}
} else {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_register);
holder.tv_sizeName.setTextColor(context.getResources().getColor(R.color.tv_black));
}
if (sizeModels.size() == 1) {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_green);
holder.tv_sizeName.setTextColor(context.getResources().getColor(R.color.white));
selectedSize = sizeModels.get(position).getSize();
if (context instanceof AddToCartActivity) {
((AddToCartActivity) context).getSelectSize(selectedSize);
}
}
}
}
#Override
public int getItemCount() {
return sizeModels.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
#BindView(R.id.tv_sizeName)
TextView tv_sizeName;
#BindView(R.id.ll_sizeAdapter)
LinearLayout ll_sizeAdapter;
#BindView(R.id.main_view)
LinearLayout ll_mainview;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
At first both adapter will set data and after click color item the size adapter must be change but it only changes when i click any of the item. adapter.notifyDataSetChanged() doesnt work here for me.
Both Adapter set
When i click color item but doesnt change size adapter
when i click size item only change size adapter
Use Interface to bridge with two adapter and communicate with each other.
When scroll recyclerview some items mixes. After I add ads after every 15 items, holder get wrong data. Some items are vip items. I will change background color of these items. But when I scroll it dublicates mixes. How can I solve?
This is my adapter
private Context mCtx;
private List<Car> carList;
private RecyclerViewAnimator mAnimator;
private int AD_TYPE=1;
private int CONTENT_TYPE=2;
private int LIST_AD_DELTA=15;
public ProductAllCarAdapter(RecyclerView recyclerView,Context mCtx, List<Car> carList) {
this.mCtx = mCtx;
this.carList = carList;
mAnimator = new RecyclerViewAnimator(recyclerView);
}
#Override
public ProductAllCarAdapter.ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == AD_TYPE){
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_add_item, null);
ProductAllCarAdapter.ProductViewHolder vh = new ProductAllCarAdapter.ProductViewHolder(itemView);
mAnimator.onCreateViewHolder(itemView);
return vh;
} else {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_car_item, null);
ProductAllCarAdapter.ProductViewHolder vh = new ProductAllCarAdapter.ProductViewHolder(itemView);
mAnimator.onCreateViewHolder(itemView);
return vh;
}
}
#Override
public int getItemViewType(int position) {
if (position>0 && position % LIST_AD_DELTA == 0)
return AD_TYPE;
return CONTENT_TYPE;
}
#Override
public void onBindViewHolder(ProductAllCarAdapter.ProductViewHolder holder, int position) {
if (getItemViewType(position) == CONTENT_TYPE) {
final Car car = carList.get(holder.getAdapterPosition());
GlideApp.with(mCtx).load(car.getImg()).into(holder.imageView);
if (car.getVip() == 1) {
holder.relativeLayout.setBackgroundColor(ContextCompat.getColor(mCtx, R.color.colorVip));
holder.imageViewVIP.setVisibility(View.VISIBLE);
}
final String carid = String.valueOf(car.getCarid());
mAnimator.onBindViewHolder(holder.itemView, position);
} else {
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Context mcontext = view.getContext();
Bundle bundle = ActivityOptionsCompat.makeCustomAnimation(mcontext, android.R.anim.fade_in, android.R.anim.fade_out).toBundle();
Intent intent = new Intent(mcontext, AdsItem.class);
mcontext.startActivity(intent, bundle);
}
});
mAnimator.onBindViewHolder(holder.itemView, position);
}
}
private int getRealPosition(int position) {
if (LIST_AD_DELTA == 0) {
return position;
} else {
return position - position / LIST_AD_DELTA;
}
}
#Override
public long getItemId(int position) { return position; }
#Override
public int getItemCount() {
int additionalContent = 0;
if (carList.size() > 0 && carList.size() > LIST_AD_DELTA) {
additionalContent = ( carList.size() / LIST_AD_DELTA);
}
return carList.size() + additionalContent;
}
public static class ProductViewHolder extends RecyclerView.ViewHolder {
private View mView;
ImageView imageView, imageViewVIP;
RelativeLayout relativeLayout;
public ProductViewHolder(View itemView) {
super(itemView);
mView = itemView;
imageView = itemView.findViewById(R.id.imageView);
imageViewVIP = itemView.findViewById(R.id.imageViewVIP);
relativeLayout = itemView.findViewById(R.id.relativeLayoutpc);
}
public void setOnClickListener(View.OnClickListener listener) {
mView.setOnClickListener(listener);
}
}
I think problem onBindViewHolder function use wrong holder. ArrayList also return true value but on scroll it mixes.
You just have to add the corresponding else of the following if statement block.
if (car.getVip() == 1) {
holder.relativeLayout.setBackgroundColor(ContextCompat.getColor(mCtx, R.color.colorVip));
holder.imageViewVIP.setVisibility(View.VISIBLE);
} else {
holder.relativeLayout.setBackgroundColor(ContextCompat.getColor(mCtx, R.color.colorNormal));
holder.imageViewVIP.setVisibility(View.GONE);
}
This is inside your onBindViewHolder function where the view type is CONTENT_TYPE.
Hope that solves your problem.