notifyDataSetChanged(); not working in android - android

This is my code.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.recycler_list, container, false);
recyclerView = (RecyclerView) v.findViewById(R.id.recycler_view);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 3);
adapter = new FragmentBrandList.MyAdapter(Utility.getBrandMap(), getActivity());
recyclerView.setAdapter(adapter);
// asynchronous call
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
Brand brand = dataSnapshot1.getValue(Brand.class);
brandMap.put(brand.getId(), brand);
}
Utility.setBrandMap(brandMap);
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
Utility.displayToast("Failed to read value." + error.toException());
}
});
return v;
}
Initially Utility.getBrandMap() is null. so noting is displaying. but in asynchronous call I am getting and updating the value and calling adapter.notifyDataSetChanged(); but still it doesn't update UI.
What is wrong here?
Edit: Adapter code
private class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Brand> brandList = new ArrayList<>();
private Context context;
public class MyViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
public MyViewHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.thumbnail);
}
}
public MyAdapter(Map<String, Brand> brands, Context context) {
//public MyAdapter(List<Brand> brands, Context context) {
this.brandList = new ArrayList<>(brandMap.values());
//this.brandList = brands;
this.context = context;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_brand, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if (brandList != null && brandList.size() > 0) {
Brand brand = brandList.get(position);
Glide.with(context).load(String.valueOf(brand.getImage()))
.error(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.into(holder.imageView);
}
}
#Override
public int getItemCount() {
return brandList.size();
}
}

Try this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.recycler_list, container, false);
recyclerView = (RecyclerView) v.findViewById(R.id.recycler_view);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 3);
adapter = new FragmentBrandList.MyAdapter(Utility.getBrandMap(), getActivity());
recyclerView.setAdapter(adapter);
// asynchronous call
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
Brand brand = dataSnapshot1.getValue(Brand.class);
brandMap.put(brand.getId(), brand);
}
adapter.setBrandMap(brandMap);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
Utility.displayToast("Failed to read value." + error.toException());
}
});
return v;
}
And in adapter code:
private class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Brand> brandList = new ArrayList<>();
private Context context;
public class MyViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
public MyViewHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.thumbnail);
}
}
public MyAdapter(Map<String, Brand> brands, Context context) {
//public MyAdapter(List<Brand> brands, Context context) {
this.brandList = new ArrayList<>(brandMap.values());
//this.brandList = brands;
this.context = context;
}
public void setBrandMap(Map<String, Brand> brandMap){
this.brandList = new ArrayList<>(brandMap.values());
notifyDataSetChanged();
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_brand, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if (brandList != null && brandList.size() > 0) {
Brand brand = brandList.get(position);
Glide.with(context).load(String.valueOf(brand.getImage()))
.error(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.into(holder.imageView);
}
}
#Override
public int getItemCount() {
return brandList.size();
}
}

You're passing an empty Map to the constructor of your MyAdapter. Once the asynchronous query is finished the Map is filled however the brandList in your adapter doesn't know anything about the new data. So what you want to do is to add the new items to the List inside the adapter.
Add the following method to the adapter:
public void addValues(Map<String, Brand> brands){
brandList.clear();
brandList.addAll(brands.values());
notifyDataSetChanged();
}
and call it once the asynchronous query is finished.

Related

E/RecyclerView: No adapter attached; skipping layout on recyclerview inside fragment

