Change image view background of View Pager2 selected image in android - android

I am trying to changing the background imageview of viewpager2 selected imageview in android. But in my case not changing image view background, when viewpager2 selected. Below code to change image view background.
final List<Integer> names = new ArrayList<Integer>();
for(int i=0;i<5;i++){
names.add(i);
}
insideRoomAdapter = new InsideRoomAdapter(context,names);
viewPager.setAdapter(insideRoomAdapter);
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
#Override
public void onPageSelected(int position) {
super.onPageSelected(position);
for(int i=0;i<names.size();i++){
if(names.get(position) == position){
Toast.makeText(context,"pos:"+ names.get(position),Toast.LENGTH_SHORT).show();
insideRoomAdapter.imageView.setBackground(ContextCompat.getDrawable(context,R.drawable.selected_light_bg));
viewPager.getAdapter().notifyDataSetChanged();
}else {
insideRoomAdapter.imageView.setBackground(ContextCompat.getDrawable(context,R.drawable.inside_room_item_bg));
viewPager.getAdapter().notifyDataSetChanged();
}
}
}
#Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});
My Adapter class
public class InsideRoomAdapter extends RecyclerView.Adapter<InsideRoomAdapter.ViewHolder> {
Context context;
List<Integer> list;
ImageView imageView;
public InsideRoomAdapter(Context context,List<Integer> list) {
this.context = context;
this.list = list;
}
#NonNull
#Override
public InsideRoomAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.inside_room_items,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull InsideRoomAdapter.ViewHolder holder, int position) {
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context,"light clicked",Toast.LENGTH_LONG).show();
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.inside_light_img);
}
}
}
Anyone can guide me how to change image view background, when viewpager2 selected.
Expected like this
Thanks in Advance.

I think you are approaching this in the wrong way. What you need is a public method for your adapter which stores the position selected from your viewpager2's onPageSelected() and in onBindViewHolder() method of your adapter simply use a check for selecting the background to use.
I have made changes to your adapter as below:
public class InsideRoomAdapter extends RecyclerView.Adapter<InsideRoomAdapter.ViewHolder> {
private Context context;
private List<Integer> list;
//moved ImageView to ViewHolder class as private
private int selectedPosition; //the int value for keeping track of your selected position
public InsideRoomAdapter(Context context,List<Integer> list) {
this.context = context;
this.list = list;
this.selectedPosition = 0; //initialize it here
}
#NonNull
#Override
public InsideRoomAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.inside_room_items,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull InsideRoomAdapter.ViewHolder holder, int position) {
/* Since ImageView was moved reference it from the holder like below
* Use a simple check to verify it the adapter position matches with the selectedPosition
* if so simply set the backgrounds as required
*/
if(position == selectedPosition) {
holder.imageView.setBackground(ContextCompat.getDrawable(context,R.drawable.selected_light_bg));
} else {
holder.imageView.setBackground(ContextCompat.getDrawable(context,R.drawable.inside_room_item_bg));
}
holder.imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context,"light clicked",Toast.LENGTH_LONG).show();
}
});
}
public void setSelectedPosition(int newPosition) {
this.selectedPosition = newPosition;
notifyDataSetChanged();
/* If you require better animations make use of notifyItemChanged() instead
* save selectedPosition value in a temp variable before swap
* and call notifyItemChanged() for both positions old and new
*/
}
#Override
public int getItemCount() {
return list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.inside_light_img);
}
}
}
And then instead of complicating your code your onPageSelected() should eb something like this
#Override
public void onPageSelected(int position) {
super.onPageSelected(position);
insideRoomAdapter.setSelectedPosition(position);
}
That's all, let us know if this answer helped solve your issue.

Related

itemView.getTag() returns -1

