ExpandableRecyclerView - How to expand and collapse multiple CardViews simultaneously - java

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

Related

Transition between 2 recycler views having cards

I have 2 recycler views that have cards.They basically look the same have the same number of cards and everthing. The first one is for like viewing and other stuff and the second one is only for deleting cards. OnlongClicking a card in the first recycler view triggers the opening of the second recycler view. I wanted to add transitions in between them like what keep notes has done when a card is long clicked. Both the recycler view use the same adapter. I have set what the adapter should do based on passing context to the adapter. enter image description here this is my 1st layout having the 1st recycler view.enter image description here this is the 2nd layout having the second recycler view.I want like a seamless transition for the tool bar again just like what Google keeps has done.A simple solution would be preferred as I am very new to this stuff.
Here is the java code for the adapter.
public class Task_recycle_view_adapter extends RecyclerView.Adapter<Task_recycle_view_adapter.ViewHolder>{
private List<struct_task> task_list= new ArrayList<>();
private ArrayList<String> isSelected=new ArrayList<String>();
protected Context context1;
protected Context context2;
private String labelName;
private String taskName;
private ConstraintLayout label_menu_avatar;
public Task_recycle_view_adapter(Context context1,Context context2)
{
this.context1=context1;
this.context2=context2;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {//parent is the parent of the recycle view it is taken as an arg to use it to attach the every view to the parent view
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_task,parent,false);//to inflate a layout
ViewHolder holder= new ViewHolder(view);
return holder;
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.taskname.setText(task_list.get(position).getTask_name());
holder.taskid.setText(String.valueOf(task_list.get(position).getTask_id()));
if(context2==null && context1!=null) {
String taskName=task_list.get(position).getTask_name();
Long taskid=task_list.get(position).getTask_id();
String duedate=task_list.get(position).getDue_date();
holder.parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DataBaseHelper dataBaseHelper = new DataBaseHelper(context1);
ArrayList<SubTaskModel> subtask_list=(ArrayList<SubTaskModel>) dataBaseHelper.getAllSubTasksFor(labelName, Long.parseLong(holder.taskid.getText().toString()));
Intent intent1 =new Intent(context1,ViewTaskActivity.class);
intent1.putExtra("label_name",labelName);
intent1.putExtra("task_id",taskid);
intent1.putExtra("task_name",taskName);
intent1.putExtra("due_date",duedate);
intent1.putParcelableArrayListExtra("subtask_list", (ArrayList<? extends Parcelable>) subtask_list);
context1.startActivity(intent1);
}
});
holder.parent.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Intent intent2 = new Intent(context1, Delete_page_Activity.class);
intent2.putParcelableArrayListExtra("task_list", (ArrayList<? extends Parcelable>) task_list);
intent2.putExtra("label_name",labelName);
intent2.putExtra("selected_task",taskName);
Pair[] pairs = new Pair[1];
pairs[0]= new Pair<View,String>(label_menu_avatar,"transition1");
ActivityOptions options= ActivityOptions.makeSceneTransitionAnimation((Activity) context1,pairs);
context1.startActivity(intent2,options.toBundle());
return true;
}
});
}
if(context2!=null && context1==null)
{
if(taskName.equals(task_list.get(position).getTask_name()))
{
holder.active=1;
isSelected.add(holder.taskid.getText().toString());
holder.parent.findViewById(R.id.layout_for_every_task).setBackgroundResource(R.drawable.background_for_task_card);
}
holder.parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.active==0) {
isSelected.add(holder.taskid.getText().toString());
v.findViewById(R.id.layout_for_every_task).setBackgroundResource(R.drawable.background_for_task_card);
holder.active=1;
}
else {
isSelected.remove(holder.taskid.getText().toString());
v.findViewById(R.id.layout_for_every_task).setBackgroundResource(R.drawable.background_for_task_card_transparent);
holder.active=0;
}
}
});
}
// subtasks 1 to 5
if(task_list.get(position).getSubtask1()!=null)
holder.subtask1.setText(task_list.get(position).getSubtask1());
else
holder.subtask1.setVisibility(View.GONE);
if(task_list.get(position).getSubtask2()!=null)
holder.subtask2.setText(task_list.get(position).getSubtask2());
else
holder.subtask2.setVisibility(View.GONE);
if(task_list.get(position).getSubtask3()!=null)
holder.subtask3.setText(task_list.get(position).getSubtask3());
else
holder.subtask3.setVisibility(View.GONE);
if(task_list.get(position).getSubtask4()!=null)
holder.subtask4.setText(task_list.get(position).getSubtask4());
else
holder.subtask4.setVisibility(View.GONE);
if(task_list.get(position).getSubtask5()!=null)
holder.subtask5.setText(task_list.get(position).getSubtask5());
else
holder.subtask5.setVisibility(View.GONE);
// due date
if(task_list.get(position).getDue_date()!=null)
holder.duedate.setText(task_list.get(position).getDue_date());
else
holder.duedate.setVisibility(View.GONE);
// progress
holder.progresscircle.setProgress(task_list.get(position).getProgress());
}
#Override
public int getItemCount() {
return task_list.size();
}
public void setTask_list(List<struct_task> task_list) {
this.task_list = task_list;//to refresh the data inside the recycler view
}
#Override
public int getItemViewType(int position) {
return position;
}
public String getLabelName() {
return labelName;
}
public void setLabelName(String labelName) {
this.labelName = labelName;
}
public ArrayList<String> getIsSelected() {
return isSelected;
}
public String getTaskName() {
return taskName;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
public void setLabel_menu_avatar(ConstraintLayout label_menu_avatar) {
this.label_menu_avatar = label_menu_avatar;
}
public static class ViewHolder extends RecyclerView.ViewHolder{// holds the view for every item inside the recycle view
private TextView taskname,taskid,duedate,subtask1,subtask2,subtask3,subtask4,subtask5;
private CardView parent;
private ProgressBar progresscircle;
public void setActive(int active) {
this.active = active;
}
private int active;
public ViewHolder(#NonNull View itemView) {
super(itemView);
taskid=itemView.findViewById(R.id.task_id);
taskname = itemView.findViewById(R.id.task_name);
parent = itemView.findViewById(R.id.card_for_every_task);
duedate = itemView.findViewById(R.id.due_date);
progresscircle = itemView.findViewById(R.id.progress_circular);
subtask1 = itemView.findViewById(R.id.subtask_1);
subtask2 = itemView.findViewById(R.id.subtask_2);
subtask3 = itemView.findViewById(R.id.subtask_3);
subtask4 = itemView.findViewById(R.id.subtask_4);
subtask5 = itemView.findViewById(R.id.subtask_5);
active=0;
}
}
}
Here is the code for the 1st activity i.e the 1st image:
public class TaskPageActivity extends AppCompatActivity {
private RecyclerView task_rv;//task recycler view
private FloatingActionButton addTask;
private long tasksNum;
private String labelName;
private DataBaseHelper dataBaseHelper = new DataBaseHelper(this);
private Task_recycle_view_adapter adapter= new Task_recycle_view_adapter(this,null);
private List<struct_task> tasks;
private EditText searchBar;
private ConstraintLayout search_btn;
private ConstraintLayout calendar_btn;
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_task_title);
getWindow().getSharedElementExitTransition();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
search_btn= findViewById(R.id.search_btn);
calendar_btn=findViewById(R.id.calendar_btn);
search_btn.setClickable(true);
search_btn.setFocusable(true);
labelName = getIntent().getExtras().getString("832715");
TextView txtLabelName = findViewById(R.id.Label_name);
txtLabelName.setText(labelName);
task_rv = findViewById(R.id.Recycle_view_task);
addTask = findViewById(R.id.add_task);
searchBar= (SearchBar) findViewById(R.id.search_bar);
tasksNum = getTasksNum(labelName, dataBaseHelper, adapter); //displays all tasks and return number of tasks
ConstraintLayout.LayoutParams params= (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
addTask.setOnClickListener(view -> {
tasksNum = getTasksNum(labelName, dataBaseHelper, adapter);
Intent intent = new Intent(TaskPageActivity.this, AddTaskPageActivity.class);
intent.putExtra("labelName", labelName);
intent.putExtra("taskID", tasksNum);
startActivity(intent);
});
search_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(searchBar.getVisibility()==View.INVISIBLE) {
search_btn.setAlpha(.5f);
searchBar.setVisibility(View.VISIBLE);
searchBar.requestFocus();
imm.showSoftInput(searchBar,InputMethodManager.SHOW_IMPLICIT);
ConstraintLayout.LayoutParams params= (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
params.verticalBias = .55f;
searchBar.setLayoutParams(params);
searchBar.requestFocus();
}
else {
searchBar.setVisibility(View.INVISIBLE);
search_btn.setAlpha(1.0f);
}
}
});
searchBar.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
if(params.verticalBias==.9f) {
searchBar.requestFocus();
params.verticalBias = .55f;
searchBar.setLayoutParams(params);
}
searchBar.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if((event.getAction()==KeyEvent.ACTION_DOWN) && (keyCode==KeyEvent.KEYCODE_ENTER) && params.verticalBias==.55f)
{
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
searchBar.requestFocus();
params.verticalBias = .9f;
searchBar.setLayoutParams(params);
searchBar.clearFocus();
imm.hideSoftInputFromWindow(searchBar.getWindowToken(),0);
}
return false;
}
});
}
}
});
searchBar.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
filter(s.toString());
}
});
AlertDialog alertDialog = new AlertDialog.Builder(TaskPageActivity.this).create();
calendar_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(calendar_btn.getAlpha()==1.0f) {
calendar_btn.setAlpha(.5f);
LayoutInflater inflater = getLayoutInflater();
View view1 = inflater.inflate(R.layout.dialog_calendar,null);
alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
alertDialog.setView(view1);
CalendarView mCalendarView= view1.findViewById(R.id.calendar);
mCalendarView.setMinDate(Calendar.getInstance().getTimeInMillis());
alertDialog.show();
}
}
});
alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
if(calendar_btn.getAlpha()==.5f)
calendar_btn.setAlpha(1.0f);
}
});
}
private void filter(String string) {
ArrayList<struct_task> filteredList = new ArrayList<>();
for(struct_task item: tasks)
{
if(item.getTask_name().contains(string) || item.getTask_name().contains(string.toUpperCase()))
{
filteredList.add(item);
}
}
if(filteredList.size()!=0) {
adapter.setTask_list(filteredList);
task_rv.setAdapter(adapter);
}
}
#Override
public void onBackPressed() {
if(searchBar.getText().toString().length()!=0) {
showAllTasks(labelName, dataBaseHelper, adapter);
searchBar.setText(null);
searchBar.setVisibility(View.INVISIBLE);
search_btn.setAlpha(1.0f);
}
else if(searchBar.getText().toString().length()==0)
{
super.onBackPressed();
}
}
#Override
protected void onResume() {
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
showAllTasks(labelName, dataBaseHelper, adapter);
if(params.verticalBias==.54f) {
searchBar.requestFocus();
params.verticalBias = .9f;
searchBar.setLayoutParams(params);
searchBar.clearFocus();
}
if(searchBar.getText().toString().length()==0) {
showAllTasks(labelName, dataBaseHelper, adapter);
}
else {
filter(searchBar.getText().toString());
}
super.onResume();
}
private void showAllTasks(String labelName, DataBaseHelper dataBaseHelper, Task_recycle_view_adapter adapter) {
tasks = dataBaseHelper.getAllTasksFor(labelName);
adapter.setLabelName(labelName);
adapter.setTask_list(tasks);
task_rv.setAdapter(adapter);
task_rv.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
}
long getTasksNum(String labelName, DataBaseHelper dataBaseHelper, Task_recycle_view_adapter adapter) {
return dataBaseHelper.getLastTaskID(labelName)+1; //to determine ID of next task
}
#Override
protected void onUserLeaveHint() {
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
params.verticalBias=.9f;
searchBar.setLayoutParams(params);
searchBar.setText(null);
searchBar.clearFocus();
super.onUserLeaveHint();
}
}
And finally for the 2nd activity which is triggered by longclicking any card
public class Delete_page_Activity extends AppCompatActivity {
private Task_recycle_view_adapter recycle_view_adapter = new Task_recycle_view_adapter(null,this);
private ArrayList<String> delete_list=new ArrayList<>();
private DataBaseHelper dataBaseHelper = new DataBaseHelper(this);
private String labelName=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_delete_page);
overridePendingTransition(0,0);
Toolbar toolbar=findViewById(R.id.toolbar_bar);
ImageView close_btn=findViewById(R.id.close_btn);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
ArrayList<struct_task> task_list = getIntent().getParcelableArrayListExtra("task_list");
labelName=getIntent().getExtras().getString("label_name");
String task = getIntent().getExtras().getString("selected_task");
Log.e("test",labelName);
RecyclerView recyclerView = findViewById(R.id.delete_Recycler_View);
recycle_view_adapter.setTaskName(task);
recycle_view_adapter.setTask_list(task_list);
recyclerView.setAdapter(recycle_view_adapter);
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
close_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_menu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId())
{
case R.id.tool_bar_item1:
delete_list = recycle_view_adapter.getIsSelected();
if(delete_list.size()==0)
{
Toast toast1= new Toast(this);
toast1.setDuration(Toast.LENGTH_SHORT);
LayoutInflater inflater= (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view= inflater.inflate(R.layout.activity_toast_msg1,null);
view.setBackgroundResource(R.drawable.background_for_calendar);
toast1.setView(view);
toast1.show();
}
else {
for (int task = 0; task < delete_list.size(); task++) {
dataBaseHelper.deleteOneTask(labelName, Long.parseLong(delete_list.get(task)));
}
finish();
}
break;
case R.id.tool_bar_item2:
Boolean flag=dataBaseHelper.deleteAllCompletedTasks(labelName);
if(flag)
finish();
else
{
Toast toast2= new Toast(this);
toast2.setDuration(Toast.LENGTH_SHORT);
LayoutInflater inflater= (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view= inflater.inflate(R.layout.activity_toast_msg2,null);
view.setBackgroundResource(R.drawable.background_for_calendar);
toast2.setView(view);
toast2.show();
}
break;
}
return true;
}
}
I have added the code related to the scene transititon which is in the adapter.
here is a gif of the problem when i add a scene transition
enter image description here
As u can see there are 2 pauses when going from 1st to 2nd activity 1st pause being longer 2nd one shorter. And also a pause when exiting the 2nd activity which seems to have the same duration as the 2nd pause.

