How do you call a fragment method from an adapter? - java

I would like to refresh my recycle view when a user taps a button, the problem is my recycle view is inside a fragment, and my user interface is being updated from my OnBindViewHolder method. So, my question is how do you call a method that's inside a fragment, from an Adapter. I would like to call my downloadCartData() from my Cart_Fragment when the user clicks on plusImageView from my adapter. I found some answers on stack overflow that says to use an interface, but I don't understand what's happening or how to apply it to my code.
public class CartAdapter extends RecyclerView.Adapter<CartAdapter.ViewHolder> {
private List<CartModel> cartArrayList;
private Context ct;
public int count = 1;
private String loggedInUserId;
public CartAdapter(List<CartModel> cartArrayList, Context ct) {
this.cartArrayList = cartArrayList;
this.ct = ct;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cart_row, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, #SuppressLint("RecyclerView") final int position) {
holder.produceName.setText(cartArrayList.get(position).getProductName());
Log.i("productname", cartArrayList.get(position).getProductName());
holder.producePrice.setText("$" + cartArrayList.get(position).getItemPrice());
holder.plusImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getCurrentUserUid();
count = count + 1;
FirebaseDatabase.getInstance().getReference("Cart").child(loggedInUserId).child(cartArrayList.get(position).getTimestamp()).child("quantity").setValue(count).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
holder.middleQUanityTv.setText(count + "");
// Cart_Fragment cart_fragment = new Cart_Fragment();
// cart_fragment.callMethod();
//
}
}
});
}
});
//Log.i("IMAGES", productArrayList.get(position).getProductImage());
Glide.with(ct)
.load(cartArrayList.get(position).getProductImage())
.centerCrop()
.into(holder.productImage);
}
#Override
public int getItemCount() {
return cartArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView produceName, producePrice, middleQUanityTv;
private ImageView productImage, plusImageView, minusImageView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
produceName = itemView.findViewById(R.id.itemNameTv);
producePrice = itemView.findViewById(R.id.priceTv);
productImage = itemView.findViewById(R.id.productImageView);
plusImageView = itemView.findViewById(R.id.plusImageView);
middleQUanityTv = itemView.findViewById(R.id.middleQuanaityTv);
}
}
//hide ui elements here..
public void getCurrentUserUid() {
FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
if (firebaseUser != null) {
loggedInUserId = firebaseUser.getUid(); //Do what you need to do with your uid
Log.i("loggedInUserUid", loggedInUserId);
}
}
}
public void downloadCartData() {
cartDb.child("Cart").child(loggedInUserId).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
if (data.exists()) {
//get the item prices to add to hashmap.
String price = data.child("itemPrice").getValue().toString();
String quantity = data.child("quantity").getValue().toString();
priceArrayList.add(price);
quantityArrayList.add(quantity);
cartModel = data.getValue(CartModel.class);
cartModelArrayList.add(cartModel);
LinearLayoutManager horizontalLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
cartRecyleView.setLayoutManager(horizontalLayoutManager);
cartAdapter = new CartAdapter(cartModelArrayList, getContext());
cartRecyleView.setAdapter(cartAdapter);
} else {
Log.i("error", "Error Loading JSON data..");
}
}
calculatePrice(priceArrayList, quantityArrayList);
Log.i("priceArrayList", priceArrayList + "");
Log.i("quanityArrayList", quantityArrayList + "");
}
#Override
public void onCancelled(DatabaseError databaseError) {
String error = databaseError.getDetails();
Log.i("error", error);
}
});
}

