How to set a progress for many progress-bars in RecyclerView - java

I am using a RecyclerView to view many Progress Bars as a slide show and an adapter.
This my adapter class
public class RecAdapter extends RecyclerView.Adapter<RecAdapter.ViewHolder> {
private static final String TAG = "RecAdapter";
private ArrayList progressbars = new ArrayList<>();
private Context pcontex;
public RecAdapter(Context pcontex ,ArrayList progressbars) {
this.progressbars = progressbars;
this.pcontex = pcontex;
}
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.progress,viewGroup,false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int i) {
Log.d(TAG, "onBindViewHolder: called");
}
#Override
public int getItemCount() {
return progressbars.size() ;
}
public class ViewHolder extends RecyclerView.ViewHolder {
ProgressBar b ;
ConstraintLayout parent;
public ViewHolder(#NonNull View itemView) {
super(itemView);
b = itemView.findViewById(R.id.progressBar);
parent= itemView.findViewById(R.id.parent);
}
}
}
My MainActivity code-
Prog = new ArrayList<>(); b2 = findViewById(R.id.progressBar) ;
b = findViewById(R.id.progressBar);
probitmap();
private void probitmap(){
Log.d(TAG, "probitmap: preparing bit maps");
Prog.add(b);
Prog.add(b2);
Recycle();// this method is out of on create
}
private void Recycle(){
Log.d(TAG, "Recycle: init recycleview");
recyclerView =findViewById(R.id.Rec);
RecAdapter Adapter = new RecAdapter(this,Prog);
recyclerView.setAdapter(Adapter);
LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(layoutManager);
}
The code is working perfectly but I need to retrieve every progress bar that is in the recycle view and set progress for each one.
I tried multiple ways but it doesn't work. Here is what I tried-
for (int i = 0; i < recyclerView.getChildCount(); i++) {
RecAdapter.ViewHolder holder = (RecAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(i);
holder.b.setProgress(50);
}

Use OnBindViewHolder to manage each "row" generated by the recycler.
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int i) {
viewHolder.b.setProgress(progressbar.get(i)); //i is the position of the recycler
viewHolder.b.setListener....
}

Related

App crash while implementing Recycle Adapter

