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?!
Related
I have 10 items inside RecyclerView. Each Item has a progressBar.How can i get access to the ProgressBar from MainActivity. This is my Adapter class.I am handling events using interface when i click on the Button of the Item in order to change the progress bar.
public class MyHospitalAdapter extends RecyclerView.Adapter<MyHospitalAdapter.MyViewHolder> {
private List<Hospital> mHospitalList;
private Context context;
public onImageClickListener mCallBack;
public interface onImageClickListener {
void clickOnImage(int id);
void onTextViewOfPriceSelected(int id, int amountOfProduction, int price, int time, int multiplier);
}
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class MyViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
ImageView imageView;
ProgressBar progressBar;
TextView textViewOnProgressBar;
Button price;
TextView productionAmount;
TextView nameHospital;
public MyViewHolder(#NonNull View itemView, ImageView imageView, ProgressBar progressBar, TextView textViewOnProgressBar, Button price, TextView productionAmount, TextView nameHospital) {
super(itemView);
this.imageView = imageView;
this.progressBar = progressBar;
this.textViewOnProgressBar = textViewOnProgressBar;
this.price = price;
this.productionAmount = productionAmount;
this.nameHospital = nameHospital;
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyHospitalAdapter(List<Hospital> mHospitalsList, Context context) {
this.mHospitalList = mHospitalsList;
this.context = context;
}
// Create new views (invoked by the layout manager)
#Override
public MyHospitalAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
OneBusinesBinding binding =
DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()),
R.layout.one_busines, parent, false);
MyViewHolder vh = new MyViewHolder(binding.constraintLayout, binding.imageBusiness, binding.progressBar, binding.textViewOnProgressbar, binding.price, binding.amountofProduction, binding.nameHospital);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
Hospital currentItem = mHospitalList.get(position);
int price = currentItem.getPrice();
int productionAmount = currentItem.getAmount();
int time = currentItem.getAmount();
int mMultiplier = currentItem.getMultiplier();
holder.imageView.setImageResource(AndroidImageAssets.getPictures().get(position));
holder.productionAmount.setText(context.getString(R.string.amount_of_production, productionAmount));
holder.price.setText(context.getString(AssetsUpgradeStrings.getStrings_On_Button_Buy().get(position), convertNumberToString(price)));
holder.progressBar.setProgressTintList(ColorStateList.valueOf(Color.GRAY));
holder.nameHospital.setText(AssetsUpgradeStrings.getHospitalsNames().get(position));
holder.textViewOnProgressBar.setText(context.getString(R.string.string_on_progressbar, position));
holder.imageView.setOnClickListener((v) -> {
mCallBack.clickOnImage(position);
});
This is part of MainActivity where i initialize my Adapter.
recyclerView = binding.recyclerView;
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
binding.recyclerView.setHasFixedSize(true);
mAdapter = new MyHospitalAdapter(mListHospitals,getApplicationContext());
recyclerView.setAdapter(mAdapter);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(mAdapter);
I pass the List of the data of the item.
You can pass you progressbar in interface method:
public interface onImageClickListener {
void clickOnImage(int id, ProgressBar myProgressBar);
void onTextViewOfPriceSelected(int id, int amountOfProduction, int price, int time, int multiplier);
}
And use it in callback in activity:
holder.imageView.setOnClickListener((v) -> {
mCallBack.clickOnImage(position, holder.progressBar);
});
OR
You can pass your activity instance in constructor of adapter.
...
private MainActivity context;
...
public MyHospitalAdapter(List<Hospital> mHospitalsList, MainActivity context) {
this.mHospitalList = mHospitalsList;
this.context = context;
}
Run activity method on button click and pass progress bar as method parameter:
holder.imageView.setOnClickListener((v) -> {
context.yourMethodHere(holder.progressBar)
});
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
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;
}
}