You have heard right from the other stack overflow posts that you can use interface to call the method of the fragment from the adapter.
First you have to create a interface and define the method name in the
interface.
interface DownloadCart{
void downloadCartData();
}
After creating this interface you need to implement this interface
into the fragment where your recycler view is declared.
class Cart_Fragment implements DownloadCart{
After implementing this interface into the class it will show you red
line in android studio. it will require to add the method of the
interface into your fragment. add your code of the
downloadCartData into this interface method body in your fragment.
void downloadCartData(){
cartDb.child("Cart").child(loggedInUserId).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
if (data.exists()) {
//get the item prices to add to hashmap.
String price = data.child("itemPrice").getValue().toString();
String quantity = data.child("quantity").getValue().toString();
priceArrayList.add(price);
quantityArrayList.add(quantity);
cartModel = data.getValue(CartModel.class);
cartModelArrayList.add(cartModel);
LinearLayoutManager horizontalLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
cartRecyleView.setLayoutManager(horizontalLayoutManager);
cartAdapter = new CartAdapter(cartModelArrayList, getContext());
cartRecyleView.setAdapter(cartAdapter);
} else {
Log.i("error", "Error Loading JSON data..");
}
}
calculatePrice(priceArrayList, quantityArrayList);
Log.i("priceArrayList", priceArrayList + "");
Log.i("quanityArrayList", quantityArrayList + "");
}
#Override
public void onCancelled(DatabaseError databaseError) {
String error = databaseError.getDetails();
Log.i("error", error);
}
});
}
Create on object of the interface into your adapter.
DownloadCart inf;
Define your adapter constructor like this and pass your interface
object into the adapter call.
public CartAdapter(List<CartModel> cartArrayList, Context ct, DownloadCart inf) {
this.cartArrayList = cartArrayList;
this.ct = ct;
this.inf = inf;
}
After that on bind view holder call your fragment method into the
adapter by using the interface object. it will call the method from
the fragment.
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, #SuppressLint("RecyclerView") final int position) {
holder.produceName.setText(cartArrayList.get(position).getProductName());
Log.i("productname", cartArrayList.get(position).getProductName());
holder.producePrice.setText("$" + cartArrayList.get(position).getItemPrice());
holder.plusImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getCurrentUserUid();
count = count + 1;
FirebaseDatabase.getInstance().getReference("Cart").child(loggedInUserId).child(cartArrayList.get(position).getTimestamp()).child("quantity").setValue(count).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
holder.middleQUanityTv.setText(count + "");
inf.downloadCartData();
}
}
});
}
});
//Log.i("IMAGES", productArrayList.get(position).getProductImage());
Glide.with(ct)
.load(cartArrayList.get(position).getProductImage())
.centerCrop()
.into(holder.productImage);
}
Tadaaa!!! and your method from fragment is called from adapter.

Pass the Cart_Fragment inside your adapter Constructor, then simply call the method you're trying to reference from your onClickListener by referencing the passed Fragment.
private Cart_Fragment cart_fragment = new Cart_Fragment();
public CartAdapter(List<CartModel> cartArrayList, Context ct, Cart_Fragment cart_fragment) {
this.cartArrayList = cartArrayList;
this.ct = ct;
this.cart_fragment = cart_fragment;
}
#Override
public void onClick(View view) {
getCurrentUserUid();
count = count + 1;
FirebaseDatabase.getInstance().getReference("Cart").child(loggedInUserId).child(cartArrayList.get(position).getTimestamp()).child("quantity").setValue(count).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
holder.middleQUanityTv.setText(count + "");
Cart_Fragment cart_fragment = new Cart_Fragment();
cart_fragment.callMethod();
}
}
});
}
});

Related

Realtime Display Value Change form Firebase