I am using RecyclerView and I want to view the the data of list item that I click on. I'm using itemView.getTag() to get the value of index and typecasting it to my CustomAdapter.
I tried various ways but not to help. please help me.
Here's my code:
public class DonorAdapter extends RecyclerView.Adapter<DonorAdapter.ViewHolder> {
ArrayList<Donor> donorsList;
ItemSelected activity;
public interface ItemSelected{
void onItemClicked(int index);
}
public DonorAdapter(Context context, ArrayList<Donor> list){
activity = (ItemSelected) context;
donorsList = list;
}
public class ViewHolder extends RecyclerView.ViewHolder
{
ImageView ivDonorGender;
TextView tvListName;
TextView tvBloodGroup;
public ViewHolder(#NonNull final View itemView) {
super(itemView);
ivDonorGender = itemView.findViewById(R.id.ivDonorGender);
tvListName = itemView.findViewById(R.id.tvListName);
tvBloodGroup = itemView.findViewById(R.id.tvListBloodGroup);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
activity.onItemClicked(donorsList.indexOf((Donor) itemView.getTag()));
}
});
}
}
#NonNull
#Override
public DonorAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.donors_list, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull DonorAdapter.ViewHolder holder, int position) {
holder.tvListName.setText(donorsList.get(position).getName());
holder.tvBloodGroup.setText(donorsList.get(position).getSurname());
}
}
#Override
public int getItemCount() {
return donorsList.size();
}
}
I am new to android so pardon me if I can't explain properly
Here's the problematic part
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
activity.onItemClicked(donorsList.indexOf((Donor)
itemView.getTag()));
}
I think you need to set the tag for each recycled item in onBindViewHolder
#Override
public void onBindViewHolder(#NonNull DonorAdapter.ViewHolder holder, int position) {
holder.tvListName.setText(donorsList.get(position).getName());
holder.tvBloodGroup.setText(donorsList.get(position).getSurname());
holder.itemView.setTag(donorsList.get(position)); // change here
}
}

Recyclerview single item selection not working correctly

I've implemented a recyclerview with staggered gridLayout containing about 31 items in the arrayList, recyclerview is working correctly, but I faced issue relating to single item selection.
When I select the value till "26" as shown in figure, its working fine
But, when I select the value after "26", the values from top most item are also selected, as shown in this next figure.
I require to only select one item at a time.
I've implemented the following code in my adapter class
public class DialogAdapter extends
RecyclerView.Adapter<DialogAdapter.DialogHolder>
{
// components
public Context context;
public ArrayList<AlertDialogModel> dialogArrayList = new
ArrayList<AlertDialogModel>();
private final ArrayList<Integer> selected = new ArrayList<>();
private int lastCheckedPosition = -1;
public Interface interface;
// parameterized constructor
public DialogAdapter(Context context, ArrayList<AlertDialogModel>
dialogArrayList,Interface interface)
{
this.context = context;
this.dialogArrayList = dialogArrayList;
this.interface = interface;
}
#NonNull
#Override
public DialogHolder onCreateViewHolder(#NonNull ViewGroup parent, int
viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_cardview,parent,false);
DialogHolder dialogHolder = new DialogHolder(view);
return dialogHolder;
}
#Override
public void onBindViewHolder(#NonNull final DialogHolder holder, final int position)
{
final AlertDialogModel alertDialogModel = dialogArrayList.get(position);
holder.textView.setText(alertDialogModel.getDisplayValue());
if(lastCheckedPosition == position)
{
holder.textView.setTextColor(context.getResources().getColor(R.color.white));
holder.textView.setBackground(context.getResources().getDrawable(R.drawable.circular_shape_selection));
}
else
{
}
holder.textView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
lastCheckedPosition = position;
notifyDataSetChanged();
holder.textView.setTextColor(context.getResources().getColor(R.color.white));
holder.textView.setBackground(context.getResources().getDrawable(R.drawable.circular_shape_selection));
interface.getSelectedValue(alertDialogModel.getDisplayValue());
}
});
}
#Override
public int getItemCount()
{
return dialogArrayList.size();
}
public static class DialogHolder extends RecyclerView.ViewHolder
{
public TextView textView;
public DialogHolder(View itemView)
{
super(itemView);
textView = (TextView)itemView.findViewById(R.id.textView);
}
}
}
Can anyone relate my code and identify the issue ?
holder.textView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
lastCheckedPosition = position;
notifyDataSetChanged();
holder.textView.setTextColor(context.getResources().getColor(R.color.white));
holder.textView.setBackground(context.getResources().getDrawable(R.drawable.circular_shape_selection));
interface.getSelectedValue(alertDialogModel.getDisplayValue());
//below line is important to remove previous selected position from the variable
lastCheckedPosition = -1;
}
});
you should put the text view to the original state:
if(lastCheckedPosition == position)
{
holder.textView.setTextColor(context.getResources().getColor(R.color.white));
holder.textView.setBackground(context.getResources().getDrawable(R.drawable.circular_shape_selection));
}
else
{
holder.textView.setTextColor(context.getResources().getColor(R.color.transparent));
holder.textView.setBackground(null));
}