I have "E/RecyclerView: No adapter attached; skipping layout" error message.
I have recycleView inside fragment so I must have done something wrong on fragment1.java.
here is the code. I set adapter on the code as you can see, but I am getting this error. Any help would be appreciated. Thank you.
public class Fragment1 extends Fragment {
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private ArrayList<Bible> arrayList;
private FirebaseDatabase database;
private DatabaseReference databaseReference;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment1, container, false);
recyclerView = rootView.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
//GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 2);
layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
arrayList = new ArrayList<>();
database = FirebaseDatabase.getInstance();
databaseReference = database.getReference("Bible");
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
arrayList.clear();
for(DataSnapshot snapshot: dataSnapshot.getChildren()){
Bible bible = snapshot.getValue(Bible.class);
arrayList.add(bible);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.e("fragment1", String.valueOf(databaseError.toException()));//에러문 출력
}
});
adapter = new BibleAdapter(arrayList, getContext());
recyclerView.setAdapter(adapter);
return rootView;
}
}
public class BibleAdapter extends RecyclerView.Adapter {
private ArrayList<Bible> arrayList;
private Context context;
private OnVerseItemClickListener listener;
public BibleAdapter(ArrayList<Bible> arrayList, Context context) {
this.arrayList = arrayList;
this.context = context;
}
public void setOnItemClickListener(OnVerseItemClickListener listener){
this.listener = listener;
}
#NonNull
#Override
public BibleAdapter.BibleViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.verse_item, parent, false);
BibleViewHolder holder = new BibleViewHolder(view, listener);
return holder;
}
#Override
public void onBindViewHolder(#NonNull BibleAdapter.BibleViewHolder holder, int position) {
Glide.with(holder.imageView)
.load(arrayList.get(position).getImage())
.into(holder.imageView);
holder.bibleType.setText(arrayList.get(position).getBibleType());
holder.keysentance.setText(arrayList.get(position).getKeysentance());
holder.verse.setText(arrayList.get(position).getVerse());
}
#Override
public int getItemCount() {
return (arrayList!=null? arrayList.size():0);
}
public class BibleViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
TextView bibleType;
TextView verse;
TextView keysentance;
public BibleViewHolder(#NonNull View itemView, final OnVerseItemClickListener listener) {
super(itemView);
this.imageView = itemView.findViewById(R.id.imageView);
this.bibleType = itemView.findViewById(R.id.bibleType);
this.keysentance = itemView.findViewById(R.id.keysentance);
this.verse = itemView.findViewById(R.id.verse);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
if(listener != null){
listener.onItemClick(BibleViewHolder.this, v, position);
}
}
});
}
}
}
in your code you have create adapter with empty arrayList, but never after that you update the list.
in adapter create swapData() method and call it when you have to refresh data or have refreshed data, in your case you will get it in onDataChange().
And also define adapter before adding listener:
adapter = new BibleAdapter(arrayList, getContext());
recyclerView.setAdapter(adapter);
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
arrayList.clear();
for(DataSnapshot snapshot: dataSnapshot.getChildren()){
Bible bible = snapshot.getValue(Bible.class);
arrayList.add(bible);
}
adapter.swapData(arrayList);
//adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.e("fragment1", String.valueOf(databaseError.toException()));//에러문 출력
}
});
in adapter class create method as:
public void swapData(ArrayList<Bible> filtersList) {
if (filtersList != null) {
this.arrayList.clear();
this.arrayList.addAll(filtersList);
notifyDataSetChanged();
}
}

Firebase Recycleview duplicate images

I am developing an app which retrieves images from Firebase. I have retrieved all the images from Firebase successfully but when I select some image as a favorite, it duplicate all the selected images twice or thrice in the new activity in RecyclerView. Please help me anyone. Thanks in advance..
Here is my code.
public class Fragment3 extends Fragment {
ArrayList<String> ImagesList = (ArrayList) (ListofData.FavoriteList = new ArrayList<>());
Set<String> hashset = new HashSet<String>(ImagesList);
RecyclerView recyclerView;
FragThreeAdapter adapter;
public Fragment3() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_fragment3, container, false);
FirebaseHandler firebaseHandler = new FirebaseHandler(getActivity());
firebaseHandler.getFavoriteUrlRef().addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot d : dataSnapshot.getChildren()) {
String images = d.getValue().toString();
ImagesList.add(images);
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
ArrayList<String> Images = new ArrayList<>(hashset);
recyclerView = view.findViewById(R.id.frag3_fav_recyclerView);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
adapter = new FragThreeAdapter(Images, getActivity());
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
return view;
}
}
My Click Listener
favoriteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(activity, "saved to favorite", Toast.LENGTH_SHORT).show();
reference = FirebaseDatabase.getInstance().getReference().child("Favorite");
String key = reference.push().getKey();
reference.child(key).setValue(imagePaths.get(position));
My Adapter Class
public class FragThreeAdapter extends RecyclerView.Adapter<FragThreeAdapter.myHolder> {
private List<String> list;
private Context context;
public FragThreeAdapter(List<String> list, Context context) {
this.list = list;
this.context = context;
}
#NonNull
#Override
public myHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater= LayoutInflater.from(context);
View view= inflater.inflate(R.layout.list_item,parent,false);
return new myHolder(view);
}
#Override
public void onBindViewHolder(#NonNull myHolder holder, int position) {
Glide.with(context)
.load(list.get(position))
.into(holder.imageView);
holder.imageView.setOnClickListener(new OnImageClickListner(position));
}
#Override
public int getItemCount() {
return list.size();
}
public class myHolder extends RecyclerView.ViewHolder{
ImageView imageView;
public myHolder(View itemView) {
super(itemView);
imageView= itemView.findViewById(R.id.imageView_id);
}
}
class OnImageClickListner implements View.OnClickListener{
int position;
public OnImageClickListner(int position){
this.position= position;
}
#Override
public void onClick(View v) {
Intent intent= new Intent(context,Frag3_Favrit_FullActvity.class);
intent.putExtra("array_position",position);
intent.putStringArrayListExtra("list", (ArrayList<String>) list);
context.startActivity(intent);
}
}
}
You can try to make like this:
public void onBindViewHolder(#NonNull myHolder holder, int position) {
if (list.get(position) != null) {
Glide.with(context)
.load(list.get(position))
.into(holder.imageView);
} esle {
holder.imageView.setImageResource(R.mipmap.some_default_cover);
}
holder.imageView.setOnClickListener(new OnImageClickListner(position));
}