Recycleview cardview Onclick duplicate effects when scrolling

I'm making my first app (calendar),
clicking the cardview item applies the same effect (changing Textview text color and Imageview background) to other items when scrolling the recycleview
in the main activity
RecyclerView daysRecyclerView;
DaysAdapter daysAdapter;
private RecyclerView.LayoutManager horizontalLayout;
ArrayList<DaysModel> daysModels;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calendar);
daysModels = getDaysList();
initDaysRecycleview();
}
private void initDaysRecycleview(){
daysRecyclerView = findViewById(R.id.daysRecyclerView);
daysRecyclerView.setHasFixedSize(true);
horizontalLayout = new LinearLayoutManager(this,RecyclerView.HORIZONTAL,false);
daysAdapter = new DaysAdapter(daysModels);
daysRecyclerView.setLayoutManager(horizontalLayout);
daysRecyclerView.setAdapter(daysAdapter);
daysAdapter.setOnItemClickListener(new DaysAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
dayClickHandler(position, 1);
}
});
}
public void dayClickHandler(int position, int change){
daysModels.get(position).changeDayHighlight(change);
daysAdapter.notifyItemChanged(position);
}
private ArrayList<DaysModel> getDaysList(){
//Not accurate used for testing
ArrayList<DaysModel> models = new ArrayList<DaysModel>();
String[] dayName ={"SAT","SUN","MON","TUE","WED","THU","FRI","SAT","SUN","MON","TUE","WED","THU","FRI","SAT","SUN","MON","TUE","WED","THU","FRI","SAT","SUN","MON","TUE","WED","THU","FRI","SAT","SUN","MON"};
int i,j;
for (i = 0;i <dayName.length;i++){
j =i+1;
models.add(new DaysModel(dayName[i], j, 0, false));
}
return models;
}
I'm using an interface for the onClickListener.
ViewHolder
public class DaysViewHolder extends RecyclerView.ViewHolder {
TextView hDayName,hDayNumber;
ImageView currentDayHighlight;
CardView dayCard;
public DaysViewHolder(View itemView, DaysAdapter.OnItemClickListener listener) {
super(itemView);
this.hDayName = itemView.findViewById(R.id.dayName);
this.hDayNumber = itemView.findViewById(R.id.dayNumber);
this.currentDayHighlight = itemView.findViewById(R.id.dayHihlight);
this.dayCard = itemView.findViewById(R.id.dayCard);
dayCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onItemClick(position);
}
}
}
});
}
}
Adapter
public class DaysAdapter extends RecyclerView.Adapter<DaysViewHolder> {
Context context;
ArrayList<DaysModel> daysModels;
OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
public DaysAdapter(ArrayList<DaysModel> daysModels) {
this.daysModels = daysModels;
}
#NonNull
#Override
public DaysViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.day_card,parent,false);
DaysViewHolder daysViewHolder = new DaysViewHolder(view, mListener);
return daysViewHolder;
}
#Override
public void onBindViewHolder(#NonNull DaysViewHolder holder, int position) {
DaysModel currentItem = daysModels.get(position);
holder.hDayName.setText(currentItem.getDayName());
holder.hDayNumber.setText(String.valueOf(currentItem.getDayNumber()));
if(currentItem.isDayHighlighted() == 1){
holder.currentDayHighlight.setBackgroundResource(R.drawable.tiny_background);
holder.hDayNumber.setTextColor(Color.BLACK);
}
}
#Override
public int getItemCount() {
return daysModels.size();
}
}
sorry for the long code text, I've just started and I am already struggling.
All you need is to set else part for you if condition in bind method of Adapter class.
So change your bind method to something like this:
#Override
public void onBindViewHolder(#NonNull DaysViewHolder holder, int position) {
DaysModel currentItem = daysModels.get(position);
holder.hDayName.setText(currentItem.getDayName());
holder.hDayNumber.setText(String.valueOf(currentItem.getDayNumber()));
if(currentItem.isDayHighlighted() == 1){
holder.currentDayHighlight.setBackgroundResource(R.drawable.tiny_background);
holder.hDayNumber.setTextColor(Color.BLACK);
}else{
holder.currentDayHighlight.setBackgroundResource(/*what ever you want for default situation*/);
holder.hDayNumber.setTextColor(/* for example Color.White*/);
}
}