RecyclerView get View by position

I have a RecyclerView and each CardView contains a TextView and an ImageView. Whenever I click an item, I want to set the image visibility to VISIBLE and to set the previous clicked item image's visibility to INVISIBLE.
This is my Adapter class :
public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.ViewHolder>{
private Context context;
private List<Category> lista;
private LayoutInflater layoutInflater;
private IncomeCategoryActivity activity;
private static final int CATEGORY_REQUEST=6;
private static final int ITEM_EDIT=1;
private static final int ITEM_DELETE=2;
private static final int EDIT_REQUEST=7;
private int current_pos=-1;
public CategoryAdapter(List<Category> lista, Context context, IncomeCategoryActivity activity) {
this.context = context;
this.lista = lista;
this.activity=activity;
layoutInflater=LayoutInflater.from(context);
}
#Override
public CategoryAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=layoutInflater.inflate(R.layout.category_layout, parent, false);
ViewHolder viewHolder=new ViewHolder(view, activity);
return viewHolder;
}
#Override
public void onBindViewHolder(CategoryAdapter.ViewHolder holder, int position) {
holder.imageView.setImageURI(lista.get(position).getUri());
holder.textView.setText(lista.get(position).getCategory());
holder.position = position;
holder.category=lista.get(position);
if(holder.category.isChecked()==true){
holder.imageViewCheck.setVisibility(View.VISIBLE);
current_pos=position;
} else {
holder.imageViewCheck.setVisibility(View.INVISIBLE);
}
}
#Override
public int getItemCount() {
return lista.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener{
public ImageView imageView;
public TextView textView;
public ImageView imageViewCheck;
public int position;
public Category category;
public IncomeCategoryActivity activity;
public ViewHolder(View itemView, IncomeCategoryActivity activity) {
super(itemView);
this.activity=activity;
imageView=itemView.findViewById(R.id.customCategoryImageView);
textView=itemView.findViewById(R.id.customCategoryTextView);
imageViewCheck=itemView.findViewById(R.id.customCheckImageView);
itemView.setOnClickListener(this);
itemView.setOnCreateContextMenuListener(this);
}
#Override
public void onClick(View v) {
String aux=textView.getText().toString();
if(aux=="CATEGORIE NOUĂ"){
Intent intent=new Intent(context, CustomIncomeActivity.class);
activity.startActivityForResult(intent, CATEGORY_REQUEST);
}
else{
imageViewCheck.setVisibility(View.VISIBLE);
int pozitie_check=getLayoutPosition();
Intent intent=new Intent(context, AddIncomeActivity.class);
intent.putExtra("categorie_venit", aux);
intent.putExtra("position_check", pozitie_check);
activity.setResult(Activity.RESULT_OK, intent);
activity.finish();
}
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle("Selectează acțiunea");
MenuItem edit=menu.add(0, ITEM_EDIT, 0, "Modifică");
MenuItem delete=menu.add(0, ITEM_DELETE, 0, "Șterge");
edit.setOnMenuItemClickListener(this);
delete.setOnMenuItemClickListener(this);
}
#Override
public boolean onMenuItemClick(MenuItem item) {
int position=getLayoutPosition();
if (item.getGroupId() == 0) {
if(item.getItemId()==ITEM_EDIT){
Category category=lista.get(position);
Intent intent=new Intent(activity, CustomIncomeActivity.class);
intent.putExtra("edit_icon", category.getUri());
intent.putExtra("edit_category", category.getCategory());
intent.putExtra("list_position", position);
activity.startActivityForResult(intent, EDIT_REQUEST);
}
else if(item.getItemId()==ITEM_DELETE){
lista.remove(position);
notifyDataSetChanged();
}
}
return true;
}
At this moment, whenever I click an item, there are two images VISIBLE on the RecyclerView: the clicked item's image and the previous clicked item's image. I think I need to get the previous View by its position and to manually set the visibility to INVISIBLE.
recycleView.getChildCount() and recycleView_parent.getChildAt() only gives the Adapter items which is shows only screen .
that means if your list has 200 items and the only 5 items shows on screen so we can find only 5 item with the help of recycleView
i am using one simple trick to solve the issue.
You can define Hashmap which hold your holder objects
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
ArrayList<Model> dataList;
Context context;
HashMap<Integer,ViewHolder> holderlist;
public MyAdapter(ArrayList<Model> dataList, Context context) {
this.context = context;
this.dataList = dataList;
holderlist = new HashMap<>();
}
And after that to save the holder in Hashmap
public void onBindViewHolder(final ViewHolder holder, final int position) {
if(!holderlist.containsKey(position)){
holderlist.put(position,holder);
}
Create a method in Adapter.
public MyListAdapter.ViewHolder getViewByPosition(int position) {
return holderlist.get(position);
}
Call this method from your Activity or whenever you want.
for (int i = 0; i < datalList.size(); i++) {
MyAdapter.ViewHolder holder = ((MyAdapter)recycleView.getAdapter()).getViewByPosition(i);
View view = holder.itemView;
TextView tv = view.findViewById(R.id.tv);
}
I have created the demo you can refer it and implement for single selection
recyclerView.setAdapter(new RecyclerView.Adapter() {
int selected_position = -1;
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new RecyclerView.ViewHolder(LayoutInflater.from(parent.getContext()).inflate(
R.layout.row_color_list,parent,false)) {
#Override
public String toString() {
return super.toString();
}
};
}
#Override
public void onBindViewHolder(#NonNull final RecyclerView.ViewHolder holder, int position) {
ImageView imageView = holder.itemView.findViewById(R.id.image);
if(selected_position == position){
imageView.setVisibility(View.VISIBLE);
}else {
imageView.setVisibility(View.GONE);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(selected_position != holder.getAdapterPosition()){
selected_position = holder.getAdapterPosition();
notifyDataSetChanged();
}
}
});
}
#Override
public int getItemCount() {
return 20;
}
});
You can do as following:
1) Declare a global variable:
private int selectedPos = -100; // Put any irrelevant number you want
2) Set selected position onClick() :
#Override
public void onClick(View v) {
selectedPos = getAdapterPosition();
}
3) Check selected postion and assign visibility inside onBindViewHolder():
#Override
public void onBindViewHolder(#NonNull final RecyclerView.ViewHolder holder, int position) {
if(position == selectedPos){
holder.imageViewCheck.setVisibility(View.VISIBLE);
} else {
holder.imageViewCheck.setVisibility(View.INVISIBLE);
}
}
Try this code..
add this code into adapter class for handling click event..
OnItemClick onItemClick;
public void setOnItemClick(OnItemClick onItemClick) {
this.onItemClick = onItemClick;
}
public interface OnItemClick {
void getPosition(String data); //pass any data to shared it.
}
after bind method..
#Override
public void onBindViewHolder(final ItemViewHolder holder, final int position) {
// below code handle click event on recycler view item.
final String str=mStringList.get(position); // here your boject
if(holder.category.isChecked()==true){
holder.imageViewCheck.setVisibility(View.VISIBLE);
current_pos=position;
} else {
holder.imageViewCheck.setVisibility(View.INVISIBLE);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onItemClick.getPosition(str); // pass your data.
}
});
}
after bind adapter into recycler view it means adapter not null then called below code..
adpater.setOnItemClick(new RecyclerViewAdpater.OnItemClick() {
#Override
public void getPosition(String data) {
// hear update your value for check into if condition.
data="sdfsdf";
adpater.notifyDataSetChanged();
}
});
and also read comments and also try to make custon class and access that object value and update after click it..
this code only how to handle click event into recycler view.

