I'm trying to display the data from my Firebase but it won't display to my recyclerView. I don't know what was wrong.
I'm also trying to find some tutorials or the same question from stackoverflow but I don't get it. Still don't show the data from Firebase.
HistoryActivity.class
public class HistoryActivity extends AppCompatActivity {
String name, route;
int earnings, time, distance, totalPassenger, tripCount;
private Firebase ref;
private RecyclerView recycler;
private RecyclerViewAdapter adapter;
List<History> historyList;
History history;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history);
Firebase.setAndroidContext(this);
recycler = (RecyclerView) findViewById(R.id.recyclerview);
historyList = fillData();
recycler.setLayoutManager(new LinearLayoutManager(this));
}
public List<History> fillData() {
historyList = new ArrayList<>();
ref = new Firebase(Config.FIREBASE_URL_HISTORY_DRIVER);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Toast.makeText(HistoryActivity.this, snapshot.getValue()+"", Toast.LENGTH_SHORT).show();
name = snapshot.child("driverName").getValue().toString().trim();
route = snapshot.child("destination").getValue().toString().trim();
earnings = Integer.valueOf(snapshot.child("earnings").getValue().toString().trim());
time = Integer.valueOf(snapshot.child("time").getValue().toString().trim());
distance = Integer.valueOf(snapshot.child("distanceTravelled").getValue().toString().trim());
totalPassenger = Integer.valueOf(snapshot.child("totalPassenger").getValue().toString().trim());
tripCount = Integer.valueOf(snapshot.child("tripCount").getValue().toString().trim());
historyList.add(new History(name, route, earnings, time, distance, totalPassenger, tripCount));
}
Toast.makeText(HistoryActivity.this, historyList.size()+":size", Toast.LENGTH_LONG).show();
adapter = new RecyclerViewAdapter(historyList);
recycler.setAdapter(adapter);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
return historyList;
}
}
RecyclerViewAdapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.HistoryViewHolder> {
List<History> historyList;
Context context;
public RecyclerViewAdapter(List<History> historyList) {
this.historyList = historyList;
}
#Override
public HistoryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflate the layout, initialize the View Holder
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_layout, parent, false);
HistoryViewHolder holder = new HistoryViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(RecyclerViewAdapter.HistoryViewHolder holder, int position) {
holder.driversName.setText(historyList.get(position).getDriversName());
holder.route.setText(historyList.get(position).getRoute());
holder.totalEarnings.setText(historyList.get(position).getEarnings());
holder.time.setText(historyList.get(position).getTime());
holder.distance.setText(historyList.get(position).getDistance());
holder.totalPassenger.setText(historyList.get(position).getTotalPassenger());
holder.tripCount.setText(historyList.get(position).getTripCount());
animate(holder);
}
#Override
public int getItemCount() {
return historyList.size();
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public void animate(RecyclerView.ViewHolder viewHolder) {
final Animation animAnticipateOvershoot = AnimationUtils.loadAnimation(context, R.anim.bounce_interpolator);
viewHolder.itemView.setAnimation(animAnticipateOvershoot);
}
public static class HistoryViewHolder extends RecyclerView.ViewHolder {
CardView cardView;
EditText driversName;
EditText route;
EditText totalEarnings;
EditText time;
EditText distance;
EditText totalPassenger;
EditText tripCount;
public HistoryViewHolder(View itemView) {
super(itemView);
cardView = (CardView) itemView.findViewById(R.id.cardView);
driversName = (EditText) itemView.findViewById(R.id.edtDriversName);
route = (EditText) itemView.findViewById(R.id.edtRoute);
totalEarnings = (EditText) itemView.findViewById(R.id.edtEarning);
time = (EditText) itemView.findViewById(R.id.edtTime);
distance = (EditText) itemView.findViewById(R.id.edtDistance);
totalPassenger = (EditText) itemView.findViewById(R.id.edtTotalPass);
tripCount = (EditText) itemView.findViewById(R.id.edtTripCount);
}
}
}
History(pojo)
public class History {
private String username;
private String driversName;
private String route;
private int earnings;
private int time;
private int distance;
private int totalPassenger;
private int tripCount;
public History(String driversName, String route, int earnings, int time, int distance, int totalPassenger, int tripCount) {
this.driversName = driversName;
this.route = route;
this.earnings = earnings;
this.time = time;
this.distance = distance;
this.totalPassenger = totalPassenger;
this.tripCount = tripCount;
}
You need to set layout before setting adapter like this:
recycler = (RecyclerView) findViewById(R.id.recyclerview);
recycler.setLayoutManager(new LinearLayoutManager(this));
historyList = fillData();
Related
This question already has answers here:
recyclerview No adapter attached; skipping layout
(38 answers)
Closed 1 year ago.
Don't know why it says "No adapter attached"
I set the layout manager and the recycler view, in middle of showProducts(); method i also set the adapter to the recycler view and still says: "No adapter attached" Can't find where is the issue, i'll gladly accept some help. Thanks folks!
Nothing shows on screen for the following code:
Main activity:
public class MainActivity extends AppCompatActivity {
private RecyclerView rView;
private RecyclerView.LayoutManager layoutManager;
private List<Product> products;
private ProductAdapter productAdapter;
private DatabaseReference mDataBase;
private CardView cardView;
//Product
private String id;
private String name;
private String author;
private String genre;
private String description;
private double price;
private int stock;
private String image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
products = new ArrayList<Product>();
mDataBase = FirebaseDatabase.getInstance().getReference();
cardView = (CardView) findViewById(R.id.cardView);
layoutManager = new LinearLayoutManager(this);
rView = (RecyclerView) findViewById(R.id.recyclerView);
rView.setHasFixedSize(true);
rView.setLayoutManager(layoutManager);
showProducts();
registerForContextMenu(rView);
}
private void showProducts() {
mDataBase.child("Products").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
products.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
name = ds.child("title").getValue().toString();
author = ds.child("author").getValue().toString();
genre = ds.child("genre").getValue().toString();
description = ds.child("description").getValue().toString();
price = Double.parseDouble(ds.child("price").getValue().toString());
stock = Integer.parseInt(ds.child("stock").getValue().toString());
image = ds.child("image").getValue().toString();
id = ds.getKey();
Product product = new Product(id, name, author, genre, description, price, stock, image);
products.add(product);
}
productAdapter = new ProductAdapter(products, R.layout.recycler_view, new ProductAdapter.OnItemClickListener() {
#Override
public void onItemClick(Product product, int position) {
}
}, new ProductAdapter.OnButtonClickListener() {
#Override
public void onButtonClick(Product product, int position) {
}
});
}
rView.setAdapter(productAdapter);
}
// Observa como pasamos el activity, con this. Podríamos declarar
// Activity o Context en el constructor y funcionaría pasando el mismo valor, this
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Adapter:
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHolder>{
private Context context;
private List<Product> products;
private int layout;
private OnItemClickListener itemClickListener;
private OnButtonClickListener btnClickListener;
public ProductAdapter(List<Product> products, int layout, OnItemClickListener itemListener, OnButtonClickListener btnListener) {
this.products = products;
this.layout = layout;
this.itemClickListener = itemListener;
this.btnClickListener = btnListener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
context = parent.getContext();
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(products.get(position), itemClickListener, btnClickListener);
}
#Override
public int getItemCount() {
return products.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public TextView author;
public TextView genre;
public TextView description;
public TextView price;
public TextView stock;
public ImageView image;
public Button btnDelete;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.textViewProductName);
author = (TextView) itemView.findViewById(R.id.textViewProductAuthor);
genre = (TextView) itemView.findViewById(R.id.textViewProductGenre);
description = (TextView) itemView.findViewById(R.id.textViewProductDescription);
price = (TextView) itemView.findViewById(R.id.textViewProductPrice);
stock = (TextView) itemView.findViewById(R.id.textViewProductStock);
image = (ImageView) itemView.findViewById(R.id.imageViewProduct);
btnDelete = (Button) itemView.findViewById(R.id.buttonDeleteCity);
}
public void bind(final Product product, final OnItemClickListener itemListener, final OnButtonClickListener btnListener) {
name.setText(product.getName());
description.setText(product.getDescription());
price.setText((int) product.getPrice());
Picasso.get().load(product.getImage()).fit().into(image);
btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
btnListener.onButtonClick(product, getAdapterPosition());
}
});
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
itemListener.onItemClick(product, getAdapterPosition());
}
});
}
}
public interface OnItemClickListener {
void onItemClick(Product product, int position);
}
public interface OnButtonClickListener {
void onButtonClick(Product product, int position);
}
}
Bind Adapter in onCreate
Use it like this
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
products = new ArrayList<Product>();
mDataBase = FirebaseDatabase.getInstance().getReference();
cardView = (CardView) findViewById(R.id.cardView);
layoutManager = new LinearLayoutManager(this);
rView = (RecyclerView) findViewById(R.id.recyclerView);
rView.setHasFixedSize(true);
rView.setLayoutManager(layoutManager);
rView.setAdapter(productAdapter);
showProducts();
registerForContextMenu(rView);
}
private void showProducts() {
mDataBase.child("Products").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
products.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
name = ds.child("title").getValue().toString();
author = ds.child("author").getValue().toString();
genre = ds.child("genre").getValue().toString();
description = ds.child("description").getValue().toString();
price = Double.parseDouble(ds.child("price").getValue().toString());
stock = Integer.parseInt(ds.child("stock").getValue().toString());
image = ds.child("image").getValue().toString();
id = ds.getKey();
Product product = new Product(id, name, author, genre, description, price, stock, image);
products.add(product);
}
productAdapter = new ProductAdapter(products, R.layout.recycler_view, new ProductAdapter.OnItemClickListener() {
#Override
public void onItemClick(Product product, int position) {
}
}, new ProductAdapter.OnButtonClickListener() {
#Override
public void onButtonClick(Product product, int position) {
}
});
}
productAdapter.notifyDataStateChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
I had ask same question 1 day ago and my question got closed so i ask it again.
Don't know why it says "No adapter attached"
I set the layout manager and the recycler view, in middle of showProducts(); method i also set the adapter to the recycler view and still says: "No adapter attached" Can't find where is the issue, i'll gladly accept some help. Thanks folks!
Nothing shows on screen for the following code:
Main activity:
public class MainActivity extends AppCompatActivity {
private RecyclerView rView;
private RecyclerView.LayoutManager layoutManager;
private List<Product> products;
private ProductAdapter productAdapter;
private DatabaseReference mDataBase;
private CardView cardView;
//Product
private String id;
private String name;
private String author;
private String genre;
private String description;
private double price;
private int stock;
private String image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
products = new ArrayList<Product>();
mDataBase = FirebaseDatabase.getInstance().getReference();
cardView = (CardView) findViewById(R.id.cardView);
layoutManager = new LinearLayoutManager(this);
rView = (RecyclerView) findViewById(R.id.recyclerView);
rView.setHasFixedSize(true);
rView.setLayoutManager(layoutManager);
showProducts();
registerForContextMenu(rView);
}
private void showProducts() {
mDataBase.child("Products").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
products.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
name = ds.child("title").getValue().toString();
author = ds.child("author").getValue().toString();
genre = ds.child("genre").getValue().toString();
description = ds.child("description").getValue().toString();
price = Double.parseDouble(ds.child("price").getValue().toString());
stock = Integer.parseInt(ds.child("stock").getValue().toString());
image = ds.child("image").getValue().toString();
id = ds.getKey();
Product product = new Product(id, name, author, genre, description, price, stock, image);
products.add(product);
}
productAdapter = new ProductAdapter(products, R.layout.recycler_view, new ProductAdapter.OnItemClickListener() {
#Override
public void onItemClick(Product product, int position) {
}
}, new ProductAdapter.OnButtonClickListener() {
#Override
public void onButtonClick(Product product, int position) {
}
});
}
rView.setAdapter(productAdapter);
}
// Observa como pasamos el activity, con this. Podríamos declarar
// Activity o Context en el constructor y funcionaría pasando el mismo valor, this
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Adapter:
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHolder>{
private Context context;
private List<Product> products;
private int layout;
private OnItemClickListener itemClickListener;
private OnButtonClickListener btnClickListener;
public ProductAdapter(List<Product> products, int layout, OnItemClickListener itemListener, OnButtonClickListener btnListener) {
this.products = products;
this.layout = layout;
this.itemClickListener = itemListener;
this.btnClickListener = btnListener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
context = parent.getContext();
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(products.get(position), itemClickListener, btnClickListener);
}
#Override
public int getItemCount() {
return products.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public TextView author;
public TextView genre;
public TextView description;
public TextView price;
public TextView stock;
public ImageView image;
public Button btnDelete;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.textViewProductName);
author = (TextView) itemView.findViewById(R.id.textViewProductAuthor);
genre = (TextView) itemView.findViewById(R.id.textViewProductGenre);
description = (TextView) itemView.findViewById(R.id.textViewProductDescription);
price = (TextView) itemView.findViewById(R.id.textViewProductPrice);
stock = (TextView) itemView.findViewById(R.id.textViewProductStock);
image = (ImageView) itemView.findViewById(R.id.imageViewProduct);
btnDelete = (Button) itemView.findViewById(R.id.buttonDeleteCity);
}
public void bind(final Product product, final OnItemClickListener itemListener, final OnButtonClickListener btnListener) {
name.setText(product.getName());
description.setText(product.getDescription());
price.setText((int) product.getPrice());
Picasso.get().load(product.getImage()).fit().into(image);
btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
btnListener.onButtonClick(product, getAdapterPosition());
}
});
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
itemListener.onItemClick(product, getAdapterPosition());
}
});
}
}
public interface OnItemClickListener {
void onItemClick(Product product, int position);
}
public interface OnButtonClickListener {
void onButtonClick(Product product, int position);
}
}
Move this line inside if condition rView.setAdapter(productAdapter); in your showProducts function
like below
private void showProducts() {
mDataBase.child("Products").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
products.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
name = ds.child("title").getValue().toString();
author = ds.child("author").getValue().toString();
genre = ds.child("genre").getValue().toString();
description = ds.child("description").getValue().toString();
price = Double.parseDouble(ds.child("price").getValue().toString());
stock = Integer.parseInt(ds.child("stock").getValue().toString());
image = ds.child("image").getValue().toString();
id = ds.getKey();
Product product = new Product(id, name, author, genre, description, price, stock, image);
products.add(product);
}
productAdapter = new ProductAdapter(products, R.layout.recycler_view, new ProductAdapter.OnItemClickListener() {
#Override
public void onItemClick(Product product, int position) {
}
}, new ProductAdapter.OnButtonClickListener() {
#Override
public void onButtonClick(Product product, int position) {
}
}); rView.setAdapter(productAdapter); }
}
// Observa como pasamos el activity, con this. Podríamos declarar
// Activity o Context en el constructor y funcionaría pasando el mismo valor, this
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
ProductAdapter productAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
products = new ArrayList<Product>();
mDataBase = FirebaseDatabase.getInstance().getReference();
cardView = (CardView) findViewById(R.id.cardView);
productAdapter = new ProductAdapter(products, R.layout.recycler_view, new ProductAdapter.OnItemClickListener() {
#Override
public void onItemClick(Product product, int position) {
}
}, new ProductAdapter.OnButtonClickListener() {
#Override
public void onButtonClick(Product product, int position) {
}
});
layoutManager = new LinearLayoutManager(this);
rView = (RecyclerView) findViewById(R.id.recyclerView);
rView.setHasFixedSize(true);
rView.setLayoutManager(layoutManager);
rView.setAdapter(productAdapter);
showProducts();
registerForContextMenu(rView);
}
make sure you initialize your adapter in your onCreate as I did and for your list do this in the onDataChange
`Product product = new Product(id, name, author, genre,
description, price, stock, image);
products.add(product);
productAdapter.notifyDataSetChanged();`
My recyclerview always reset to first position after new data is inserted to firebase. In my TestAdapter class, I have an onClickListener which increments like on a post when clicked. Whenever I click on this "like" button, view is reset to first position. I believe this issue is related to setAdapter() being called on data changed. Please help!
MainActivity fetches "post" data from Firebase and populates it in TestAdapter class.
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private TestAdapter testAdapter;
private ArrayList<Post> postList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
fetchPostFromDB();
}
private void fetchPostFromDB() {
DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference("Post");
databaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
postList = new ArrayList<>();
for (DataSnapshot snap : snapshot.getChildren()) {
String post = snap.child("post").getValue().toString();
Post post = new Post(post);
postList.add(post);
}
testAdapter = new TestAdapter(getApplicationContext(), postList);
recyclerView.setAdapter(testAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
TestAdapter binds the data (postList) and has an onClickListener.
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.TestHolder> {
private List<Post> postList;
private Context context;
private DatabaseReference databaseReference;
public TestAdapter(Context ct, ArrayList<Post> postList) {
context = ct;
this.postList = postList;
}
#NonNull
#Override
public TestHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.post_item, parent, false);
final TestHolder holder = new TestHolder(view);
holder.ibLike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String postID = postList.get(holder.getAdapterPosition()).getPostID();
databaseReference = FirebaseDatabase.getInstance().getReference("Posts").child(postID).child("likes");
int incrementLike = postList.get(holder.getAdapterPosition()).getLikes() + 1;
databaseReference.setValue(incrementLike);
}
});
return holder;
}
#Override
public void onBindViewHolder(#NonNull final TestHolder holder, final int position) {
holder.tvPost.setText(postList.get(position).getPost());
holder.tvVotes.setText(Integer.toString(postList.get(position).getLikes()));
}
#Override
public int getItemCount() {
return postList.size();
}
public static class TestHolder extends RecyclerView.ViewHolder {
TextView tvPost, tvLikes;
ImageButton ibLike;
public TestHolder(#NonNull View itemView) {
super(itemView);
tvPost = itemView.findViewById(R.id.tvPost);
tvLikes = itemView.findViewById(R.id.tvLikes);
ibLike = itemView.findViewById(R.id.ibLike);
}
}
Here need to initialize your adapter class from main activity. and then when data received just call adapter.notifiyDatasetChanged like:
onCreate():
postList = new ArrayList<>();
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
testAdapter = new TestAdapter(getApplicationContext(), postList);
recyclerView.setAdapter(testAdapter);
and from your fetchPostFromDB delete adapter initialization insted of this just put this line testAdapter.notifiyDataSetChanged()
And when click on text button you can update/handle like this:
holder.ibLike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String postID = postList.get(holder.getAdapterPosition()).getPostID();
databaseReference = FirebaseDatabase.getInstance().getReference("Posts").child(postID).child("likes");
int incrementLike = postList.get(holder.getAdapterPosition()).getLikes() + 1;
postList.get(holder.getAdapterPosition()).setLikes(incrementLike);
databaseReference.setValue(incrementLike);
notifyDataSetChanged();
}
});
So my problem is that.. why does the isChecked method not working.
My first guess to my problem would be im declaring the wrong array?
My second guess would be I lack something to call or missing something out?
the goal of my code here is to create a collector in firebase and then record it in the database of the collector by which the user chose from the multiple selected job orders
public class MainActivity extends AppCompatActivity {
private List<Model> mModelList;
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
Button mjobOrderBtn;
FirebaseAuth fAuth;
FirebaseFirestore fStore;
String jobId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recyclerview);
mjobOrderBtn = findViewById(R.id.jobOrderBtn);
mRecyclerView = findViewById(R.id.recycler_view);
mAdapter = new RecyclerViewAdapter(getListData());
LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(manager);
mRecyclerView.setAdapter(mAdapter);
fAuth = FirebaseAuth.getInstance();
fStore = FirebaseFirestore.getInstance();
jobId = fAuth.getCurrentUser().getUid();
DocumentReference documentReference = fStore.collection("job order").document(jobId);
mjobOrderBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mRecyclerView.isChecked()){
}
}
});
}
private List<Model> getListData() {
mModelList = new ArrayList<>();
mModelList.add(new Model("Flat Tire "));
mModelList.add(new Model("Towing "));
mModelList.add(new Model("Battery "));
mModelList.add(new Model("Empty Gas "));
return mModelList;
}
}
RecyclerViewAdaptor.java
class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
private List<Model> mModelList;
public RecyclerViewAdapter(List<Model> modelList) {
mModelList = modelList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_itemrow, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
final Model model = mModelList.get(position);
holder.textView.setText(model.getText());
holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);
holder.textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
model.setSelected(!model.isSelected());
holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);
}
});
}
#Override
public int getItemCount() {
return mModelList == null ? 0 : mModelList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private View view;
private TextView textView;
private MyViewHolder(View itemView) {
super(itemView);
view = itemView;
textView = itemView.findViewById(R.id.text_view);
}
}
}
Also here's the model class
Model.java
public class Model {
private String text;
private boolean isSelected = false;
public Model(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
public boolean isSelected() {
return isSelected;
}
}
you need to create checkbox inside view item layout for each item in your array. Here is an example
you can get your order list with a defined method inside adapter class. Something like this:
public List<Model> getSelectedItems(){
List<Model> results = new ArrayList<Model>();
for(model: mModelList){
if(model.isSelected()){
results.add(model);
}
}
return results;
}
And inside button order click method, just get it out:
mjobOrderBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
List<Model> orderList = mAdapter.getSelectedItems();
}
});
I have a problem, when I enter my FinalListActivity first time by clicking button in MainActivity, everything works good. But when I go back to MainActivity and then I try enter again it throws an exception:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: app.listazakupow, PID: 5147
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at app.listazakupow.Adapters.FinalListAdapter.onBindViewHolder(FinalListAdapter.java:44)
at app.listazakupow.Adapters.FinalListAdapter.onBindViewHolder(FinalListAdapter.java:16)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6781)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5752)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6019)
I know it's something wrong with my int ArrayList in Adapter class but i dont know what i should do. It is this fragment:
holder.imageView.setImageResource(imagesIndex.get(position));
Can somone help me? Below my code:
FinalListActivity
public class FinalListActivity extends AppCompatActivity {
private ArrayList<String> finalListArrayList;
private ArrayList<Integer> imagesIndex;
private RecyclerView recyclerView;
private TextView textView1, textView2, textView3;
private FinalListAdapter myAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private AppDatabase appDatabase;
private static final String DATABASE_NAME = "images_base";
#SuppressLint({"WrongViewCast", "SetTextI18n"})
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_finallist);
Intent intent = getIntent();
finalListArrayList = intent.getStringArrayListExtra("productList");
imagesIndex = intent.getIntegerArrayListExtra("imagesList");
appDatabase = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, DATABASE_NAME).fallbackToDestructiveMigration().build();
recyclerView = findViewById(R.id.recycler_view1);
mLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLayoutManager);
AsyncTask.execute(new Runnable() {
#Override
public void run() {
for(String s:finalListArrayList) {
String category = appDatabase.daoAccess().getCategoryByKeyword(s);
String imagePath = appDatabase.daoAccess().getImagePathForCategory(category);
int id;
if(imagePath!=null) {
id = getApplicationContext().getResources().getIdentifier(imagePath, "drawable", getPackageName());
}
else{
id = getApplicationContext().getResources().getIdentifier("app_logo_black", "drawable", getPackageName());
}
imagesIndex.add(id);
}
System.out.println("FinalListArrayListSize is:" + finalListArrayList.size()+" imageIndexList is: "+imagesIndex.size());
}
});
myAdapter = new FinalListAdapter(finalListArrayList, imagesIndex, recyclerView);
recyclerView.setAdapter(myAdapter);
myAdapter.notifyDataSetChanged();
textView1 = findViewById(R.id.textView1);
textView2 = findViewById(R.id.textView2);
textView3 = findViewById(R.id.textView3);
textView1.setText("Amount of products: " + finalListArrayList.size());
}
#Override
protected void onResume(){
super.onResume();
System.out.println("FinalListArrayListSize is:" + finalListArrayList.size()+" imageIndexList is: "+imagesIndex.size());
}
}
FinalListAdapter
public class FinalListAdapter extends
RecyclerView.Adapter<FinalListAdapter.MyViewHolder> {
private ArrayList<String> mDataset;
private ArrayList<Integer> imagesIndex;
private ArrayList<FinalListItem> finalListItems;
private RecyclerView recyclerView;
public FinalListAdapter(ArrayList<String> mDataset,ArrayList<Integer> imagesIndex, RecyclerView recyclerView) {
this.mDataset = mDataset;
this.imagesIndex = imagesIndex;
this.recyclerView = recyclerView;
finalListItems = new ArrayList<>();
for (String a : mDataset) {
finalListItems.add(new FinalListItem(a, false));
}
}
public ArrayList<Integer> getImagesIndex(){
return imagesIndex;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return 0;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.final_list_TextView1.setText(finalListItems.get(position).getName());
holder.imageView.setImageResource(imagesIndex.get(position));
holder.checkBox.setOnCheckedChangeListener(null);
holder.checkBox.setBackgroundResource(R.drawable.listitem_white);
if(finalListItems.get(position).isChecked){
holder.linearLayout.setBackgroundResource(R.drawable.listitem_green);
holder.checkBox.setChecked(true);
}
else{
holder.linearLayout.setBackgroundResource(R.drawable.listitem_white);
holder.checkBox.setChecked(false);
}
holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int currentPosition = holder.getAdapterPosition();
if(isChecked){
FinalListItem finalItemBefore = finalListItems.get(currentPosition);
FinalListItem finalItemAfter = new FinalListItem(finalItemBefore.getName(), true);
finalListItems.remove(finalItemBefore);
finalListItems.add(finalItemAfter);
recyclerView.scrollToPosition(0);
holder.linearLayout.setBackgroundResource(R.drawable.listitem_green);
notifyItemMoved(currentPosition, getItemCount() - 1);
}
else{
finalListItems.get(currentPosition).setChecked(false);
notifyItemChanged(currentPosition);
}
}
});
}
#Override
public int getItemCount() {
return finalListItems.size();
}
private class FinalListItem {
private String name;
private boolean isChecked;
public FinalListItem(String name, boolean isChecked) {
this.name = name;
this.isChecked = isChecked;
}
public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
}
public String getName() {
return name;
}
}
public class MyViewHolder extends RecyclerView.ViewHolder {
final private TextView final_list_TextView1;
final private CheckBox checkBox;
final private LinearLayout linearLayout;
final private ImageView imageView;
public MyViewHolder(View view) {
super(view);
final_list_TextView1 = view.findViewById(R.id.final_list_TextView1);
checkBox = view.findViewById(R.id.checkBox1);
linearLayout = view.findViewById(R.id.linearLayout1);
imageView = view.findViewById(R.id.item_image);
}
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.finallist_list_layout, parent, false);
return new MyViewHolder(view);
}
}
Yes, the line of code:
holder.imageView.setImageResource(imagesIndex.get(position));
is causing the error.
Why? Because the value of position has nothing to do with the index of any value in the ArrayList "imagesIndex". The value position you get from onBindViewHolder refers to the row in the RecyclerView that means the ArrayList "finalListItems" which you generate in your constructor.