I am new to android studio and currently watching tutorials. As of now I have a Shopping cart activity where I can increment, decrement and delete items in cart. The thing is whenever I delete, add or deduct an item, the cart values does not update. I still need to change activities to see the changes. Also the item that I deleted still appears at the bottom of recyclerview items after the dialog appearance unless I change the activity and go back. Please help me how to apply real time update. Below are my class files for the cart activity and adapter class.
CartActivity.java
#Override
protected void onStop() {
if (EventBus.getDefault().hasSubscriberForEvent(MyUpdateCartEvent.class))
EventBus.getDefault().removeStickyEvent(MyUpdateCartEvent.class);
EventBus.getDefault().unregister(this);
super.onStop();
}
#Subscribe(threadMode = ThreadMode.MAIN_ORDERED, sticky = true)
public void onUpdateCart(MyUpdateCartEvent event) {
loadCartFromFirebase();
}
private void loadCartFromFirebase() {
fAuth = FirebaseAuth.getInstance();
if(fAuth.getCurrentUser() != null){
userId = fAuth.getCurrentUser().getUid();
} else {
userId = "UNIQUE_USER_ID";
}
List<CartModel> cartModels = new ArrayList<>();
FirebaseDatabase.getInstance()
.getReference("cart")
.child(userId)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
for (DataSnapshot cartSnapshot : snapshot.getChildren()) {
CartModel cartModel = cartSnapshot.getValue(CartModel.class);
cartModel.setKey(cartSnapshot.getKey());
cartModels.add(cartModel);
}
cartLoadListener.onCartLoadSuccess(cartModels);
} else {
cartLoadListener.onCartLoadFailed("Cart Empty");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
cartLoadListener.onCartLoadFailed(error.getMessage());
}
});
}
private void init() {
ButterKnife.bind(this);
cartLoadListener = this;
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recycler_cart.setLayoutManager(layoutManager);
purchScrnBtn.setOnClickListener(v -> startActivity(new Intent(this, PurchaseActivity.class)));
}
#Override
public void onCartLoadSuccess(List<CartModel> cartModelList) {
double sum = 0;
for (CartModel cartModel : cartModelList) {
sum += cartModel.getTotalPrice();
}
textTotal.setText(new StringBuilder("$").append(sum));
MyCartAdapter adapter = new MyCartAdapter(this, cartModelList);
recycler_cart.setAdapter(adapter);
}
MyCartAdapter.java
package com.example.cart.adapter;
public class CartActivity extends AppCompatActivity implements CartLoadListener {
public MyCartViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new MyCartViewHolder(LayoutInflater.from(context)
.inflate(R.layout.layout_cart_item, parent, false));
}
#Override
public void onBindViewHolder(#NonNull MyCartViewHolder holder, int position) {
holder.minus.setOnClickListener(v -> {
minusCartItem(holder,cartModelList.get(position));
});
holder.delete.setOnClickListener(v -> {
AlertDialog dialog = new AlertDialog.Builder(context)
.setTitle("Delete item")
.setMessage("Do you really want to delete item")
.setNegativeButton("CANCEL", (dialogInterface, i) -> dialogInterface.dismiss())
.setPositiveButton("OK", (dialogInterface2, i) -> {
//Temp remove
notifyItemRemoved(position);
deleteFromFirebase(cartModelList.get(position));
dialogInterface2.dismiss();
}).create();
dialog.show();
});
}
private void deleteFromFirebase(CartModel cartModel) {
FirebaseDatabase.getInstance()
.getReference("cart")
.child(userId)
.child(cartModel.getKey())
.removeValue()
.addOnSuccessListener(aVoid -> EventBus.getDefault().postSticky(new MyUpdateCartEvent()));
}
#SuppressLint("SuspiciousIndentation")
private void minusCartItem(MyCartViewHolder holder, CartModel cartModel) {
if(cartModel.getQuantity() > 1)
cartModel.setQuantity(cartModel.getQuantity()-1);
cartModel.setTotalPrice(cartModel.getQuantity()*Float.parseFloat(cartModel.getPrice()));
//update quantity
holder.txtQuantity.setText(new StringBuilder().append(cartModel.getQuantity()));
updateFirebase(cartModel);
}
public class MyCartViewHolder extends RecyclerView.ViewHolder{
Unbinder unbinder;
public MyCartViewHolder(#NonNull View itemView) {
super(itemView);
unbinder = ButterKnife.bind(this, itemView);
}
}
}
The thing is whenever I delete, add or deduct an item, the cart values does not update.
That's because you load data from Firebase with addListenerForSingleValueEvent, which only loads the data when you call it. If you want to continue to monitor the data for changes, use addValueEventListener instead.

How to flow Data from One RecyclerView to Another RecyclerView when an item in first RecyclerView is clicked?