RecyclerView In Fragment Not Working (Unable to add data to it)

Here is my fragment
public class TransactionsFragment extends Fragment {
private FirebaseAuth mAuth;
private DatabaseReference mDBref;
FirebaseUser Fuser;
private String UID;
private RecyclerView recyclerView;
private RecyclerView.Adapter trpAdapter;
private List<TransGetterSetter> DataList;
String trans_id;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_transactions, container, false);
DataList = new ArrayList<>();
recyclerView = (RecyclerView) v.findViewById(R.id.RVList);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
TransactionRVAdapter trvAdapter = new TransactionRVAdapter(DataList, getContext());
recyclerView.setAdapter(trvAdapter);
mAuth = FirebaseAuth.getInstance();
mDBref = FirebaseDatabase.getInstance().getReference();
Fuser = mAuth.getInstance().getCurrentUser();
UID = Fuser.getUid();
mDBref.child("transactions").child(UID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot chidSnap : dataSnapshot.getChildren()) {
trans_id = chidSnap.getKey();
DataList.add(new TransGetterSetter("" + trans_id));
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
trvAdapter.notifyDataSetChanged();
return v;
}
}
If i toast "trans_id" string im getting expected result.
Here is My Adapter class
public class TransactionRVAdapter extends RecyclerView.Adapter<TransactionRVAdapter.rvViewHolder> {
Context mContext;
List<TransGetterSetter> DataList = new ArrayList<>();
public class rvViewHolder extends RecyclerView.ViewHolder{
private TextView TransId;
public rvViewHolder(#NonNull View itemView) {
super(itemView);
TransId = (TextView) itemView.findViewById(R.id.TransIdTxt);
}
}
public TransactionRVAdapter( List<TransGetterSetter> DataList,Context mContext){
this.DataList = DataList;
this.mContext = mContext;
}
#NonNull
#Override
public rvViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.fragment_transactions_item, viewGroup, false);
return new rvViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull rvViewHolder rvViewHolder, int i) {
rvViewHolder.TransId.setText(DataList.get(i).getTrans_id());
}
#Override
public int getItemCount() {
return DataList.size();
}
}
Here is my GetterSetter class
public class TransGetterSetter {
private String trans_id;
public TransGetterSetter() {
}
public TransGetterSetter(String trans_id) {
this.trans_id = trans_id;
}
public String getTrans_id() {
return trans_id;
}
public void setTrans_id(String trans_id) {
this.trans_id = trans_id;
}
}
Im able to get Data from firebase, but when i try to add it to recycler view it dosen't show any data. Recycler view is showing empty. I checked my code many time but haven't found solution.
You should call :
trvAdapter.notifyDataSetChanged();
After the for loop inside the (onDataChange) event listener.
Try to called ..
DataList.add(new TransGetterSetter("" + trans_id));
after this line called ..
trvAdapter.notifyDataSetChanged();

RecyclerView dosent show any elements following is my code