Nested Recycler View, Child And Parent Remove Issue

I have created a Nested recycle rview with parent and child both dynamic.Addition to both Parent and Child is working fine.Deletion from child is working fine.I want to remove parent view when all the child views for the same is removed.Confused about how could i implement the same.
Here is the child Adapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<ToDoModel> values;
private Context context;
//private OnEditListener onEditListener;
AlertDialog alertDialog;
/*public MyAdapter(List<ToDoModel> context) {
this.values = context;
this.onEditListener = onEditListener;
}*/
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView txtHeader;
public TextView txtFooter;
public ImageView mIcon;
public View layout;
public ImageView deleteItem;
public CheckBox doneButton;
public ImageView editItem;
public ViewHolder(View v) {
super(v);
layout = v;
txtHeader = (TextView) v.findViewById(R.id.firstLine);
txtFooter = (TextView) v.findViewById(R.id.secondLine);
mIcon = (ImageView) v.findViewById(R.id.icon);
deleteItem = (ImageView) v.findViewById(R.id.deleteButton);
doneButton = (CheckBox) v.findViewById(R.id.checkBox);
editItem = (ImageView) v.findViewById(R.id.editButton);
}
}
public void add(int position, ToDoModel item) {
values.add(position, item);
sort();
notifyDataSetChanged();
//notifyItemInserted(position);
}
public void replace(ToDoModel item)
{
int editPos;
editPos = values.indexOf(item);
values.set(editPos,item);
sort();
notifyDataSetChanged();
}
public void sort() {
if ((int) values.size() > 1) {
Collections.sort(values);
}
}
public void remove(int position) {
values.remove(position);
notifyDataSetChanged();
}
public MyAdapter(List<ToDoModel> myDataset) {
values = myDataset;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
LayoutInflater inflater = LayoutInflater.from(
parent.getContext());
View v =
inflater.inflate(R.layout.todo_row_view, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final ToDoModel toDoModel = values.get(position);
switch ((String) toDoModel.task) {
case "To Go":
holder.mIcon.setImageResource(R.drawable.ic_explore24px);
break;
case "To Get":
holder.mIcon.setImageResource(R.drawable.ic_shoppingbag24px);
break;
case "To Do":
holder.mIcon.setImageResource(R.drawable.ic_todo);
break;
default:
break;
}
holder.txtHeader.setText(toDoModel.header);
holder.txtFooter.setText(toDoModel.task + " | " + toDoModel.tod + " | " + toDoModel.footer);
holder.doneButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (buttonView.isChecked()) {
//holder.mIcon.setImageResource(R.drawable.ic_check_circle24px);
Toast.makeText(buttonView.getContext(), "Marked As Done", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(buttonView.getContext(), "Marked As UnDone", Toast.LENGTH_SHORT).show();
}
}
});
holder.deleteItem.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
View view = LayoutInflater.from(v.getContext()).inflate(R.layout.delete_promptdialog,null);
Button YesButton = (Button) view.findViewById(R.id.buttonYes);
Button NoButton = (Button) view.findViewById(R.id.buttonNo);
YesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
remove(position);
Toast.makeText(v.getContext(), "List Item Removed", Toast.LENGTH_SHORT).show();
alertDialog.dismiss();
}
});
NoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Delete Canceled", Toast.LENGTH_SHORT).show();
alertDialog.dismiss();
}
});
builder.setView(view);
alertDialog=builder.create();
alertDialog.show();
/*remove(position);
Toast.makeText(v.getContext(), "List Item Removed", Toast.LENGTH_SHORT).show();*/
}
});
/* holder.editItem.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
onEditListener.onEditClick(values.get(position));
//Toast.makeText(v.getContext(), "List Edit", Toast.LENGTH_SHORT).show();
}
});*/
}
/*public interface OnEditListener {
void onEditClick(ToDoModel currentData);
}*/
#Override
public int getItemCount() {
return values.size();
}
}
Here is the Parent Adapter
public class ParentAdapter extends RecyclerView.Adapter<ParentAdapter.ParentViewHolder> {
private RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
public List<TodoParent> parentList;
public TodoParent todayList;
public static long todayEpochDate;
public ParentAdapter(List<TodoParent> parentList, MainFragment mainFragment) {
this.parentList = parentList;
}
public void add(int position, TodoParent item) {
parentList.add(position, item);
sort();
notifyDataSetChanged();
//notifyItemInserted(position);
}
public void sort() {
if ((int) parentList.size() > 1) {
Collections.sort(parentList);
//if(!(todayList.ParentTitle.isEmpty())) Collections.swap(parentList, parentList.indexOf(todayList), 0);
}
/* if ( todayList )
{
System.out.println("Entering Swap");
setToday(todayList);
}*/
}
public void setToday(TodoParent item) {
int todayPos;
todayPos = parentList.indexOf(item);
parentList.remove(todayPos);
notifyDataSetChanged();
parentList.add(0,item);
notifyDataSetChanged();
}
#NonNull
#Override
public ParentAdapter.ParentViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.todo_parent_view,parent,false);
ParentViewHolder vh = new ParentViewHolder(view);
return vh;
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onBindViewHolder(#NonNull ParentViewHolder holder, int position) {
TodoParent todoParent = parentList.get(position);
todoParent.ParentId = position;
Calendar mCal;
mCal = Calendar.getInstance();
int mDay = mCal.get(Calendar.DAY_OF_MONTH);
int mMonth = mCal.get(Calendar.MONTH);
int mYear = mCal.get(Calendar.YEAR);
String dateString = mDay +"/"+ (mMonth+1) +"/" + mYear;
try {
todayEpochDate = new SimpleDateFormat("dd/MM/yyyy").parse(dateString).getTime()/1000;
} catch (ParseException e) {
e.printStackTrace();
}
if((long)todayEpochDate == (long)todoParent.EpochTime)
{
holder.mTitle.setText("Today");
todayList = todoParent;
System.out.println("todayE:"+todayEpochDate);
System.out.println("SelectedE:"+todoParent.EpochTime);
}
else
{
holder.mTitle.setText(todoParent.ParentTitle);
System.out.println("today:"+todayEpochDate);
System.out.println("Selected:"+todoParent.EpochTime);
}
LinearLayoutManager layoutManager = new LinearLayoutManager(holder.childView.getContext(),
LinearLayoutManager.VERTICAL,false);
layoutManager.setInitialPrefetchItemCount(todoParent.mChildList.size());
holder.childView.setLayoutManager(layoutManager);
MyAdapter myAdapter = new MyAdapter(todoParent.mChildList);
holder.childView.setAdapter(myAdapter);
holder.childView.setRecycledViewPool(viewPool);
}
#Override
public int getItemCount() {
return parentList.size();
}
public class ParentViewHolder extends RecyclerView.ViewHolder {
public TextView mTitle;
public RecyclerView childView;
public ParentViewHolder(#NonNull View itemView) {
super(itemView);
mTitle = itemView.findViewById(R.id.mParentTitle);
childView = itemView.findViewById(R.id.mChildView);
}
}
}
remove for child is working fine. How to remove Parent here when there are no more child views?

CardView not expanding on 2nd click

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();
}
}
});

Recyclerview holder mixes on scroll

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.

Categories