FirebaseRecyclerAdapter doesn't recognize first layout as a position

My Title is kind of hard to understand but basically when I add items into my database is should display it in a RecyclerView. Now in my RecyclerView I have two layouts but the problem is the first item of my database goes behind my first item in my other layout. So if I have 3 items in my database, it shows only 2 items from the database and the first item hides behind my first item in the RecyclerView which is a different layout that does not use the database at all.
This is my code:
FirebaseRecyclerOptions<Event> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<Event>()
.setQuery(query1, Event.class).build();
AccAdapter = new FirebaseRecyclerAdapter<Event, RecyclerView.ViewHolder>(firebaseRecyclerOptions){
final static int TYPE_HEADER = 0;
final static int TYPE_ITEM = 1;
#Override
public int getItemViewType(int position) {
if (position == 0) return TYPE_HEADER;
return TYPE_ITEM;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEADER){
View view = LayoutInflater.from(getActivity()).inflate(R.layout.recycler_view_row_add_items,
parent, false);
return new ProdudctHolder3(view);
} else {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.recycler_view_row_acc,
parent, false);
return new ProductHolder2(view);
}
}
#Override
protected void onBindViewHolder(final RecyclerView.ViewHolder holder, int position, final Event model) {
if (holder instanceof ProdudctHolder3){
((ProdudctHolder3) holder).addBackground.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(getActivity(), AccAddItems.class ));
}
});
} else{
final ProductHolder2 productHolder2 = (ProductHolder2) holder;
productHolder2.mName.setText(model.getName());
productHolder2.view.setBackgroundResource(getBackgroundDrawable(Integer.valueOf(model.getProductAmount())));
productHolder2.mbackground.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog = new Dialog(getActivity());
dialog.setContentView(R.layout.popup_edit_product);
SeekBar amountSeekBar = dialog.findViewById(R.id.amountSeekBar);
amountSeekBar.setMax(100);
amountSeekBar.setProgress(Integer.valueOf(model.getProductAmount()));
amountSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
progress = i;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
getRef(holder.getAdapterPosition()).child("productAmount").setValue(String.valueOf(progress));
dialog.dismiss();
}
});
dialog.show();
}
});
productHolder2.mbackground.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
final PopupMenu popupMenu = new PopupMenu(getActivity(), productHolder2.mbackground);
popupMenu.inflate(R.menu.menu_acc);
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.deleteProduct:
getRef(productHolder2.getAdapterPosition()).removeValue();
popupMenu.dismiss();
return true;
default:
return false;
}
}
});
popupMenu.show();
return true;
}
});
}
}
};
mAccRecyclerViewRef.setAdapter(AccAdapter);
My two Product Holders
private class ProdudctHolder3 extends RecyclerView.ViewHolder{
private RelativeLayout addBackground;
public ProdudctHolder3(View itemView) {
super(itemView);
addBackground = itemView.findViewById(R.id.mBackground2);
}
}
private class ProductHolder2 extends RecyclerView.ViewHolder{
private TextView mName;
private RelativeLayout mbackground;
private View view;
public ProductHolder2(View itemView) {
super(itemView);
mName = itemView.findViewById(R.id.ItemName);
mbackground = itemView.findViewById(R.id.mBackground1);
view = itemView.findViewById(R.id.amountIndicator);
}
}
The ideal solution would have been to set two adapters on a single RecyclerView but unfortunatelly this is not possible.
However, you can make a single custom Adapter that handles two types of items. I will explain this by getting an example.
Let's assume you need to display objects of two types, humans and aliens. Your objects require completely different layouts and completely different ViewHolders. Please see the below code for the ViewHolders:
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static class HumanViewHolder extends RecyclerView.ViewHolder {
public HumanViewHolder(View itemView) {
super(itemView);
//Prepare your ViewHolder
}
public void bind(Human human) {
//Display your human object
}
}
private static class AlienViewHolder extends RecyclerView.ViewHolder {
public AlienViewHolder(View itemView) {
super(itemView);
//Prepare your ViewHolder
}
public void bind(Alien alien) {
//Display your alien object
}
}
}
First you need to add two different constants to your adapter representing both type of views:
private static final int ITEM_TYPE_HUMAN;
private static final int ITEM_TYPE_ALIEN;
To keep things simple, let's also assume you store your objects in a list:
private List<Object> items = new ArrayList<>();
public MyAdapter(List<Object> items) {
this.items.addAll(items);
//Other stuff if needed
}
Now, the first you need to do, is to implement getItemViewType() method:
#Override
public int getItemViewType(int position) {
if (items.get(position) instanceof Human) {
return ITEM_TYPE_HUMAN;
} else {
return ITEM_TYPE_ALIEN;
}
}
Second, you need to use the item type inside the onCreateViewHolder() method like this:
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
if (viewType == ITEM_TYPE_HUMAN) {
View view = layoutInflater.inflate(R.layout.item_human, parent, false);
return new HumanViewHolder(view);
} else {
View view = layoutInflater.inflate(R.layout.item_alien, parent, false);
return new AlienViewHolder(view);
}
}
In the end, you just need to bind the proper view holder like this:
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
Object item = items.get(position);
if (viewHolder instanceof HumanViewHolder) {
((HumanViewHolder) viewHolder).bind((Human) item);
} else {
((AlienViewHolder) viewHolder).bind((Alien) item);
}
}
Why use the Firebase Recycler Adapter when you could easily make a custom one? If I understood well you want an item to be fixed at position 0 (header) while others will be added below the first one, right? If so, here is a solution I like to use:
public interface ViewType {
public int getViewType();
}
public interface ViewTypeDelegateAdapter {
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent);
public void onBindViewHolder(RecyclerView.ViewHolder holder, ViewType item);
}
public class ViewTypes {
public static int HEADER = 0
public static int ITEM = 1
}
public class ProductDelegateAdapter implements ViewTypeDelegateAdapter {
private int resID;
private Context context;
public ProductDelegateAdapter(int resID, Context context) {
this.resID = resID;
this.context = context;
}
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {
return new ProductHolder(LayoutInflater.from(parent.context).inflate(resID, parent, false));
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, ViewType item) {
(holder as ProductHolder).bind("test");
}
class ProductHolder extends RecyclerView.ViewHolder {
public ProductHolder(View view) {
super(view);
}
public void bind(String test) {
}
}
}
public class HeaderDelegateAdapter implements ViewTypeDelegateAdapter {
private int resID;
private Context context;
public ProductDelegateAdapter(int resID, Context context) {
this.resID = resID;
this.context = context;
}
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {
return new HeaderHolder(LayoutInflater.from(parent.context).inflate(resID, parent, false));
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, ViewType item) {
(holder as HeaderHolder).bind("test");
}
class HeaderHolder extends RecyclerView.ViewHolder {
public HeaderHolder(View view) {
super(view);
}
public void bind(String test) {
}
}
}
public class AccAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private Context context;
private List<ViewType> items;
private SparseArrayCompat<ViewTypeDelegateAdapter> delegateAdapters;
private ViewType headerItem;
public AccAdapter(Context context) {
this.context = context;
this.items = new ArrayList();
this.delegateAdapters = new SparseArrayCompat();
this.headerItem = new ViewType() {
#Override
public int getViewType() {
return ViewTypes.HEADER;
}
};
this.items.add(this.headerItem);
this.delegateAdapters.put(ViewTypes.HEADER, HeaderDelegateAdapter(R.id.test, this.context));
this.delegateAdapters.put(ViewTypes.ITEM, ProductDelegateAdapter(R.id.test, this.context));
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, Int viewType) {
return delegateAdapters.get(viewType).onCreateViewHolder(parent);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, Int position) {
delegateAdapters.get(getItemViewType(position)).onBindViewHolder(holder, items[position])
}
#Override
public Int getItemViewType(Int position) {
return items.get(position).getViewType();
}
#Override
public Int getItemCount() {
return items.getSize();
}
public void add(ViewType viewType) {
val initPosition = this.items.size - 1
this.items.add(item)
notifyItemRangeChanged(initPosition, this.items.size + 1)
}
}
public class Event implements ViewType {
private String id;
#Override
public int getViewType() {
return ViewTypes.ITEM;
}
}
Excuse me for some syntax errors, I've translated to Java from Kotlin to help you. Hope it helps!