Hi, I faced an issue here.. I was creating a chatbot in which user can type a text to send it and also can select a text out of the recommended texts
so I created two RecycleViews
My goal is - when the user selects one of the recommended text, then that text should appear in the Chatting RecycleView
here is my main Activity Class
public class Charts extends AppCompatActivity {
private static final String USER_KEY = "user";
private static final String BOT_KEY = "bot";
RecyclerView chart_recycle,auto_texts;
EditText message_text;
ImageView send_btn,mic_button;
ImageView setting_button;
ChartsAdapter chartsAdapter;
RecyclerView.LayoutManager linearLayout;
ArrayList<ChartModeClass> modeClassesArrayList = new ArrayList<>();
AutoAdapter autoAdapter;
RecyclerView.LayoutManager horizontal;
List<Texts> list = new ArrayList();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatting_hole);
message_text = findViewById(R.id.message_text);
send_btn = findViewById(R.id.send_btn);
mic_button = findViewById(R.id.mic_btn);
setting_button = findViewById(R.id.setting_button);
chart_recycle = findViewById(R.id.chart_recycle);
chart_recycle.setHasFixedSize(true);
auto_texts = findViewById(R.id.auto_texts);
auto_texts.setHasFixedSize(true);
linearLayout = new LinearLayoutManager(getApplicationContext(), RecyclerView.VERTICAL, false);
chart_recycle.setLayoutManager(linearLayout);
//Auto text
horizontal = new LinearLayoutManager(getApplicationContext(),RecyclerView.HORIZONTAL, false);
auto_texts.setLayoutManager(horizontal);
chartsAdapter = new ChartsAdapter(modeClassesArrayList, Charts.this);
chart_recycle.setAdapter(chartsAdapter);
//Auto texts
autoAdapter = new AutoAdapter(getApplicationContext(),list);
auto_texts.setAdapter(autoAdapter);
addInputs();
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(Charts.this);
mic_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bottomSheetDialog.setContentView(R.layout.record);
bottomSheetDialog.show();
}
});
message_text.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().length()==0){
mic_button.setVisibility(View.VISIBLE);
send_btn.setVisibility(View.GONE);
}else {
send_btn.setVisibility(View.VISIBLE);
mic_button.setVisibility(View.GONE);
}
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().isEmpty()){
// Toast.makeText(getApplicationContext(),"Enter text",Toast.LENGTH_LONG).show();
mic_button.setVisibility(View.VISIBLE);
send_btn.setVisibility(View.GONE);
}else {
send_btn.setVisibility(View.VISIBLE);
mic_button.setVisibility(View.GONE);
}
}
#Override
public void afterTextChanged(Editable editable) {
if (editable.toString().length()==0){
mic_button.setVisibility(View.VISIBLE);
send_btn.setVisibility(View.GONE);
}
}
});
send_btn.setOnClickListener(view -> {
if (message_text.getText().toString().isEmpty()) {
Toast.makeText(Charts.this, "Please enter text..", Toast.LENGTH_SHORT).show();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
returnResponse(message_text.getText().toString());
}
message_text.setText("");
});
}
#SuppressLint("NotifyDataSetChanged")
private void returnResponse(String message) {
modeClassesArrayList.add(new ChartModeClass(message, USER_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size()-1);
String url = "http://xxxxxxxxxxxxxxxx"+message;
String BASE_URL = "https://xxxxxxxxx";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
Call<MessageModeClass> call = retrofitApi.getMessage(url);
call.enqueue(new Callback<MessageModeClass>() {
#Override
public void onResponse(#NonNull Call<MessageModeClass> call, #NonNull Response<MessageModeClass> response) {
if (response.isSuccessful()) {
MessageModeClass messageModeClass = response.body();
if (messageModeClass != null) {
modeClassesArrayList.add(new ChartModeClass(messageModeClass.getCnt(), BOT_KEY));
}
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
} else {
Toast.makeText(Charts.this, "response is null", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(#NonNull Call<MessageModeClass> call, #NonNull Throwable t) {
modeClassesArrayList.add(new ChartModeClass("No response check your network connection!", BOT_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
}
});
}
#SuppressLint("NotifyDataSetChanged")
#Override
protected void onStart() {
super.onStart();
String lang = getIntent().getExtras().getString("lang");
if (lang.equals("english")){
modeClassesArrayList.add(new ChartModeClass("Hey welcome back am fema bot", BOT_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
}else if (lang.equals("swahili")){
modeClassesArrayList.add(new ChartModeClass("Habari karibu miminni bot niliyetengenezw", BOT_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
}else {
modeClassesArrayList.add(new ChartModeClass("Hey welcome back am fema bot", BOT_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
}
}
private void addInputs() {
Texts text1 = new Texts("gender?");
Texts text2 = new Texts("gender equality");
Texts text3 = new Texts("what is good about females");
Texts text4 = new Texts("un goals");
Texts text5 = new Texts("about men");
list.addAll(Arrays.asList(new Texts[]{text1,text2,text3,text4,text5}));
}
}
here is my Adapter class class codes
public class AutoAdapter extends RecyclerView.Adapter<AutoAdapter.ViewHolderClass> {
Context context;
List<Texts> list;
public AutoAdapter(Context context, List<Texts> list) {
this.context = context;
this.list = list;
}
#NonNull
#Override
public ViewHolderClass onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.text_list,parent,false);
ViewHolderClass viewHolderClass = new ViewHolderClass(view);
return viewHolderClass;
}
#Override
public void onBindViewHolder(#NonNull ViewHolderClass holder, #SuppressLint("RecyclerView") int position) {
holder.input_text.setText(list.get(position).getText());
holder.input_text.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// my stack
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public class ViewHolderClass extends RecyclerView.ViewHolder {
TextView input_text;
public ViewHolderClass(#NonNull View itemView) {
super(itemView);
input_text = itemView.findViewById(R.id.input_text);
}
}
}
You can add a list of your recommendations in another RecyclerView
Then in the ViewHolder of each item of the RecyclerView add Callback to listen on click events when a user clicks one of the item like the following
public class ViewHolderClass extends RecyclerView.ViewHolder {
private TextView input_text;
private final Callback callback; // custom callback
public ViewHolderClass(#NonNull View itemView, Callback callback) {
super(itemView);
this.callback = callback;
input_text = itemView.findViewById(R.id.input_text);
// now add onClickListener of the itemView to fire custom callback
itemView.setOnClickListener(view -> {
this.callback.onItemClick(getAdapterPosition());
});
}
// this is my custom callback for return click event
public interface Callback {
void onItemClick(int position);
}
}
Now inside your adapter add the callback from viewholder
public class AutoAdapter extends RecyclerView.Adapter<AutoAdapter.ViewHolderClass> {
private Context context;
private List<Texts> list;
private AutoAdapterCallback callback;
public AutoAdapter(Context context, List<Texts> list) {
this.context = context;
this.list = list;
}
public setCallback(AutoAdapterCallback callback) {
this.callback = callback;
}
#NonNull
#Override
public ViewHolderClass onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.text_list,parent,false);
ViewHolderClass viewHolderClass = new ViewHolderClass(view, new ViewHolderClass.Callback() {
#Override
public void onItemClick(int position) {
// forward callback to adapter callback
if (callback != null) {
// get actual item from its position
final Texts texts = getItemByPosition(position);
// send to adapter callback
callback.onItemClick(texts);
}
});
return viewHolderClass;
}
#Override
public void onBindViewHolder(#NonNull ViewHolderClass holder, #SuppressLint("RecyclerView") int position) {
holder.input_text.setText(list.get(position).getText());
// I haven't used this inteady I added callback on viewholder side
// holder.input_text.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View view) {
// // my stack
// }
// });
}
#Override
public int getItemCount() {
return list.size();
}
// return Texts object by given position
public Texts getItemByPosition(int position) {
return this.list.get(position);
}
// add adapter callback to be called by viewholder
public interface AdapterCallback {
void onItemClick(Texts texts);
}
}
After that, now on your Activity you can easily listen on any item when a user clicks and get its corresponding Texts object from list as following:
//code ...
// here
//Auto texts
autoAdapter = new AutoAdapter(getApplicationContext(),list);
//set callback to listen for click events
autoAdapter.setCallback(new AutoAdapter.AutoAdapterCallback() {
#Override
public void onItemClick(Texts texts) {
// you can get your clicked item here
// now you can put texts object to another RecyclerView :)
}
});
auto_texts.setAdapter(autoAdapter);
//code ...

Populate details activity with Firebase Real Time Database after click on RecyclerView

i want to click in my recyclerview and open a new activity to show the datails. Ultil now i
have accomplished to open the activity and show the values "interno" and "siniiga" with the next intent. how can i get "madre and padre" values from firebase? applying the method to add father and mother, then I will use it for the rest of the values ​​that the xml shows. excuse my horrible code. if someone know a different method, let me know
attached code and images.
Main Activity
RecyclerView rv;
List<cow> vacas;
adapter adapter;
ImageButton mbuttoninf;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rv = (RecyclerView) findViewById(R.id.recyclerViewGirdView);
rv.setLayoutManager(new LinearLayoutManager(this));
vacas = new ArrayList<>();
FirebaseDatabase database = FirebaseDatabase.getInstance();
adapter = new adapter(vacas);
rv.setAdapter(adapter);
database.getReference("Vacas").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
vacas.removeAll(vacas);
for (DataSnapshot snapshot1 :
snapshot.getChildren()) {
cow vaca = snapshot1.getValue(cow.class);
vacas.add(vaca);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
cow
String interno;
String siniiga;
String ulr;
String madre;
String padre;
public cow() {
}
public cow(String interno, String siniiga, String ulr, String madre, String padre) {
this.interno = interno;
this.siniiga = siniiga;
this.ulr = ulr;
this.madre = madre;
this.padre = padre;
}
public String getInterno() {
return interno;
}
public void setInterno(String interno) {
this.interno = interno;
}
public String getSiniiga() {
return siniiga;
}
public void setSiniiga(String siniiga) {
this.siniiga = siniiga;
}
public String getUlr() {
return ulr;
}
public void setUlr(String ulr) {
this.ulr = ulr;
}
public String getMadre() {
return madre;
}
public void setMadre(String madre) {
this.madre = madre;
}
public String getPadre() {
return padre;
}
public void setPadre(String padre) {
this.padre = padre;
}
}
Adapter
List<cow> vacas;
Context context;
public adapter(List<cow> vacas) {
this.vacas = vacas;
}
#NonNull
#Override
public cowviewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_vaca,parent,false);
cowviewHolder holder = new cowviewHolder(v);
return holder;
}
#Override
public void onBindViewHolder(#NonNull final cowviewHolder holder, final int position) {
final cow vacaslist = vacas.get(position);
holder.textViewinterno.setText(String.valueOf(vacaslist.interno));
holder.textViewsiniiga.setText(String.valueOf(vacaslist.siniiga));
Glide.with(holder.imageviewrec.getContext()).load(vacaslist.getUlr()).into(holder.imageviewrec);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(v.getContext(),detailactivity.class);
intent.putExtra("keyint", vacaslist.getInterno());
intent.putExtra("keysin", vacaslist.getSiniiga());
v.getContext().startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return vacas.size();
}
public static class cowviewHolder extends RecyclerView.ViewHolder {
TextView textViewinterno, textViewsiniiga, tvmadre, tvpadre;
ImageView imageviewrec;
public cowviewHolder(#NonNull View itemView) {
super(itemView);
textViewinterno = itemView.findViewById(R.id.interno);
textViewsiniiga = itemView.findViewById(R.id.siniiga);
imageviewrec = itemView.findViewById(R.id.imgrec);
tvmadre = itemView.findViewById(R.id.tvmadre);
tvpadre = itemView.findViewById(R.id.tvpadre);
}
}
detailsactivity
TextView textView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.informationfire);
TextView tvinterno = (TextView) findViewById(R.id.tvinterno);
TextView tvsiniiga = (TextView) findViewById(R.id.tvsiniiga);
String vinterno = "";
String vsiniiga = "";
Bundle extras = getIntent().getExtras();
if (extras !=null);
vinterno = extras.getString("keyint");
vsiniiga = extras.getString("keysin");
tvinterno.setText(vinterno);
tvsiniiga.setText(vsiniiga);
}
}
firebase
enter image description here
and the xml for details
enter image description here
when you are getting data from firebase you saving that data in a Object and then add that object to list, so your list contains objects , so you can pass through the intents same way as you are doing others.
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(v.getContext(),detailactivity.class);
intent.putExtra("keyint", vacaslist.getInterno());
intent.putExtra("keysin", vacaslist.getSiniiga());
intent.putExtra("madre", vacaslist.getMadre());
intent.putExtra("padre", vacaslist.getPadre());
v.getContext().startActivity(intent);
}
});

RecyclerAdapter IndexOutOfBoundError on using CustomViewHolder

What i'm trying to do is that, I have an adapter which I'm using for many different activities each having their own ViewHolder. So I'm firstly making an abstract recycler adapter named DimRecyclerAbstractAdapter without a ViewHolder. Then for each different activity I'm making a static inner class named DimCustomAdapter which extends DimRecyclerAbstractAdapter having it's own ViewHolder. But I'm getting this error.
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:411)
This is the abstract adapter class -
public abstract class DimRecyclerAbstractAdapter<VHA extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VHA> {
private List<tbl_dim_1> mtbldimList1;
public DimRecyclerAbstractAdapter(List<tbl_dim_1> tblDimList1) {
this.mtbldimList1 = tblDimList1;
}
#Override
public int getItemCount() {
return mtbldimList1.size();
}
public void addItems(List<tbl_dim_1> tblDimList1) {
this.mtbldimList1 = tblDimList1;
notifyDataSetChanged();
}
#Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
mtbldimList1 = null;
super.onDetachedFromRecyclerView(recyclerView);
}
}
This is the activity in which I've implemented custom ViewHolder -
public class DetailActivity1 extends LifecycleActivity{
DimListViewModel dmvmodel;
RecyclerView rcView;
DimCustomAdapter rcAdapter;
public static final String LOG_TAG = "In DetailActivity1 ";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recycler_view);
Intent receivedIntent = getIntent();
int rid_int = receivedIntent.getIntExtra("mRId",0);
Log.v(LOG_TAG,"Rid value int == " + rid_int);
rcView = (RecyclerView) findViewById(R.id.recyclerView);
rcAdapter = new DimCustomAdapter(new ArrayList<tbl_dim_1>());
rcView.setLayoutManager(new LinearLayoutManager(DetailActivity1.this));
Log.v(LOG_TAG, "Layout manager set");
rcView.setAdapter(rcAdapter);
dmvmodel = ViewModelProviders.of(this).get(DimListViewModel.class);
Log.v(LOG_TAG, "View model returned");
dmvmodel.getDimList2con1(rid_int).observe(DetailActivity1.this, new Observer<List<tbl_dim_1>>() {
#Override
public void onChanged(#Nullable List<tbl_dim_1> changedItems) {
Log.v(LOG_TAG, "onChanged called, items will be added");
rcAdapter.addItems(changedItems);
}
});
}
#Override
protected void onDestroy() {
rcAdapter = null;
rcView.setAdapter(null);
rcView.setLayoutManager(null);
rcView = null;
dmvmodel = null;
super.onDestroy();
RefWatcher refWatcher = LeakCheckApplication.getRefWatcher(this);
refWatcher.watch(this);
}
public static class DimCustomAdapter extends DimRecyclerAbstractAdapter<DimCustomAdapter.RecyclerViewHolder> {
private static List<tbl_dim_1> mtbldimCustom;
DimCustomAdapter(List<tbl_dim_1> tblDimListPassed) {
super(mtbldimCustom);
mtbldimCustom = tblDimListPassed;
}
#Override
public DimCustomAdapter.RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View vw = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_item, parent, false);
// vw.setOnClickListener(vwOnClickListener);
return new DimCustomAdapter.RecyclerViewHolder(vw);
}
#Override
public void onBindViewHolder(final RecyclerViewHolder holder, int position) {
// Log.v(LOG_TAG, "Inside onBindViewHolder - ");
if (holder.dataTextView.getText() != null) {
String LOG_TAG = "DimCustomAdapter:";
Log.d(LOG_TAG, "holder is not null, i was right");
holder.dataTextView.setText(null);
holder.dataTextView.setOnClickListener(null);
}
final tbl_dim_1 dimAtPosition = mtbldimCustom.get(position);
holder.dataTextView.setText(dimAtPosition.mCONTENT);
holder.dataTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg) {
Intent dw = new Intent(arg.getContext(), DetailActivity2.class);
dw.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dw.putExtra("mRId", dimAtPosition.mR_ID);
arg.getContext().startActivity(dw);
}
});
}
class RecyclerViewHolder extends RecyclerView.ViewHolder {
private TextView dataTextView;
RecyclerViewHolder(View view) {
super(view);
dataTextView = (TextView) view.findViewById(R.id.data_text_view);
}
}
}
}
And this is how I'm calling this inner class from outer class within same activity -
DimCustomAdapter rcAdapter = new DimCustomAdapter(new ArrayList<tbl_dim_1>());
Its because of empty list that you are passing while creating the adapter.
DimCustomAdapter rcAdapter = new DimCustomAdapter(new ArrayList<tbl_dim_1>());
Just add a null or empty check in onBindViewHolder method before calling
final tbl_dim_1 dimAtPosition = mtbldimCustom.get(position);
Hope this will stop crashing your application.
You can try like below,
ArrayList<tbl_dim_1> list = new ArrayList<>()
rcAdapter = new DimCustomAdapter(list);
then in observe method,
dmvmodel.getDimList2con1(rid_int).observe(DetailActivity1.this, new Observer<List<tbl_dim_1>>() {
#Override
public void onChanged(#Nullable List<tbl_dim_1> changedItems) {
Log.v(LOG_TAG, "onChanged called, items will be added");
list.addAll(changedItems);
rcAdapter.notifyDataSetChanged()
}
});
This is the solution i worked out for my problem( In case anyone face the same problem ).
Modyfying Durga's answer -
Firstly i added the isEmpty() check that he mentioned in comment.
Then in the activity i changed the code to this -
a) Added this new method in DimCustomAdapter -
public void changeList(List<tbl_dim_1> addedList){
mtbldimCustom = addedList;
}
b) Called this method in observe method -
dmvmodel.getDimList2con1(rid_int).observe(DetailActivity1.this, new Observer<List<tbl_dim_1>>() {
#Override
public void onChanged(#Nullable List<tbl_dim_1> changedItems) {
Log.v(LOG_TAG, "onChanged called, items will be added");
rcAdapter.changeList(changedItems);
rcAdapter.addItems(changedItems);
}
});