Fragment_bookmovie2.java
public class Fragment_bookmovie2 extends android.support.v4.app.Fragment implements View.OnClickListener {
private static final String TAG ="Fragment_bookmovie2" ;
ArrayList<String> moviename= new ArrayList<>();
ArrayList<String> movieyear= new ArrayList<>();
ArrayList<String> moviebanner= new ArrayList<>();
private RecyclerView.LayoutManager layoutManager;
private static RecyclerView recyclerView;
Movie_listAdapter2 adapter ;
LinearLayout progress;
RelativeLayout ll;
public Fragment_bookmovie2() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Log.e(TAG,"reched on create");
// first step - retrieve object
Backendless.Persistence.of(Booking.class).find(new AsyncCallback<BackendlessCollection<Booking>>() {
#Override
public void handleResponse(BackendlessCollection<Booking> response) {
for(Booking booking : response.getData()) {
if(!moviename.contains(booking.getMovie().get(0).getMovie_Name())) {
moviename.add(booking.getMovie().get(0).getMovie_Name());
movieyear.add(booking.getMovie().get(0).getYear());
moviebanner.add("https://api.backendless.com/" + BackendSetting.APPLICATION_ID + "/" + BackendSetting.VERSION + "/files/mypics/" + booking.getMovie().get(0).getImage());
}
}
adapter.notifyDataSetChanged();
ll.removeView(progress);
}
#Override
public void handleFault(BackendlessFault fault) {
Toast.makeText(getActivity(), fault.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
moviename.add("haha");
movieyear.add("hello");
moviebanner.add("http://www.w3schools.com/css/trolltunga.jpg");
// Inflate the layout for this fragment
ll = (RelativeLayout) inflater.inflate(R.layout.fragment_bookmovie2, container, false);
progress = (LinearLayout) ll.findViewById(R.id.progress_bookingFrag);
recyclerView = (RecyclerView) ll.findViewById(R.id.recycle_movielist);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new Movie_listAdapter2(getActivity(),moviename,movieyear,moviebanner);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
return ll;
}
#Override
public void onClick(View view) {
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onResume() {
super.onResume();
}
/*#Override
public void onButtonClickListnerProceed(Integer pos) {
Intent booking_screen_redirect = new Intent(getActivity(), BookingScreen2.class);
booking_screen_redirect.putExtra("movie_name",moviename.get(pos));
this.onPause();
startActivity(booking_screen_redirect);
getActivity().overridePendingTransition(R.anim.pull_in_right, R.anim.push_out_left);
}*/
}
Movie_listAdapter2.java
public class Movie_listAdapter2 extends RecyclerView.Adapter<Movie_listAdapter2.Movie_cards>{
final static String TAG="Movie_listAdapter2";
Context context_external;
ArrayList<String> moviename=new ArrayList<>();
ArrayList<String> movieyear=new ArrayList<>();
ArrayList<String> banner=new ArrayList<>();
public Movie_listAdapter2(Context context,ArrayList<String> resource, ArrayList<String> resource1, ArrayList<String> resource2) {
//set the context and the format of the layout inside the list item
//i.e R.layout.movie_list_adapter
//also the resource i.e the item names in an ArrayList
this.moviename = resource;
this.movieyear = resource1;
this.banner = resource2;
this.context_external=context;
Log.e(TAG,"size = "+movieyear.size()+" "+moviename.size());
}
public static class Movie_cards extends RecyclerView.ViewHolder {
CardView cv;
TextView movie_name;
TextView movie_year;
Button proceed;
ImageView movie_banner;
public Movie_cards(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.movie_list_card);
movie_name = (TextView)itemView.findViewById(R.id.tv_card_moviename);
movie_year = (TextView)itemView.findViewById(R.id.tv_card_movieyear);
movie_banner = (ImageView)itemView.findViewById(R.id.card_moviebanner);
proceed = (Button) itemView.findViewById(R.id.b_card_proceed);
}
}
#Override
public Movie_cards onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_list_card, parent, false);
Movie_cards pvh = new Movie_cards(v);
return pvh;
}
public void updateData(ArrayList<String> resource, ArrayList<String> resource1, ArrayList<String> resource2) {
this.moviename = resource;
this.movieyear = resource1;
this.banner = resource2;
notifyDataSetChanged();
}
#Override
public void onBindViewHolder(final Movie_cards holder, final int position) {
holder.movie_name.setText(moviename.get(position));
holder.movie_year.setText(movieyear.get(position));
Picasso.with(context_external)
.load(banner.get(position))
.placeholder(R.drawable.placeholder)
.networkPolicy(NetworkPolicy.OFFLINE)
.error(R.drawable.placeholder)
.fit()
.into(holder.movie_banner, new Callback() {
#Override
public void onSuccess() {
//i.e image was loaded from cache
}
#Override
public void onError() {
//image was downloaded as it wasn't available in cache
Picasso.with(context_external)
.load(banner.get(position))
.placeholder(R.drawable.placeholder)
.error(R.drawable.warning)
.fit()
.into(holder.movie_banner);
}
});
holder.proceed.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Intent booking_screen_redirect = new Intent(context_external, BookingScreen2.class);
booking_screen_redirect.putExtra("movie_name",moviename.get(position));
context_external.startActivity(booking_screen_redirect);
//overridePendingTransition(R.anim.pull_in_right, R.anim.push_out_left);
}
});
}
#Override
public int getItemCount() {
return 0;
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
}
the fragment displays empty and no items appear even though i have added the data to arraylists and passed to the adapter. please help . thanks in advance
Problem is in below code you are returning 0 that's why its not showing any item
#Override
public int getItemCount() {
return 0;
}
You should return your list's size here either moviename.size(); or movieyear.size()

