I am a new Android developer, can someone please give me an example of a custom recyclerview onclick and change image.
Please help me.
Thanks in advance..
Write this code to create Custom view
public class CustomView extends RecyclerView.Adapter<CustomView.RecyclerViewHolder> {
public static class RecyclerViewHolder extends RecyclerView.ViewHolder {
final TextView mName, mPhone;
View mCircle;
RecyclerViewHolder(View itemView) {
super(itemView);
mName = (TextView) itemView.findViewById(R.id.CONTACT_name);
mPhone = (TextView) itemView.findViewById(R.id.CONTACT_phone);
mCircle = itemView.findViewById(R.id.CONTACT_circle);
}
}
public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_layout, viewGroup, false);
return new RecyclerViewHolder(v);
}
public void onBindViewHolder(RecyclerViewHolder viewHolder, int i) {
// get the single element from the main array
final Contact contact = Contact.CONTACTS[i];
// Set the values
viewHolder.mName.setText(contact.get(Contact.Field.NAME));
viewHolder.mPhone.setText(contact.get(Contact.Field.PHONE));
// Set the color of the shape
GradientDrawable bgShape = (GradientDrawable) viewHolder.mCircle.getBackground();
bgShape.setColor(Color.parseColor(contact.get(Contact.Field.COLOR)));
}
#Override
public int getItemCount() {
return Contact.CONTACTS.length;
}
}
Related
I am getting data from server and then parsing it and storing it in a List. I am using this list for the RecyclerView's adapter. I am using Fragments.
I extended
RecyclerView.Adapter<RecyclerView.ViewHolder>
this my complete adapter class
public class GridAdapter extends RecyclerView.Adapter<GridAdapter.ViewHolder> {
private List<ProductModel> list;
ItemClickListener itemClickListener;
public GridAdapter(List<ProductModel> list, ItemClickListener itemClickListener) {
this.list = list;
this.itemClickListener = itemClickListener;
}
public void update(int position,ProductModel pm){
Log.v("update adapter",position+"");
list.set(position,pm);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final ProductModel cp = list.get(position);
holder.tvName.setText(cp.name);
holder.tvPrice.setText(cp.price);
holder.ratingBar.setRating(cp.rate);
Log.v("grid",cp.id + "=="+ cp.checked);
if(cp.checked==1){
holder.imgCheck.setVisibility(View.VISIBLE);
}else{
holder.imgCheck.setVisibility(View.GONE);
}
LayerDrawable stars = (LayerDrawable) holder.ratingBar.getProgressDrawable();
stars.getDrawable(2).setColorFilter(Color.YELLOW, PorterDuff.Mode.SRC_ATOP);
holder.lnrItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
itemClickListener.onItemClick(cp,position);
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvName, tvPrice;
ImageView imgMenu, imgCheck;
LinearLayout lnrItem;
RatingBar ratingBar;
public ViewHolder(View itemView) {
super(itemView);
lnrItem = itemView.findViewById(R.id.lnrItem);
imgMenu = itemView.findViewById(R.id.imgMenu);
imgCheck = itemView.findViewById(R.id.imgCheck);
tvName = itemView.findViewById(R.id.tvName);
ratingBar = itemView.findViewById(R.id.ratingBar);
tvPrice = itemView.findViewById(R.id.tvPrice);
}
}
}
and in fragment activity i use this code to load adapter to recyclerview
public void fillListProduct(List<ProductModel> mItems) { //method for load adapter for the first time
mAdapterGrid = new GridAdapter(mItems,this);
recGrid.setAdapter(mAdapterGrid);
}
void update(){ //method to change checked value
mAdapterGrid.update(cp.row,cp);
mAdapterGrid.notifyDataSetChanged();
}
in my custom adapter i have 3 variable lets call id, name, checked, everything work properly, in first load i set 0 as default value for checked, in my scenario user can change checked value by tap the row of recycleview.
my question is, when user tap desire row then checked will change from 0 to 1 and display it to recycelview, i already use notifydatasetchange() but not working.
Please help.
thanks
Try to remove mAdapterGrid.notifyDataSetChanged();
and modify this function in your adpater:
public void update(int position,ProductModel pm){
Log.v("update adapter",position+"");
list.set(position,pm);
notifyItemChanged(position);
}
I have a RecyclerView defined in my android project. The Adapter for the RecyclerView is as follows
public class CustomAdapter1 extends RecyclerView.Adapter<CustomAdapter1.MyViewHolder> {
private Fragment1 myFrag;
private ArrayList<DataModel1> dataSet;
DBHandler db;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView butAccept,butReject;
TextView nick,stat,tit,cat,desc,dt;
public CardView cardView;
public MyViewHolder(View itemView) {
super(itemView);
this.nick = (TextView) itemView.findViewById(R.id.nick);
this.stat = (TextView) itemView.findViewById(R.id.stat);
this.tit = (TextView) itemView.findViewById(R.id.tit);
this.cat = (TextView) itemView.findViewById(R.id.cat);
this.desc = (TextView) itemView.findViewById(R.id.desc);
this.dt = (TextView) itemView.findViewById(R.id.dt);
this.butAccept = (TextView)itemView.findViewById(R.id.accept_textview);
cardView = (CardView) itemView.findViewById(R.id.card_view);
cardView.setOnClickListener(this);
butAccept.setOnClickListener(this);
db = new DBHandler(itemView.getContext());
}
#Override
public void onClick(View v) {
if( v.getId() == butAccept.getId()){
String x = String.valueOf(dataSet.get(getAdapterPosition()).getMeetId());
myFrag.showToast(x);
}
}
}
public CustomAdapter1(ArrayList<DataModel1> data,Fragment1 frag) {
this.dataSet = data;
myFrag = frag;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardfrag1, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder,final int listPosition) {
TextView nick = holder.nick;
TextView stat = holder.stat;
TextView tit = holder.tit;
TextView cat = holder.cat;
TextView desc = holder.desc;
TextView dt= holder.dt;
nick.setText(dataSet.get(listPosition).getNick());
stat.setText(dataSet.get(listPosition).getStat());
tit.setText(dataSet.get(listPosition).getTit());
cat.setText(dataSet.get(listPosition).getCat());
desc.setText(dataSet.get(listPosition).getDesc());
dt.setText(dataSet.get(listPosition).getDt());
}
#Override
public int getItemCount() {
return dataSet.size();
}
}
The final TextView butAccept has dynamic values.I have an internal DB that has the column Status. When the value of the Status is 1 I need to change the text that is being displayed in the TextView butAccept.
How should I do this? Should I write a function in my CustomAdapter, or in the fragment in which I am using the adapter?
In my Fragment I have a function :
private void checkTheAcceptStatus(int x){
int status = db.getMeetingStatus(x);
Toast.makeText(getActivity(),String.valueOf(status),Toast.LENGTH_SHORT).show();
if(status == 1){
}
}
This function is being called everytime a new item is added to the adapter. The internal DB is being queried correctly and if the value of Status is being returned. If the value is 1 what should I do?
I saw this question, but this is unclear and I was unable to come to any conclusion from this.
If I understood correctly every row in your list has this accept button. So in your onBindViewHolder() you cant set the buttons text depending on the state of your status variable. When you detect changes in your db you can use the various notify methods provided depending on your needs: notifyItemChanged(...), notifyItemRangeChanged(...), notifyItemAdded(...), notifyItemRemoved(...) etc. Your onBindViewHolder should look something like this:
#Override
public void onBindViewHolder(final ViewHolder vh, int position) {
if(dataSet.get(position).getStatus() == 1){
vh.butAccept.setText("Your status 1 case text here");
} else {
vh.butAccept.setText("Your status not 1 case text here");
}
}
Also you can just use notifyDataSetChanged() if you want to refresh the whole list, but the methods above are more efficient.
I'm trying to set an onclick method in my RecyclerView. It worked on another project but not here. I searched on the web but can't figure it out. Not even the toast is popping up. Can someone, please, explain to me where I am making a mistake?
Here's my code:
private Context mContext;
private MenuImages[] mMenuImages;
public MenuAdapter(Context context, MenuImages[] menuImages){
mContext = context;
mMenuImages = menuImages;
}
#Override
public MenuViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.menu_list_item, parent, false);
MenuViewHolder viewHolder = new MenuViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(MenuViewHolder holder, int position) {
holder.bindMenu(mMenuImages[position]);
}
#Override
public int getItemCount() {
return mMenuImages.length;
}
public class MenuViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener{
public ImageView mImageView;
public TextView mTextView;
public MenuViewHolder(View itemView) {
super(itemView);
mImageView = (ImageView) itemView.findViewById(R.id.itemImageView);
mTextView = (TextView) itemView.findViewById(R.id.textView2);
itemView.setOnClickListener(this);
}
public void bindMenu(MenuImages menuImage){
mImageView.setImageBitmap(menuImage.getImageMenu());
mTextView.setText(menuImage.getTitleImageMenu());
}
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), getLayoutPosition(), Toast.LENGTH_LONG).show();
}
}
in my case I was using RecyclerView in InterceptorCardView of other class wich was preventing onClickListener of recyclerview,
when I changed it with CardView and it worked perfectly
Note: I removed clickable = "false" ,focusable = "false".
it may be late but in your layout xml file you should add attribute clickable = "false" and also focusable = "false" to the children view ,textview and imageview in your case
Imagine a CardView with a button and text field. When I press on a button, text should change in the textfield. Code for my recyclerView is given below, where I am setting the text and a listener for a button:
#Override
public void onBindViewHolder(CategoriesDetailedViewHolder holder, int position) {
final CategoryDetailedModel model = categoriesDetailedModels.get(position);
holder.description.setText(model.getQuestion());
holder.btnPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
holder.description.setText("some text");
}
});
}
The main problem is with the string:
holder.description.setText("some text");
It cannot be accessed from an inner class.
Is anyone have any idea how to change text in card view from itself.
Update 1
public class CategoriesDetailedViewHolder extends RecyclerView.ViewHolder{
CardView cv;
TextView description;
TextView positiveCounter;
TextView negativeCounter;
TextView btnPlus;
View negativeCounterWrapper;
View positiveCounterWrapper;
CategoriesDetailedViewHolder(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
description = (TextView)itemView.findViewById(R.id.main_text);
positiveCounter = (TextView)itemView.findViewById(R.id.tv_positive_count_in_circle);
negativeCounter = (TextView)itemView.findViewById(R.id.tv_negative_count_in_circle);
btnPlus = (TextView)itemView.findViewById(R.id.plus_button);
positiveCounterWrapper = itemView.findViewById(R.id.positive_count_wrapper);
negativeCounterWrapper = itemView.findViewById(R.id.negative_count_wrapper);
cv.setPreventCornerOverlap(false);
}
}
#Override
public CategoriesDetailedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.categories_detailed_list_row_view, parent, false);
CategoriesDetailedViewHolder pvh = new CategoriesDetailedViewHolder(v);
context = parent.getContext();
return pvh;
}
Instead of,
TextView description;
Make it,
public TextView description;
EDIT:
Change the following,
#Override
public void onBindViewHolder(CategoriesDetailedViewHolder holder, int position) { ... }
to,
#Override
public void onBindViewHolder( final CategoriesDetailedViewHolder holder, int position) { .... }
I use this code and it works fine, you just need to use onBind method.
This is one example, I use this in my project and you can just change it to suit your needs:
public void onBindViewHolder(final TipsViewHolder TipsViewHolder, final int i) {
TipsViewHolder.cardText.setText("Old text");
TipsViewHolder.txtBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TipsViewHolder.cardText.setText("New Text");
}
});
}
I want to update a progressbar in a recyclerview item.
Now I have no idea, how to get the progressbar within an item and update it from another class, which isn't connected in anyway with this adapter.
Here's my code:
public class TransmissionAdapter extends RecyclerView.Adapter<TransmissionAdapter.ViewHolderUI> {
public static class ViewHolderUI extends RecyclerView.ViewHolder{
ImageView fileTypeImage;
TextView fileName;
TextView progressDescription;
TextView timeAgoTrans;
ProgressBar uploadProgess;
public ViewHolderUI(View itemView) {
super(itemView);
fileTypeImage = (ImageView) itemView.findViewById(R.id.file_type_image);
fileName = (TextView) itemView.findViewById(R.id.file_name);
progressDescription = (TextView) itemView.findViewById(R.id.progress_description);
timeAgoTrans = (TextView) itemView.findViewById(R.id.time_ago_trans);
uploadProgess = (ProgressBar) itemView.findViewById(R.id.progress_bar_transmission);
}
}
#Override
public ViewHolderUI onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_view, null);
return new ViewHolderUI(itemView);
}
#Override
public void onBindViewHolder(ViewHolderUI holder, int position) {
holder.fileName.setText(TransmissionsView.itemTexte.get(position));
}
#Override
public int getItemCount() {
return TransmissionsView.itemTexte.size();
}
}
I tried to put the progress in an arraylist and update the progress in the recyclerlist using notifyDataSetChanged and set the current progress in "onBindViewHolder" method. But if the progressbar is to fast the UI Thread skipped frames, so is this the right way?!