Android change TextView textSize on RecyclerView adapter from Activity

i'm trying to find how can i change my RecyclerView adapter textViews from Activity, in my activity i have two widgets such as increment_text_size and decrement_text_size which they must change adapter textviews,
for achieve to that, i create simple listener on activity to manage them:
Activity:
public interface IonChangeBookContentTextSize {
void incrementTextSize();
void decrementTextSize();
}
public static void setIonChangeBookContentTextSize(IonChangeBookContentTextSize l) {
ionChangeBookContentTextSize = l;
}
and after click on widgets i use this listener on adapter
Activity:
#OnClick(R.id.decrement_text_size)
public void decrement_text_size(View view) {
if (ionChangeBookContentTextSize != null) {
ionChangeBookContentTextSize.decrementTextSize();
}
}
#OnClick(R.id.increment_text_size)
public void increment_text_size(View view) {
if (ionChangeBookContentTextSize != null) {
ionChangeBookContentTextSize.incrementTextSize();
}
}
now in adapter i'm using this listener
public class ShowBookContentsAdapter extends RecyclerView.Adapter<ShowBookContentsAdapter.ShowBookContentsViewHolder> {
private List<Contents> list;
private Context context;
private static final int NOTE = 1;
public static IonChangeBottomViewVisibility ionChangeBottomViewvisibility;
private ShowBookContentsViewHolder holder;
private View view;
public ShowBookContentsAdapter(List<Contents> items, Context mContext, IonChangeBottomViewVisibility mOnChangeBottomViewVisibility) {
list = items;
context = mContext;
ionChangeBottomViewvisibility = mOnChangeBottomViewVisibility;
}
#Override
public ShowBookContentsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layout = -1;
switch (viewType) {
case 0:
layout = R.layout.item_book_content_paragraph;
break;
case 1:
layout = R.layout.item_book_content_heading_one;
break;
}
view = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
holder = new ShowBookContentsViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(ShowBookContentsViewHolder holder, final int position) {
switch (list.get(position).getContentType()) {
case 0:
implementingHeadingParagraphView(holder, position);
break;
case 1:
implementingHeadingOneView(holder, position);
break;
}
}
private void implementingHeadingParagraphView(final ShowBookContentsViewHolder holder, final int position) {
Utils.overrideFonts(context, holder.book_content_paragraph, PersianFontType.SHABNAM);
holder.book_content_paragraph.setText(Html.fromHtml(list.get(position).getContent()));
ActivityShowBookContent.setIonChangeBookContentTextSize(new ActivityShowBookContent.IonChangeBookContentTextSize() {
#Override
public void incrementTextSize() {
holder.book_content_paragraph.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
}
#Override
public void decrementTextSize() {
holder.book_content_paragraph.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
}
});
}
#Override
public int getItemViewType(int position) {
return list.get(position).getContentType();
}
#Override
public int getItemCount() {
return list.size();
}
public int getItemPosition(int itemId) {
return itemPositions.get(itemId);
}
public class ShowBookContentsViewHolder extends RecyclerView.ViewHolder {
#Nullable
#BindView(R.id.book_content_paragraph)
TextView book_content_paragraph;
#Nullable
#BindView(R.id.book_content_heading_one)
TextView book_content_heading_one;
public ShowBookContentsViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
}
implementing this listener as :
ActivityShowBookContent.setIonChangeBookContentTextSize(new ActivityShowBookContent.IonChangeBookContentTextSize() {
#Override
public void incrementTextSize() {
holder.book_content_paragraph.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
}
#Override
public void decrementTextSize() {
holder.book_content_paragraph.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
}
});
on implementingHeadingParagraphView method work for current position, not for all rows on recyclerview adapter, how can i fix this problem?
You do not have to create a listener for this purpose. You should hold a field named textSize in your adapter. Then, set this whenever you want from your activity.
public class ShowBookContentsAdapter extends RecyclerView.Adapter<ShowBookContentsAdapter.ShowBookContentsViewHolder> {
private int textSize;
// constructor etc.
#Override
public ShowBookContentsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_book_content_paragraph, parent, false);
final ShowBookContentsViewHolder holder new ShowBookContentsViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(ShowBookContentsViewHolder holder, final int position) {
implementingHeadingParagraphView(holder, position);
}
private void implementingHeadingParagraphView(final ShowBookContentsViewHolder holder, final int position) {
Utils.overrideFonts(context, holder.book_content_paragraph, PersianFontType.SHABNAM);
holder.book_content_paragraph.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
holder.book_content_paragraph.setText(Html.fromHtml(list.get(position).getContent()));
}
public void setTextSizes(int textSize) {
this.textSize = textSize;
notifyDataSetChanged();
}
//... other adapter methods
public class ShowBookContentsViewHolder extends RecyclerView.ViewHolder {
#Nullable
#BindView(R.id.book_content_paragraph)
TextView book_content_paragraph;
#Nullable
#BindView(R.id.book_content_heading_one)
TextView book_content_heading_one;
public ShowBookContentsViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
call this from your activity
showBookContentsAdapter.setTextSizes(18);
You have to call notifydatasetchanged from you activity
1.First, save the font size on constant variable if temporary or use shared preferences if need in whole life cycle of app
Make a method in your activity to save font size
private void saveFontSize(boolean isFont){
IS_LARGE_FONT= isFont;
recyclerView.post(new Runnable(){
adapter.notifyDataSetChanged();
});
}
In your adapter class just check that value in bindholder
if(IS_LARGE_FONT)
{
//set large font
}
else{
// set small font
}

Categories

Resources