Error in recyclerView

Can anyone check if there are errors in it. here my code, If there is any error in the code please tell me? I don't know how to fix the code Search.java.
in my RecyclerItemClickListener.java
public interface RecyclerItemClickListener {
void onItemClick(int position);
}
My Adapter HierAdapter.java
public class HireAdapter extends RecyclerView.Adapter<HireAdapter.ViewHolder>{
private ArrayList<HireItem> TeacherItemList;
private Context context;
private RecyclerItemClickListener itemClickListener;
public HireAdapter(Context c, ArrayList<HireItem> teacherItemList, RecyclerItemClickListener listener) {
TeacherItemList = teacherItemList;
context = c;
itemClickListener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder{
public final TextView nameText, subjectText,levelText ,cityText;
public ViewHolder(View itemView) {
super(itemView);
nameText = (TextView)itemView.findViewById(R.id.result_name);
subjectText = (TextView)itemView.findViewById(R.id.result_subject);
levelText = (TextView)itemView.findViewById(R.id.result_level);
cityText = (TextView)itemView.findViewById(R.id.result_city);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rowView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_teachers,parent,false);
final ViewHolder viewHolder = new ViewHolder(rowView);
rowView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
itemClickListener.onItemClick(viewHolder.getLayoutPosition());
}
});
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.nameText.setText(TeacherItemList.get(position).getResult_name());
holder.subjectText.setText(TeacherItemList.get(position).getResult_subject());
holder.levelText.setText(TeacherItemList.get(position).getResult_level());
holder.cityText.setText(TeacherItemList.get(position).getResult_city());
//Here it is simply write onItemClick listener here
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Context context = v.getContext();
Intent intent = new Intent(context, ProfileTeaAdapter.class);
context.startActivity(intent);
}
});
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public int getItemCount() {
return TeacherItemList.size();
}}
Here Search.java, I wrote notes at each error. Because I did not know how to correct some codes to work with HireAdapter and RecyclerItemClickListener, can anyone solve the error?
public class Search extends Fragment implements RecyclerItemClickListener {
private Context context;
private RecyclerView recyclerView;
private DatabaseReference databaseReference;
private FirebaseAuth firebaseAuth;
private List<HireItem> hireItem = new ArrayList<>();
HireAdapter mAdapter;
ImageView bt_search;
ProgressDialog progressDialog;
Spinner spinner_sort;
String key = "req_skill1";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_search,container,false);
//Getting FireBase Instance
firebaseAuth = FirebaseAuth.getInstance();
databaseReference = FirebaseDatabase.getInstance().getReference("teachers");
//Getting id of Views
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.rv_places);
recyclerView.setAdapter(mAdapter);
//
bt_search = (ImageView)view.findViewById(R.id.bt_search);
spinner_sort = (Spinner)view.findViewById(R.id.spinner_sort);
setupSpinner();
List<HireItem> hireItem = new ArrayList<>();
mAdapter = new HireAdapter(getContext(),R.layout.list_item_teachers,hireItem); // error at (getContext(),R.layout.list_item_teachers,hireItem)
bt_search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(mAdapter != null){
mAdapter.clear(); // error at .clear();
}
progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage("Searching Teachers");
progressDialog.show();
FirebaseDatabase.getInstance().getReference("teachers").orderByChild("subject").startAt(key).endAt(key + "~")
.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Teachers child = dataSnapshot.getValue(Teachers.class);
HireItem hireItem = new HireItem(child.teaname, child.city, child.subject, child.level, child.sex,child.mobile, child.qualification, child.skill1, child.experince, child.salary,child.age);
mAdapter.add(hireItem); // error at .add
progressDialog.dismiss();
if(mAdapter == null){
Toast.makeText(getContext(), "No Match Found", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
if(mAdapter == null){
Toast.makeText(getContext(), "No Match Found", Toast.LENGTH_SHORT).show();
}
else{
recyclerView.setAdapter(mAdapter); // error at recyclerView
}
}
});
return view;
}
private void setupSpinner(){
ArrayAdapter adapter = ArrayAdapter.createFromResource(getContext(),R.array.array_teacher_sort,
android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
spinner_sort.setAdapter(adapter);
spinner_sort.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
key = (String)adapterView.getItemAtPosition(i);
if(key.equals(getString(R.string.sort_A))){
key = "Math";
}else if(key.equals(getString(R.string.sort_AA))){
key = "computer";
}
else if(key.equals(getString(R.string.sort_AB))){
key = "Biology";
}
else if(key.equals(getString(R.string.sort_AD))){
key = "Physics";
}
else if(key.equals(getString(R.string.sort_AXX))){
key = "Holy Quran";
}
else if(key.equals(getString(R.string.sort_AZ))){
key = "Chysics";
}
else if(key.equals(getString(R.string.sort_AS))){
key = "English";
}
else if(key.equals(getString(R.string.sort_AQ))){
key = "Arabic";
}
else if(key.equals(getString(R.string.sort_ADD))){
key = "Science";
}
else if(key.equals(getString(R.string.sort_AE))){
key = "History";
}
else if(key.equals(getString(R.string.sort_AW))){
key = "Geograpghy";
}
else if(key.equals(getString(R.string.sort_AR))){
key = "Art education";
}
else if(key.equals(getString(R.string.sort_AT))){
key = "Family education";
}
else if(key.equals(getString(R.string.sort_aae))){
key = "Religion";
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
#Override
public void onResume() {
super.onResume();
mAdapter.clear(); // error at .clear();
}
#Override
public void onItemClick(int position) {
} }
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rowView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_teachers,parent,false);
final ViewHolder viewHolder = new ViewHolder(rowView);
rowView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
itemClickListener.onItemClick(viewHolder.getLayoutPosition());
}
});
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.nameText.setText(TeacherItemList.get(position).getResult_name());
holder.subjectText.setText(TeacherItemList.get(position).getResult_subject());
holder.levelText.setText(TeacherItemList.get(position).getResult_level());
holder.cityText.setText(TeacherItemList.get(position).getResult_city());
//Here it is simply write onItemClick listener here
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Context context = v.getContext();
Intent intent = new Intent(context, ProfileTeaAdapter.class);
context.startActivity(intent);
}
});
}
Here you are setting onClickListner on the same view twice. The Listener set in the onBindViewHolder will override the Listner set in the onCreateViewHolder method.

Categories

Resources