Custom methods in adapter are not resolving in android

I have 2 methods inside of adapter class.
addValues(brandMap);
setBrandMap(brandMap);
that I'm trying to call after async call. However, the compiler is complaining that it cannot resolve these methods. What is the issue?
This is complete class.
public class FragmentBrandList extends ListFragment {
private String TAG = getClass().getSimpleName();
private Map<String, Brand> brandMap = new ConcurrentHashMap<>();
private RecyclerView.Adapter adapter;
private FirebaseDatabase database = FirebaseDatabase.getInstance();
private RecyclerView recyclerView;
private Query query = database.getReference("brands").orderByChild("name");
public FragmentBrandList() {
}
public static FragmentBrandList newInstance(int num) {
FragmentBrandList f = new FragmentBrandList();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.recycler_list, container, false);
recyclerView = (RecyclerView) v.findViewById(R.id.recycler_view);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 3);
RecyclerView.setLayoutManager(mLayoutManager);
adapter = new FragmentBrandList.MyAdapter(Utility.getBrandMap(), getActivity());
recyclerView.setAdapter(adapter);
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
Brand brand = Utility.getBrands().get(position);
Intent intent = new Intent(getActivity(), ActivityProductList.class);
intent.putExtra("BrandId", brand.getId());
startActivity(intent);
}
#Override
public void onLongClick(View view, int position) {
}
}));
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
Brand brand = dataSnapshot1.getValue(Brand.class);
brandMap.put(brand.getId(), brand);
}
Utility.setBrandMap(brandMap);
adapter.addValues(brandMap);
adapter.setBrandMap(brandMap);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
Utility.displayToast("Failed to read value." + error.toException());
}
});
return v;
}
Adapter class
private class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Brand> brandList = new ArrayList<>();
private Context context;
public class MyViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
public MyViewHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.thumbnail);
}
}
public MyAdapter(Map<String, Brand> brands, Context context) {
//public MyAdapter(List<Brand> brands, Context context) {
this.brandList = new ArrayList<>(brandMap.values());
//this.brandList = brands;
this.context = context;
}
public void setBrandMap(Map<String, Brand> brandMap){
this.brandList = new ArrayList<>(brandMap.values());
notifyDataSetChanged();
}
public void addValues(Map<String, Brand> brands){
brandList.clear();
brandList.addAll(brands.values());
notifyDataSetChanged();
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_brand, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if (brandList != null && brandList.size() > 0) {
Brand brand = brandList.get(position);
Glide.with(context).load(String.valueOf(brand.getImage()))
.error(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.into(holder.imageView);
}
}
#Override
public int getItemCount() {
return brandList.size();
}
}
You have declared your adapter field as:
private RecyclerView.Adapter adapter;
That means wherever you use it, you'll see it as just a RecyclerView.Adapter, which doesn't have your custom methods on it. It doesn't matter that you've assigned there a subclass of RecyclerView.Adapter that has extra methods. It is because you might've assigned there a different subclass that didn't have those methods.
If you want to use your custom methods then change the declaration to:
private MyAdapter adapter;
Then you can use all methods declared in MyAdapter and inherited from superclasses. The tradeoff is that you cannot assign there any other subclass of RecyclerView.Adapter, but thanks to that compiler can know you can always use your extra methods.
The problem is this line.
private RecyclerView.Adapter adapter;
As you are holding your custom adapter object in the Base reference, hence those methods of your custom adapter is not visible to you. Change the reference to the type of your Custom Adapter and it should work fine.

Categories

Resources