I'm creating an app to simply store the records of a tractions and able to see the record.
In IteamListActivity I want to see my records of tractions.
I want to list all the data item in recycle view.
When I click 'View' button in activity_home xml, app crashes.
GitHub Link of the project is Here
Code is
Adapter
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.viewHolder>{
ArrayList<DataModel> list;
Context context;
public DataAdapter(ArrayList<DataModel> list, Context context) {
this.list = list;
this.context = context;
}
#NonNull
#Override
public viewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view =
LayoutInflater.from(context).inflate(R.layout.data_list_design,parent,false);
return new viewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull viewHolder holder, int position) {
DataModel model = list.get(position);
holder.sn.setText(model.getSn());
holder.date.setText(model.getDate());
holder.name.setText(model.getName());
holder.weight.setText(model.getWeight());
holder.rate.setText(model.getRate());
holder.total.setText(model.getTotal());
}
#Override
public int getItemCount() {
return list.size();
}
public class viewHolder extends RecyclerView.ViewHolder {
TextView sn,date,name,weight,rate,total;
public viewHolder(#NonNull View itemView) {
super(itemView);
sn = itemView.findViewById(R.id.snTitle);
date = itemView.findViewById(R.id.dateTitle);
name = itemView.findViewById(R.id.nameTitle);
weight = itemView.findViewById(R.id.weightTitle);
rate = itemView.findViewById(R.id.rateTitle);
total = itemView.findViewById(R.id.totalTitle);
}
}
}
HomeActivity
binding.listview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(HomeActivity.this,ItemListActivity.class );
startActivity(intent);
}
});
ItemListActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityItemListBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
ArrayList<DataModel> list = new ArrayList<>();
list.add(new DataModel(1,"2021-07-29","Potato", 76,50,100));
list.add(new DataModel(2,"2021-07-30","Potato", 106,60,100));
list.add(new DataModel(3,"2021-08-02","Potato", 83,80,100));
list.add(new DataModel(4,"2021-08-03","Potato", 67,90,100));
list.add(new DataModel(5,"2021-08-05","Potato", 70,70,100));
DataAdapter adapter = new DataAdapter(list,this);
LinearLayoutManager linearLayoutManager = new
LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
binding.datalistRv.setLayoutManager(linearLayoutManager);
binding.datalistRv.setNestedScrollingEnabled(false);
binding.datalistRv.setAdapter(adapter);
}
Solution is
#Override
public void onBindViewHolder(#NonNull viewHolder holder, int position) {
DataModel model = list.get(position);
holder.sn.setText(model.getSn().toString());
holder.date.setText(model.getDate());
holder.name.setText(model.getName());
holder.weight.setText(model.getWeight().toString());
holder.rate.setText(model.getRate().toString());
holder.total.setText(model.getTotal().toString());
}
Reason of crush is model.getSn(), model.getWeight(), model.getRate(), model.getTotal() return Integer and textView.setText() calls public final void setText(#StringRes int resid) which tries to find string by Integers which you provided from your model.

How to get the item position in a ListView and GridView outside the adapter?

I'm trying to get a View position through his view hierarchy.
When I have a RecyclerView, for get the current view position I do:
if(view.getParent() instanceof RecyclerView){
RecyclerView rv = (RecyclerView)view.getParent();
if(rv.getLayoutManager()!=null) {
position = rv.getLayoutManager().getPosition(view);
}
}
But when a ListView or GridView appears, I'm not able to get a Layout Manager to get the position of the view. The idea is to make it in a generic way, without knowing the Custom Adapter the view has.
I have tried to get the position through the ListView and GridView adapter but I dont see any method that do that.
Someone can help me?
Thank you a lot!
Create interface for get position for outside adapter class
here is adapter code:
public class ReportMediaAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<File> reportMediaList = new ArrayList<>();
private Context context;
private int selectedPos = -1;
private OnRemoveImage onRemoveImage;
public ReportMediaAdapter(Context context, ArrayList<File> reportMediaList, OnRemoveImage onRemoveImage) {
this.reportMediaList = reportMediaList;
this.onRemoveImage = onRemoveImage;
this.context = context;
}
**public interface OnRemoveImage {
void onRemove(int pos);
}**
public class MyViewHolder extends RecyclerView.ViewHolder {
private ImageView iv_image, iv_remove;
public MyViewHolder(View itemView) {
super(itemView);
iv_image = itemView.findViewById(R.id.iv_image);
iv_remove = itemView.findViewById(R.id.iv_remove);
}
}
#Override
public int getItemCount() {
return reportMediaList.size()-1;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_media, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
try {
MyViewHolder menuItemHolder = (MyViewHolder) holder;
CommonMethods.loadImage(context, reportMediaList.get(position), menuItemHolder.iv_image);
menuItemHolder.iv_remove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
**onRemoveImage.onRemove(position);**
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here is activity code:
#Override
public void onRemove(int pos) {
// use adapter position
}
I have found a solution:
if(view.getParent() instanceof ViewGroup) {
position = ((ViewGroup)view.getParent()).indexOfChild(view);
}

How to add a recyclerview item dynamically when click a button in another activity?

I have a recyclerview in ShoppingCartActivity and a button in ProductDetailActivity. I want to send some data to ShoppingCartActivity when a button clicked in ProductDetailActivity and display them in recyclerview item that creates dynamically in ShoppingCartActivity.
I added addData method to recyclerview Adapter but it doesn't work and app crashes.
shop_btn = findViewById(R.id.add_to_shopping_cart);
shop_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent addToCart = new Intent(ProductDetailActivity.this, ShoppingCartActivity.class);
startActivity(addToCart);
}
});
//HERE IS MY RECYCLERVIEW ADAPTER
public class RecyclerViewAdapter_ShoppingCart extends RecyclerView.Adapter<RecyclerViewAdapter_ShoppingCart.MyViewHolder> {
private Context context;
List<CartItems> cartItemsList;
public RecyclerViewAdapter_ShoppingCart(Context context, List<CartItems> cartItemsList) {
this.context = context;
this.cartItemsList = cartItemsList;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view;
LayoutInflater layoutInflater = LayoutInflater.from(context);
view = layoutInflater.inflate(R.layout.card_cart, parent, false);
return new MyViewHolder(view);
}
#NonNull
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, final int position) {
holder.cart_title.setText(cartItemsList.get(position).getTitle());
holder.cart_price.setText(cartItemsList.get(position).getPrice());
Picasso.get().load(cartItemsList.get(position).getImageUrl()).into(holder.cart_img);
}
#Override
public int getItemCount() {
return cartItemsList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView cart_title, cart_price;
ImageView cart_img;
public MyViewHolder(View itemView) {
super(itemView);
cart_title = itemView.findViewById(R.id.cart_title);
cart_price = itemView.findViewById(R.id.cart_price);
//cart_delete = itemView.findViewById(R.id.cart_delete);
cart_img = itemView.findViewById(R.id.cart_image);
}
}
public void addItem(List<CartItems> cartItems) {
CartItems newValue = new CartItems();
newValue.setTitle("123");
newValue.setPrice("123");
newValue.setImageUrl("");
cartItems.add(newValue);
notifyDataSetChanged();
}
}
My goal is adding recyclerview items dynamically to ShoppingCartActivity when a button clicked in ProductDetailActivity but app crashes.

