I have a RecycleView Which shows a bunch of list in which one item is selected by showing its background color blue, now I want user to select any item from list and its color get changed to blue how to implement this inside RecyclerView.Adapter or any other logic
public class ToggleAdapter extends RecyclerView.Adapter<ToggleAdapter.ToggleViewHolder>{
private ArrayList<ToggleParams> dataList=new ArrayList<>();
private Context context;
private static int selection;
public ToggleAdapter(ArrayList<ToggleParams> dataList, Context context,int selection) {
setData(dataList,context,selection);
}
#Override
public ToggleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_row,parent,false);
ToggleViewHolder toggleViewHolder=new ToggleViewHolder(v);
return toggleViewHolder;
}
#Override
public void onBindViewHolder(ToggleViewHolder holder, int position) {
if(position==selection){
holder.selected_item.setBackgroundColor(context.getResources().getColor(R.color.blue));
holder.text_view.setTextColor(context.getResources().getColor(android.R.color.white));
}
holder.image_view.setImageDrawable(context.getResources().getDrawable(dataList.get(position).getIMAGE_ID()));
holder.text_view.setText(dataList.get(position).getTOGGLE_TEXT());
}
private void setData(ArrayList<ToggleParams> dataList, Context context,int selection) {
this.dataList = dataList;
this.context = context;
this.selection = selection;
}
#Override
public int getItemCount() {
return dataList.size();
}
public static class ToggleViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public LinearLayout selected_item;
public ImageView image_view;
public TextView text_view;
public ToggleViewHolder(View itemView) {
super(itemView);
selected_item= (LinearLayout) itemView.findViewById(R.id.selected_item);
selected_item.setOnClickListener(this);
image_view= (ImageView) itemView.findViewById(R.id.imageView);
text_view= (TextView) itemView.findViewById(R.id.textView);
}
public void onClick(View v) {
selection=getPosition();
//After getting this position I want that this item list in recyclerview to change its background color but how to call notifyDataSetChange() here something equivalent to that
}
}
}
You can use the setOnCLickListener in onBindViewHolder and can call notifyDatasetChanged there or a better way is to define an interface which gets called on when an itemView is clicked and to instantiate it in the adapter. For example see the following answer
Why doesn't RecyclerView have onItemClickListener()? And how RecyclerView is different from Listview?
Related
I'm a bit new to Android development.
I was wondering how I can save state of checkboxes in a RecyclerView. I know there are existing solutions for this, but I have a list of items in another RecyclerView that uses the same set of checkboxes. When you click an item, it should show all checkboxes and check those previously checked checkboxes for that item.
I have seen posts using SharedPreferences to save the state but I have different checkboxes states for different item click in another RecyclerView and I do not know how to save these different states.
This is the Adapter class for the list of checkboxes named CurrentAddonAdapter.java:
public class CurrentAddonAdapter extends RecyclerView.Adapter<CurrentAddonAdapter.ViewHolder17> {
private Context context;
private ArrayList items3,price3;
private List<AddonList> addonlist1;
private OnItemClickListener17 mOnItemClickListener17;
CurrentAddonAdapter(Context context, ArrayList items3, ArrayList price3,List addonlist1,OnItemClickListener17 onItemClickListener17){
this.context = context;
this.items3 = items3;
this.price3 = price3;
this.addonlist1 = addonlist1;
this.mOnItemClickListener17 = onItemClickListener17;
}
#NonNull
#Override
public ViewHolder17 onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.addoncard,parent,false);
return new ViewHolder17(view,mOnItemClickListener17);
}
private SparseBooleanArray selecteditems = new SparseBooleanArray();
#Override
public void onBindViewHolder(#NonNull final CurrentAddonAdapter.ViewHolder17 holder, int position) {
holder.item1.setText(String.valueOf(items3.get(position)));
holder.price1.setText(String.valueOf(price3.get(position)));
final AddonList currentaddon = addonlist1.get(position);
holder.item1.setChecked(selecteditems.get(position));
holder.item1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.item1.isChecked()){
holder.item1.setChecked(true);
mOnItemClickListener17.onItemCheck(currentaddon);
}
else{
holder.item1.setChecked(false);
mOnItemClickListener17.onItemUncheck(currentaddon);
}
}
});
}
#Override
public int getItemCount() {
return items3.size();
}
public class ViewHolder17 extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView price1;
CheckBox item1;
OnItemClickListener17 onItemClickListener17;
public ViewHolder17(#NonNull View itemView, final OnItemClickListener17 onItemClickListener17) {
super(itemView);
item1 = itemView.findViewById(R.id.addoncheck);
price1 = itemView.findViewById(R.id.priceadd);
this.onItemClickListener17 = onItemClickListener17;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onItemClickListener17.onItemClick7(getAdapterPosition());
}
}
public interface OnItemClickListener17{
void onItemClick7(int position);
void onItemCheck(AddonList addonList);
void onItemUncheck(AddonList addonList);
}
}
This is the code for the item click. It shows a dialog box with the list of all checkboxes with CardView elements array named items3 and price3
Cursor viewaddon = db.viewalladdon();
while(viewaddon.moveToNext()){
items3.add(viewaddon.getString(2));
price3.add(viewaddon.getString(3));
addonlist1.add(new AddonList(viewaddon.getString(2)));
}
addrecycler.setHasFixedSize(true);
currentAddonAdapter = new CurrentAddonAdapter(getActivity(),items3,price3,addonlist1,this);
addrecycler.setAdapter(currentAddonAdapter);
addrecycler.setLayoutManager(new LinearLayoutManager(getActivity()));
Please, help. I've been trying to find a solution for weeks and I still can't find one. I just really need this for school.
As I'm new to android, I'm struggling to highlight Recyclerview clicked or current item. I have tried some workarounds but nothing helps. Basically I want to highlight selected item even after it is coming back from respective Fragment. Please check my code and help me to get done. Thanks.
public class ContentaAdapter extends RecyclerView.Adapter<ContentaAdapter.MyViewHolder> {
Context context;
ArrayList<String> ItemTitle;
ArrayList<String> ItemSource;
public ContentaAdapter(Context context, ArrayList<String> ItemTitle, ArrayList<String> ItemSource) {
this.context = context;
this.ItemTitle = ItemTitle;
this.ItemSource = ItemSource;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_items_layout, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.ItemTitle.setText(ItemTitle.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Fragment contentdisplay = new ViewContentFragment();
Bundle bundle=new Bundle();
bundle.putStringArrayList("ItemTitle",ItemTitle);
bundle.putStringArrayList("ItemSource",ItemSource);
bundle.putInt("position",position);
bundle.putInt("ItemCounts",ItemTitle.size());
contentdisplay.setArguments(bundle);
((MainActivity)context).replaceFragment(contentdisplay);
}
});
}
#Override
public int getItemCount() {
return ItemTitle.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView ItemTitle;
public MyViewHolder(View itemView) {
super(itemView);
ItemTitle = (TextView) itemView.findViewById(R.id.item_title);
}
}
}
you need to to add isSelected state in to your list item data model and change it onClick.
And when you know state you can change background in ViewHolder
if (isSelected) {
// set selected background here
} else {
// set not selected background here
}
And instead of keeping two lists in adapter you should create one with model ArrayList<DataModel> similar to this:
class DataModel {
String ItemTitle;
String ItemSource;
Boolean isSelected;
}
also you shouldn't pass both list to other fragment, instead take only what you need, for example yourList.get(position);
I have some vertical EditText in a RecyclerView.
when I touch an EditText at second half vertical screen. Cursor moving on previous EditText and focus on it.
I searched about this and could not find any solution .
please help..
Edit:
i'm clicking an edit text that's in position 10 of recycler view.
but android focuses on edit text that's in position 9
Edit 2 :
my adapter class:
public class inputsAdapter extends RecyclerView.Adapter<holder> implements View.OnFocusChangeListener {
public List<String> paramList,resultList;
Context mContext;
boolean doneParam,doneResult;
public View focusedView;
public ArrayAdapter<String> adapter ;
public inputsAdapter(List<String> paramList, List<String> resultList, Context mContext) {
this.paramList = paramList;
this.resultList = resultList;
this.mContext = mContext;
this.doneParam=false;
this.doneResult=false;
this.focusedView=null;
this.adapter = new ArrayAdapter<String>
(mContext,android.R.layout.simple_list_item_1,mContext.getResources().getStringArray(R.array.correct_params) );
}
#Override
public holder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.parameter_row,parent,false);
return new holder(view);
}
#Override
public void onBindViewHolder(holder holder, final int position) {
if(position<paramList.size()){
holder.paramConst.setVisibility(View.VISIBLE);
holder.paramConst.setTag(position);
holder.paramEt.setAdapter(adapter);
holder.paramEt.setText(paramList.get(position));
holder.addParam.setVisibility(View.GONE);
doneParam=false;
holder.paramEt.setOnFocusChangeListener(this);
}else if(position==paramList.size()){
holder.paramConst.setVisibility(View.INVISIBLE);
holder.addParam.setBackground(mContext.getResources().getDrawable(R.drawable.ic_add_box_black_24dp));
holder.addParam.setVisibility(View.VISIBLE);
}else{
holder.paramConst.setVisibility(View.INVISIBLE);
holder.addParam.setVisibility(View.GONE);
}
if(position<resultList.size()){
holder.resultConst.setVisibility(View.VISIBLE);
holder.resultConst.setTag(position);
holder.resultEt.setText(resultList.get(position));
holder.addResult.setVisibility(View.GONE);
doneResult=false;
}else if(position==resultList.size()){
holder.resultConst.setVisibility(View.INVISIBLE);
holder.addResult.setBackground(mContext.getResources().getDrawable(R.drawable.ic_add_box_black_24dp));
holder.addResult.setVisibility(View.VISIBLE);
}else{
holder.resultConst.setVisibility(View.INVISIBLE);
holder.addResult.setVisibility(View.GONE);
}
}
#Override
public int getItemCount() {
if(paramList.size()>resultList.size())
{return paramList.size()+1;}
else {return resultList.size()+1; }
}
#Override
public void onFocusChange(View view, boolean b) {
if(b){
this.focusedView=view;
}else{
ConstraintLayout constraintLayout= (ConstraintLayout) view.getParent();
int index= (int) constraintLayout.getTag();
EditText et= (EditText) view;
paramList.set(index,et.getText().toString());
}
}
}
class holder extends RecyclerView.ViewHolder {
AutoCompleteTextView paramEt,resultEt;
Button addParam,addResult;
ConstraintLayout paramConst,resultConst;
public holder(View itemView) {
super(itemView);
paramEt=itemView.findViewById(R.id.paramEt);
resultEt=itemView.findViewById(R.id.resultEt);
paramConst=itemView.findViewById(R.id.paramConstraint);
resultConst=itemView.findViewById(R.id.resultConstraint);
addParam=itemView.findViewById(R.id.paramAddAfterBtn);
addResult=itemView.findViewById(R.id.resultAddAfterBtn);
}
}
Your getItemCount method is returning the wrong value. You don´t need to add a +1 to it. So change your method to the following code and see if it´s solving your problem:
#Override
public int getItemCount() {
if(paramList.size()>resultList.size())
{return paramList.size();}
else {return resultList.size(); }
}
I have a setOnClick listener inside my onBindViewHolder
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
((ViewHolder) holder).txtType.setText(object.text);
((ViewHolder) holder).checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, ""+position, Toast.LENGTH_SHORT).show();
//???.scrolltoPosition(position+1);
}
});
on click, I would be scrolling the viewport to the next recycler view item. I've done this inside my MainActivity java by recyclerView.scrollToPosition(position);. But inside Adapter Class on onBindViewHolder, I have no idea how to call my recyclerView on the Main Java Class.
How should I do this?
edit:
For simplification purposes, I revised this previous code, because I have used a multiview adapter for my recycler. Here is the multiview adapter:
public class MultiViewTypeAdapter extends RecyclerView.Adapter {
private ArrayList<InstructionModel>dataSet;
Context mContext;
int total_types;
private LinearLayoutManager manager;
public MultiViewTypeAdapter(LinearLayoutManager manager)
{
this.manager=manager;
}
public static class SimpleTextViewHolder extends RecyclerView.ViewHolder {
TextView txtType;
CardView cardView;
CheckBox checkBox;
public SimpleTextViewHolder(View itemView) {
super(itemView);
this.txtType = (TextView) itemView.findViewById(R.id.type);
this.cardView = (CardView) itemView.findViewById(R.id.card_view);
this.checkBox = (CheckBox) itemView.findViewById(R.id.checkBox);
}
}
public static class TimeTextViewHolder extends RecyclerView.ViewHolder {
TextView txtType;
CardView cardView;
CheckBox checkBox;
public TimeTextViewHolder(View itemView) {
super(itemView);
this.txtType = (TextView) itemView.findViewById(R.id.type);
this.cardView = (CardView) itemView.findViewById(R.id.card_view);
this.checkBox = (CheckBox) itemView.findViewById(R.id.checkBox);
}
}
public MultiViewTypeAdapter(ArrayList<InstructionModel> data, Context context) {
this.dataSet = data;
this.mContext = context;
total_types = dataSet.size();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case InstructionModel.SIMPLE_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.simple, parent, false);
return new SimpleTextViewHolder(view);
case InstructionModel.TIME_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.time, parent, false);
return new TimeTextViewHolder(view);
}
return null;
}
#Override
public int getItemViewType(int position) {
switch (dataSet.get(position).type) {
case 0:
return InstructionModel.SIMPLE_TYPE;
case 1:
return InstructionModel.TIME_TYPE;
default: return -1;
}
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int listPosition) {
InstructionModel object = dataSet.get(listPosition);
if (object != null) {
switch (object.type) {
case InstructionModel.SIMPLE_TYPE:
((SimpleTextViewHolder) holder).txtType.setText(object.text);
break;
case InstructionModel.TIME_TYPE:
((TimeTextViewHolder) holder).txtType.setText(object.text);
break;
}
}
}
#Override
public int getItemCount() {
return dataSet.size();
}
P.S.
If you see some random useless stuff, I was trying something.
Pass the LayoutManger with constuctor
class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
private LinearLayoutManager manager;
public Adapter(LinearLayoutManager manager)
{
this.manager=manager;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
((ViewHolder) holder).txtType.setText(object.text);
((ViewHolder) holder).checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, ""+position, Toast.LENGTH_SHORT).show();
manager.scrollToPosition(position+1);
}
});
}
I think you should define a interface to notify your parent RecyclerView to do scroll operation, the RecyclerView into ViewHodler inside operation, resulting in the coupling
You can pass a listener object in the constructor which implements by Fragment OR Activity.
/**
* item click interface of adapter
*/
public interface MultiViewTypeAdapterListener {
void onScroll(int position)
}
This interface implements by Fragment OR Activity
/**
* On Scroll Implement Method from adapter listener.
*
* #param position
*/
#Override
public void onScroll(int position) {
// Here you can call that method
recyclerview.scrolltoPosition(position)
}
Then you pass this listener in the constructor of the adapter.
private void buildRecyclerView() {
multiViewTypeAdapter = new MultiViewTypeAdapter(this);
recyclerView.setAdapter(multiViewTypeAdapter);
}
In the constructor, you can assign like this
private MultiViewTypeAdapterListener mMultiViewTypeAdapterListener;
public OfferAdapter(MultiViewTypeAdapterListener mMultiViewTypeAdapterListener) {
this.mMultiViewTypeAdapterListener = mMultiViewTypeAdapterListener
}
}
Now you can use this listener by setting click listener on anyViwe like this
((ViewHolder) holder).checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, ""+position, Toast.LENGTH_SHORT).show();
//???.scrolltoPosition(position+1);
mMultiViewTypeAdapterListener.onScroll(position+1);
}
});
It returns to call the method of onItemClick which implements this method.
private int getScrollRange() {
int scrollRange = 0;
if (parent.getChildCount() > 0) {
View child = parent.getChildAt(0);
scrollRange = Math.max(0,
child.getHeight() - (parent.getHeight()));
}
return scrollRange;
}
ScrollView parent=findViewById(R.id.scroll_Recipe_Detail);
parent.scrollTo(0,getScrollRange());
if you want to scroll on new items added, you must override "onItemsAdded".
Here is how I did it:
recyclerView.apply {
setHasFixedSize(true)
layoutManager = MyLinearLayoutManager(this#MainActivity)
...
}
private class MyLinearLayoutManager(private val context: Context) :
LinearLayoutManager(context) {
// Force new items appear at the top
override fun onItemsAdded(recyclerView: RecyclerView, positionStart: Int, itemCount: Int) {
super.onItemsAdded(recyclerView, positionStart, itemCount)
scrollToPosition(findLastVisibleItemPosition())
}
}
Android Recycler View OnClick event is not working in the code. I can see the Recycler view grid but when I am clicking on one item nothing is happening.
Here is my code:
public class StaggeredGridAdapter extends RecyclerView.Adapter<StaggeredGridAdapter.StaggeredGridView> {
private Context context;
private List<Warehouse> warehouses = new ArrayList<Warehouse>();
int size;
public StaggeredGridAdapter(Context context) {
this.context = context;
}
public void addItems(List<Warehouse> response) {
size = response.size();
warehouses = response;
}
#Override
public StaggeredGridView onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false);
StaggeredGridView staggeredGridView = new StaggeredGridView(layoutView);
return staggeredGridView;
}
#Override
public void onBindViewHolder(StaggeredGridView holder, int position) {
holder.textView.setText(warehouses.get(position).getFace());
}
#Override
public int getItemCount() {
return size;
}
class StaggeredGridView extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView textView;
public StaggeredGridView(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.img_name);
}
#Override
public void onClick(View v) {
Toast.makeText(context, "clicked", Toast.LENGTH_SHORT).show();
}
}
}
I inherited inner class i.e. StaggeredGridView with Views.OnClickListner and debug point is not reaching to StaggeredGridView.OnClick method. There is no exception in ADB logs.
What I am doing wrong here?
You need to do this simple thing and it will start working with you
itemView.setOnClickListener(this)
//add this
public StaggeredGridView(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.img_name);
staggeredGridView.setOnClickListener(this)
}