RecyclerView problem to load more than n items

I've implementend a RecyclerView as follow
The Adapter with the Holder
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.indovinelloelement,parent,false);
MyHolder holder = new MyHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull MyHolder holder, int position) {
holder.category.setText(data.get(position).getCategory());
holder.difficulty.setText(""+data.get(position).getDifficulty());
holder.title.setText(data.get(position).getTitle());
holder.score.setText(""+data.get(position).getScore());
if(data.get(position).isLocked())
holder.setLocked();
else
holder.setUnlocked();
}
public DataGestour.Indovinello getIndovinello(int pos){
return data.get(pos);
}
#Override
public int getItemCount() {
return data.size();
}
public class MyHolder extends RecyclerView.ViewHolder {
public TextView category,score,difficulty,title;
private ImageView lock_state;
public MyHolder(View itemView) {
super(itemView);
category = (TextView)itemView.findViewById(R.id.categoria);
score = (TextView)itemView.findViewById(R.id.punteggio);
difficulty = (TextView) itemView.findViewById(R.id.difficolta);
title = (TextView)itemView.findViewById(R.id.titolo);
lock_state = (ImageView) itemView.findViewById(R.id.lock_state);
}
public void setLocked(){
lock_state.setImageResource(R.drawable.ic_lock_outline_black_24dp);
}
public void setUnlocked(){
lock_state.setImageResource(R.drawable.ic_lock_open_black_24dp);
}
}
ArrayList<DataGestour.Indovinello> data;
Context context;
public MyAdapter(Context context, ArrayList<DataGestour.Indovinello> list){
this.context = context;
this.data = list;
}
}
and the RecyclerView:
rc = (RecyclerView)root_view.findViewById(R.id.lista_domande);
rc.setHasFixedSize(true);
LinearLayoutManager ly = new LinearLayoutManager(getContext());
ly.setOrientation(LinearLayoutManager.VERTICAL);
rc.setLayoutManager(ly);
try{
gestour = new DataGestour(getContext());
}catch (IllegalStateException e){
Log.e("DataManager",e.getMessage());
};
adapter = new MyAdapter(getContext(),gestour.getAllDatas());
rc.setAdapter(adapter);
adapter.notifyDataSetChanged();
where DataGestoure is a class that manipulates some data from a
database and store them in a ArrayList (DataGestour.getAllDatas is the method to return the data under a ArrayList)
The problem start only if the ArrayList contains more then 3 items becouse the RecyclerView doen't show them despite the fact that the adapter holds all the data in ArrayList< DataGestour.Indovinello > data
Well, you need a little more order in your code, since it is not properly structured, by default the RecyclerView has its Scrolleable view unless in the XML this attribute is removed, well I recommend that you use this code in your adapter and use a model to save the information you get from your BD, that is the correct way to work to keep everything in order and it is easier to work it, once this is done you can use this code perfectly that I am sure will work, remember to only pass information to my Model that in my case calls it "Model" and with this the error of your data load will be solved. It is also advisable to use a List <> for these cases since the Arrays <> tend to have errors when you manipulate the data and more if you do it the way you present the code.
private List<Model> mDataList;
public MyAdapter(Context context){
this.context = context;
this.mDataList = new ArrayList<>();
}
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.indovinelloelement,parent,false);
return new MyHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyHolder holder, int position) {
MyHolder holder = (MyHolder) MyHolder;
hoder.bind(mDataList.getPosition(position));
}
#Override
public int getItemCount() {
return mDataList.size();
}
public void setData(List<Model> list) {
mDataList.clear();
mDataList.addAll(list);
notifyDataSetChanged();
}
public class MyHolder extends RecyclerView.ViewHolder {
TextView category;
category = (TextView)itemView.findViewById(R.id.categoria);
TextView score;
score = (TextView)itemView.findViewById(R.id.punteggio);
TextView difficulty;
difficulty = (TextView) itemView.findViewById(R.id.difficolta);
TextView title;
title = (TextView)itemView.findViewById(R.id.titolo);
ImageView lock_state;
lock_state = (ImageView) itemView.findViewById(R.id.lock_state);
public MyHolder(View itemView) {
super(itemView);
}
protected void bind(Model model){
category.setText(model.getCategory());
score.setText(model.getScore());
difficulty.setText(model.getDifficulty());
title.setText(model.getTitle());
if(model.isLocked()){
lock_state.setImageResource(R.drawable.ic_lock_outline_black_24dp);
} else {
lock_state.setImageResource(R.drawable.ic_lock_open_black_24dp);
}
}
}
}
And for your class that contains the RecyclerView use the code as follows.
RecyclerView mRecyclerView;
mRecyclerView = (RecyclerView)root_view.findViewById(R.id.lista_domande);
private MyAdapter mAdapter;
private List<Model> mDataList;
private DataGestour gestour;
private void setupRecyclerView(){
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(linearLayoutManager);
mAdapter = new MyAdapter(getContext());
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setData(mDataList);
}
private void getDataDB(){
mDataList.add(gestour.getAllDatas);
}

Displaying recyclerView on MainActivity

I'm trying to display my recyclerView on MainActivity, but can't seem to do it.
This is my code: (which compiles with no errors)
private RecyclerView recyclerView;
private MyAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) this.findViewById(R.id.recycler_view_example);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyAdapter(this, getData());
recyclerView.setAdapter(adapter);
// Add Code to display recyclerView on Main...
}
// This is not my actual data, just testing it out
public static List<Block> getData() {
List<Block> data = new ArrayList<>();
String[] ids = {"310", "313", "320"};
String[] names = {"name of three ten", "name of three thirteen", "name of three twenty"};
for (int i=0; i<ids.length; i++) {
data.add(new Block(ids[i], names[i]));
}
return data;
}
And myActivity Class:
private final LayoutInflater inflater;
// Data: (information)
List<Block> data = new ArrayList<>();
public MyAdapter(Context context, List<Block> data) {
inflater = LayoutInflater.from(context);
this.data = data;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.block, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder h, int position) {
MyViewHolder holder = new MyViewHolder(h.itemView);
Block current = data.get(position);
holder.id.setText(current.getId());
holder.name.setText(current.getName());
}
#Override
public int getItemCount() {
return 0;
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView id;
TextView name;
Button button;
// Constructor
public MyViewHolder(View itemView) {
super(itemView);
id = (TextView) itemView.findViewById(R.id.the_course_id);
name = (TextView) itemView.findViewById(R.id.course_name);
button = (Button) itemView.findViewById(R.id.click);
}
}
}
All I'm trying to do now is that when I run the emulator, I will see the contents of the recyclerView. But, I've been stuck on this for a while as nothing seems to work.
Mind you I'm a beginner with Android, so forgive me if this is very trivial.
You should return the number of items in your list, within getItemCount as in:
#Override
public int getItemCount() {
return data.size();
}
Ok here you need to change the following: update -
recyclerView.setLayoutManager(new LinearLayoutManager(this));
to
recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
and in adapter class change:
#Override
public int getItemCount() {
return data.size();
}
thats it. Happy coding :)
Change onBindViewHolder to:
#Override
public void onBindViewHolder(RecyclerView.ViewHolder h, int position) {
Block current = data.get(position);
h.id.setText(current.getId());
h.name.setText(current.getName());
}
also add #SelçukCihan solution to this
EDIT
Also if you want to use your MyViewHolder you have to change the following:
First change class signature:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>
and also change the signature for onBindViewHolder:
public void onBindViewHolder(MyViewHolder h, int position)
and finally change the signature of your MyViewHolder class:
static class MyViewHolder extends RecyclerView.ViewHolder

Categories