Firebase Database not retrieving in emulator/device - java

Firebase database screenshot link
I Cannot retrieve the data in a device this is wallpaper app
I have updated the google play services also but nothing happens.
I have also given the internet permission.
I have also tested on the emulator and a physical device.
Firebase database screenshot link on top.
CategoryFragment.java
public class CategoryFragment extends Fragment {
FirebaseDatabase database;
DatabaseReference categoryBackground;
//Firebase UI adpter
FirebaseRecyclerOptions<CategoryItem> options;
FirebaseRecyclerAdapter<CategoryItem, CategoryViewHolder> adapter;
//View
RecyclerView recyclerView;
private static CategoryFragment INSTANCE=null;
public CategoryFragment() {
database = FirebaseDatabase.getInstance();
categoryBackground =
database.getReference(Common.STR_CATEGORY_BACKGROUND);
options = new FirebaseRecyclerOptions.Builder<CategoryItem>()
.setQuery(categoryBackground, CategoryItem.class)
.build();
adapter = new FirebaseRecyclerAdapter<CategoryItem, CategoryViewHolder>
(options) {
#Override
protected void onBindViewHolder(#NonNull final CategoryViewHolder
holder, int position, #NonNull final CategoryItem model) {
Picasso.with(getActivity())
.load(model.getImageLink())
.networkPolicy(NetworkPolicy.OFFLINE)
.into(holder.background_image, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
//Try again if cache failed to load
Picasso.with(getActivity())
.load(model.getImageLink())
.error(R.drawable.ic_terrain_black_24dp)
.into(holder.background_image, new
Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Log.e("ERROR_MSU", "Couldn't
fetch image");
}
});
}
});
holder.category_name.setText(model.getName());
holder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position) {
//Code later for detail category
}
});
}
#Override
public CategoryViewHolder onCreateViewHolder(ViewGroup parent, int
viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_category_item,parent,false);
return new CategoryViewHolder(itemView);
}
};
}
public static CategoryFragment getInstance()
{
if(INSTANCE == null)
INSTANCE = new CategoryFragment();
return INSTANCE;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_category, container,
false);
recyclerView = (RecyclerView)view.findViewById(R.id.recycler_category);
recyclerView.setHasFixedSize(true);
GridLayoutManager gridLayoutManager = new
GridLayoutManager(getActivity(),2);
recyclerView.setLayoutManager(gridLayoutManager);
setCategory();
return view;
}
private void setCategory() {
adapter.startListening();
recyclerView.setAdapter(adapter);
}
#Override
public void onStart() {
super.onStart();
if (adapter!=null)
adapter.startListening();
}
#Override
public void onStop() {
if (adapter!=null)
adapter.stopListening();
super.onStop();
}
#Override
public void onResume() {
super.onResume();
if (adapter!=null)
adapter.stopListening();
}
}
CategoryItem.java
public class CategoryItem {
public String name;
public String imageLink;
public CategoryItem() {
}
public CategoryItem(String name, String imageLink){
this.name = name;
this.imageLink = imageLink;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImageLink() {
return imageLink;
}
public void setImageLink(String imageLink) {
this.imageLink = imageLink;
}
}
CategoryViewHolder
public class CategoryViewHolder extends RecyclerView.ViewHolder implements
View.OnClickListener {
public TextView category_name;
public ImageView background_image;
ItemClickListener itemClickListener;
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
public CategoryViewHolder(View itemView) {
super(itemView);
background_image = (ImageView)itemView.findViewById(R.id.image);
category_name = (TextView)itemView.findViewById(R.id.name);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v){
itemClickListener.onClick(v,getAdapterPosition());
}
}

Related

Nested RecycleView with Firebase this error "Expected a List while deserializing, but got a class java.util.HashMap" when I insert data using push()

This is the code for the nested recycler view.
If I add data using the push() method, i get the Nested RecycleView with Firebase this error:
Expected a List while deserializing, but got a class java.util.HashMap
AlertDialog dialog;
IFirebaseLoadListener iFirebaseLoadListener;
RecyclerView my_recycler_view;
DatabaseReference myData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myData= FirebaseDatabase.getInstance().getReference("MyData");
dialog= new SpotsDialog.Builder().setContext(this).build();
iFirebaseLoadListener = this;
// view
my_recycler_view= (RecyclerView)findViewById(R.id.my_recycler_view);
my_recycler_view.setHasFixedSize(true);
my_recycler_view.setLayoutManager(new LinearLayoutManager(this));
load data
getFirebaseData();
}
private void getFirebaseData() {
dialog.show();
myData.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
List<itemGroup> itemGroups= new ArrayList<>();
for(DataSnapshot groupSnapshot: dataSnapshot.getChildren())
{
itemGroup itemGroup= new itemGroup();
///
Firebase instance code
///
itemGroup.setHeaderTitle(groupSnapshot.child("headerTitle").getValue(true).toString());
GenericTypeIndicator<ArrayList<itemData>> genericTypeIndicator= new GenericTypeIndicator<ArrayList<itemData>>(){} ;
itemGroup.setListItem(groupSnapshot.child("listItem").child(key).getValue(genericTypeIndicator));
itemGroups.add(itemGroup);
}
iFirebaseLoadListener.onFirebaseLoadSuccess(itemGroups);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
iFirebaseLoadListener.onFirebaseLoadFailed(databaseError.getMessage());
}
});
}
#Override
public void onFirebaseLoadSuccess(List<itemGroup> itemGroupList) {
MyItemGroupAdapter adapter = new MyItemGroupAdapter(this,itemGroupList);
my_recycler_view.setAdapter(adapter);
dialog.dismiss();
}
#Override
public void onFirebaseLoadFailed(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
}
public class itemData {
private String name ,image;
public itemData() {
}
public itemData(String name, String image) {
this.name = name;
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
public class itemGroup {
private String headerTitle;
private ArrayList<itemData> listItem;
public itemGroup() {
}
public itemGroup(String headerTitle, ArrayList<itemData> listItem) {
this.headerTitle = headerTitle;
this.listItem = listItem;
}
public String getHeaderTitle() {
return headerTitle;
}
public void setHeaderTitle(String headerTitle) {
this.headerTitle = headerTitle;
}
public ArrayList<itemData> getListItem() {
return listItem;
}
public void setListItem(ArrayList<itemData> listItem) {
this.listItem = listItem;
}
}
public class MyItemAdapter extends RecyclerView.Adapter<MyItemAdapter.MyViewHolder> {
private Context context;
private List<itemData> itemDataList;
public MyItemAdapter(Context context, List<itemData> itemDataList) {
this.context = context;
this.itemDataList = itemDataList;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView =
LayoutInflater.from(context).inflate(R.layout.layout_item,viewGroup,false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.txt_item_titles.setText(itemDataList.get(i).getName());
Picasso.get().load(itemDataList.get(i).getImage()).into(myViewHolder.img_item);
myViewHolder.setiItemClickListener(new IItemClickListener() {
#Override
public void onItemClickListener(View view, int i) {
Toast.makeText(context, ""+ itemDataList.get(i).getName(),
Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return (itemDataList != null ? itemDataList.size() : 0);
}
public class MyViewHolder extends RecyclerView.ViewHolder implements
View.OnClickListener {
TextView txt_item_titles;
ImageView img_item;
IItemClickListener iItemClickListener;
public void setiItemClickListener(IItemClickListener iItemClickListener) {
this.iItemClickListener = iItemClickListener;
}
public MyViewHolder (View itemView ){
super(itemView);
txt_item_titles= (TextView)itemView.findViewById(R.id.tvTitle);
img_item= (ImageView) itemView.findViewById(R.id.itemImage);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
iItemClickListener.onItemClickListener(v,getAdapterPosition());
}
}
}
public class MyItemGroupAdapter extends
RecyclerView.Adapter<MyItemGroupAdapter.MyViewHolder> {
private Context context;
private List<itemGroup> dataList;
public MyItemGroupAdapter(Context context, List<itemGroup> dataList) {
this.context = context;
this.dataList = dataList;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView =
LayoutInflater.from(context).inflate(R.layout.layout_group,viewGroup,false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder myViewHolder, int i) {
myViewHolder.item_title.setText(dataList.get(i).getHeaderTitle());
List<itemData> itemData = dataList.get(i).getListItem();
MyItemAdapter itemListAdapter=new MyItemAdapter(context,itemData);
myViewHolder.recycler_view_item_list.setHasFixedSize(true);
myViewHolder.recycler_view_item_list.setLayoutManager(new
LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL,false));
myViewHolder.recycler_view_item_list.setAdapter(itemListAdapter);
myViewHolder.recycler_view_item_list.setNestedScrollingEnabled(false);
// btn more
myViewHolder.btn_more.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "Button More "+ myViewHolder.item_title.getText(),
Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return (dataList != null ? dataList.size() : 0);
}
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView item_title ;
RecyclerView recycler_view_item_list;
Button btn_more;
public MyViewHolder (View itemView ){
super (itemView);
item_title= (TextView) itemView.findViewById(R.id.itemTitle);
btn_more= (Button)itemView.findViewById(R.id.btMore);
recycler_view_item_list=
(RecyclerView)itemView.findViewById(R.id.recycler_view_list);
}
}
}
This happens when you try to have a structure like this in the database:
"list": {
"-Nasdueqriyew": "First value",
"-Nberqiy39esd": "Second value",
"-Nc3hadsiuhad": "Third value"
}
And then try to map it to a List or array in your Java class.
The JSON structure is not a list, because it was pairs of keys and values, which in Java translates to:
Map<String, Object>
So most likely, the List<itemData> in your code needs to be a Map<String, itemData>.

How can I get a variable from RecyclerView Adapter passed to MainActivity?

I was just playing around with some code, learning new things, when I ran into this problem... I'm trying to pass a variable from my RecylcerViewAdapter to a method in MainActivity, but I just can't seem to accomplish it.
I tried a lot of different thing with interfaces and casting, but nothing did the trick. Since I'm fairly new to all of this, maybe I'm making a trivial mistake somewhere?
My Interface:
public interface AdapterCallback {
void onMethodCallback(int id);
}
This is my adapter class:
public class PostAdapter extends RecyclerView.Adapter<PostAdapter.ViewHolder> {
private List<Post> postList;
private Context context;
private AdapterCallback listener;
public PostAdapter() {
}
public PostAdapter(List<Post> postList, Context context) {
this.postList = postList;
this.context = context;
}
public void setListener(AdapterCallback listener) {
this.listener = listener;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_layout, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, final int position) {
viewHolder.tvTitle.setText(postList.get(position).getTitle());
viewHolder.tvBody.setText(new StringBuilder(postList.get(position).getBody().substring(0, 20)).append("..."));
viewHolder.tvId.setText(String.valueOf(postList.get(position).getUserId()));
viewHolder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = postList.get(position).getId();
if (listener != null) {
listener.onMethodCallback(id);
}
}
});
}
#Override
public int getItemCount() {
return postList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvTitle;
TextView tvBody;
TextView tvId;
LinearLayout parentLayout;
public ViewHolder(View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tvTitle);
tvBody = itemView.findViewById(R.id.tvBody);
tvId = itemView.findViewById(R.id.tvId);
parentLayout = itemView.findViewById(R.id.parentLayout);
}
}
}
And my MainActivity:
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivityLog";
private CompositeDisposable disposable = new CompositeDisposable();
#BindView(R.id.rvPosts)
RecyclerView rvPosts;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
rvPosts.setHasFixedSize(true);
rvPosts.setLayoutManager(new LinearLayoutManager(this));
populateList();
logItems();
}
private void populateList() {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeQuery().observe(MainActivity.this, new Observer<List<Post>>() {
#Override
public void onChanged(#Nullable List<Post> posts) {
PostAdapter adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
}
});
}
public void logItems() {
PostAdapter adapter = new PostAdapter();
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeSingleQuery(id).observe(MainActivity.this, new Observer<Post>() {
#Override
public void onChanged(#Nullable final Post post) {
Log.d(TAG, "onChanged: data response");
Log.d(TAG, "onChanged: " + post);
}
});
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
disposable.clear();
}
}
The populateList() method works just fine, but the logItems() method is the problem.
So when i click on a view in RecyclerView I expect the log to output the title, description and ID of the post that was clicked. nut nothing happens...
So, any help would be appreciated.
Make adapter global variable i.e. a field. Use the same object to set every properties.
private PostAdapter adapter;
Replace your logItems method with this:
public void logItems() {
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeSingleQuery(id).observe(MainActivity.this, new Observer<Post>() {
#Override
public void onChanged(#Nullable final Post post) {
Log.d(TAG, "onChanged: data response");
Log.d(TAG, "onChanged: " + post);
}
});
}
});
}
And populateList with this:
private void populateList() {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeQuery().observe(MainActivity.this, new Observer<List<Post>>() {
#Override
public void onChanged(#Nullable List<Post> posts) {
adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
logItems();
}
});
}
And don't call logItems() from onCreate
This is how I implement with my ListAdapters:
public class FeedbackListAdapter extends RecyclerView.Adapter<FeedbackListAdapter.ViewHolder> {
private final ArrayList<Feedback> feedbacks;
private View.OnClickListener onItemClickListener;
private View.OnLongClickListener onItemLongClickListener;
private final Context context;
public FeedbackListAdapter(ArrayList<Feedback> feedbacks, Context context) {
this.feedbacks = feedbacks;
this.context = context;
}
public void setItemClickListener(View.OnClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public void setOnItemLongClickListener(View.OnLongClickListener onItemLongClickListener){
this.onItemLongClickListener = onItemLongClickListener;
}
public class ViewHolder extends RecyclerView.ViewHolder{
final TextView feedback, created, updated;
final LinearLayout mainLayout;
ViewHolder(View iv) {
super(iv);
/*
* Associate layout elements to Java declarations
* */
mainLayout = iv.findViewById(R.id.main_layout);
feedback = iv.findViewById(R.id.feedback);
created = iv.findViewById(R.id.created_string);
updated = iv.findViewById(R.id.updated_string);
}
}
#Override
public int getItemCount() {
return feedbacks.size();
}
#Override
#NonNull
public FeedbackListAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_feedback_table_row, parent, false);
return new FeedbackListAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(final #NonNull FeedbackListAdapter.ViewHolder holder, final int position) {
/*
* Bind data to layout
* */
try{
Feedback feedback = feedbacks.get(position);
holder.feedback.setText(feedback.getContent());
holder.created.setText(feedback.getCreated());
holder.updated.setText(feedback.getUpdated());
holder.mainLayout.setOnClickListener(this.onItemClickListener);
holder.mainLayout.setOnLongClickListener(this.onItemLongClickListener);
holder.mainLayout.setTag(feedback.getDbID());
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
holder.mainLayout.setBackgroundResource(outValue.resourceId);
}catch(IndexOutOfBoundsException e){
e.printStackTrace();
}
}
}
In onPopulateList you create an adaptor:
PostAdapter adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
However in public void logItems() { you used a different adapter
PostAdapter adapter = new PostAdapter();
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
...
}
});
Therefore the list is being populated with 1 adapter, but you are setting the listener on an unused second adapter.
The fix is to use the same adapter for both. If you make the adapater a field, and don't create a new one inside of logItems, but just set your listener it should work.
i.e.
// as a field in your class
private PostAdapter adapter;
then
// in `populateList()`
adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
and
// in `logItems()`
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
...
}
});
In Adapter
public class CustomerListAdapter extends RecyclerView.Adapter<CustomerListAdapter.OrderItemViewHolder> {
private Context mCtx;
ProgressDialog progressDialog;
//we are storing all the products in a list
private List<CustomerModel> customeritemList;
public CustomerListAdapter(Context mCtx, List<CustomerModel> orderitemList) {
this.mCtx = mCtx;
this.customeritemList = orderitemList;
progressDialog = new ProgressDialog(mCtx);
}
#NonNull
#Override
public OrderItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.activity_customer_list, null);
return new OrderItemViewHolder(view, mCtx, customeritemList);
}
#Override
public void onBindViewHolder(#NonNull OrderItemViewHolder holder, int position) {
CustomerModel customer = customeritemList.get(position);
try {
//holder.textViewPINo.setText("PINo \n"+Integer.toString( order.getPINo()));
holder.c_name.setText(customer.getCustomerName());
holder.c_address.setText(customer.getAddress());
holder.c_contact.setText(customer.getMobile());
holder.i_name.setText(customer.getInteriorName());
holder.i_contact.setText(customer.getInteriorMobile());
holder.i_address.setText(customer.getAddress());
} catch (Exception E) {
E.printStackTrace();
}
}
#Override
public int getItemCount() {
return customeritemList.size();
}
class OrderItemViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener {
AlertDialog.Builder alert;
private Context mCtx;
TextView c_name, c_contact, c_address, i_name, i_contact, i_address;
TextView OrderItemID, MaterialType, Price2, Qty, AQty;
//we are storing all the products in a list
private List<CustomerModel> orderitemList;
public OrderItemViewHolder(View itemView, Context mCtx, List<CustomerModel> orderitemList) {
super(itemView);
this.mCtx = mCtx;
this.orderitemList = orderitemList;
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
// CatelogOrderDetailModel catelogOrderDetailModel = new CatelogOrderDetailModel();
c_name = itemView.findViewById(R.id.customerName);
c_contact = itemView.findViewById(R.id.contact);
c_address = itemView.findViewById(R.id.address);
i_name = itemView.findViewById(R.id.interiorName);
i_address = itemView.findViewById(R.id.interiorAddress);
i_contact = itemView.findViewById(R.id.interiorContact);
}
#Override
public void onClick(View v) {
int position = getAdapterPosition();
CustomerModel orderitem = this.orderitemList.get(position);
}
#Override
public boolean onLongClick(View v) {
int position = getAdapterPosition();
CustomerModel orderitem = this.orderitemList.get(position);
if (v.getId() == itemView.getId()) {
// showUpdateDeleteDialog(order);
try {
} catch (Exception E) {
E.printStackTrace();
}
Toast.makeText(mCtx, "lc: ", Toast.LENGTH_SHORT).show();
}
return true;
}
}
}

Passing data from RecyclerView.Adapter to fragment onClick

I'm trying to figure out how to get data from a clicked item in a RecyclerView to a listview in a Fragment. I can't seem to figure out how to do this, as I can't get my bundle to work.
I've tried various solutions offered here on Stackoverflow, but none of them have worked. I have managed to get the info from the recyclerview, but I am stuck trying to figure out how I can pass it to the fragment. Can someone please help me?
The Adapter class:
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.ViewHolder> {
private Context context;
ArrayList<FoodActivity> list;
public FoodAdapter(ArrayList<FoodActivity> list){
this.list = list;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_item_food, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
holder.foods.setText(list.get(position).getName());
holder.carbo.setText(list.get(position).getCarbohydrates());
holder.protein.setText(list.get(position).getProtein());
holder.fats.setText(list.get(position).getFats());
//Get items from recyclerview when user clicks them. Then send them to FoodFragment
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String foods = list.get(position).getName();
String carbo = list.get(position).getCarbohydrates();
String protein = list.get(position).getProtein();
String fats = list.get(position).getFats();
Toast.makeText(v.getContext(), "test: " + foods, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return list.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView foods, carbo, fats, protein;
public ViewHolder(View itemView) {
super(itemView);
carbo = itemView.findViewById(R.id.carbo);
protein = itemView.findViewById(R.id.protein);
fats = itemView.findViewById(R.id.fats);
foods = itemView.findViewById(R.id.food);
}
}
}
The Fragment where the data comes from:
public class TrackingFragment extends Fragment {
DatabaseReference databaseReference;
ArrayList<FoodActivity> list;
RecyclerView recyclerView;
SearchView searchView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tracking, container, false);
databaseReference = FirebaseDatabase.getInstance().getReference().child("foods");
recyclerView = view.findViewById(R.id.rv);
searchView = view.findViewById(R.id.searchFood);
return view;
}
#Override
public void onStart() {
super.onStart();
if(databaseReference != null){
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
list = new ArrayList<>();
for(DataSnapshot ds : dataSnapshot.getChildren()){
list.add(ds.getValue(FoodActivity.class));
}
FoodAdapter adapter = new FoodAdapter(list);
recyclerView.setAdapter(adapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getActivity(), databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
if(searchView != null){
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
search(newText);
return true;
}
});
}
}
private void search(String str){
ArrayList<FoodActivity> searchList = new ArrayList<>();
for(FoodActivity object : list){
if(object.getName().toLowerCase().contains(str.toLowerCase())){
searchList.add(object);
}
}
FoodAdapter foodAdapter = new FoodAdapter(searchList);
recyclerView.setAdapter(foodAdapter);
}
}
And the class where it needs to go:
public class FoodFragment extends Fragment {
ImageButton addFood;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_food, container, false);
addFood = view.findViewById(R.id.addFood);
addFood.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction fr = getFragmentManager().beginTransaction();
fr.replace(R.id.fragment_container, new TrackingFragment());
fr.addToBackStack(null).commit();
}
});
return view;
}
}
The most simple is to add variables you need to your activity, set their values with onClick() and then retrieve data in other fragment:
in activity:
String foods;
public String getFoods() {
return foods;
}
public void setFoods(String foods) {
this.foods = foods;
}
in adapter:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((YourActivity)getActivity()).setFoods("Any value");
}
});
in destination fragment:
String foods = ((YourActivity)getActivity()).getFoods();
Add an interface to your adapter as follow
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.ViewHolder> {
interface OnClickListener {
void onClick(FoodActivity clickedItem);
}
private OnClickListener mCallback;
private ArrayList<FoodActivity> list;
public FoodAdapter(ArrayList<FoodActivity> list){
this.list = list;
}
public void setOnClickListener(OnClickListener callback) {
mCallback = callback;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_item_food, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
holder.foods.setText(list.get(position).getName());
holder.carbo.setText(list.get(position).getCarbohydrates());
holder.protein.setText(list.get(position).getProtein());
holder.fats.setText(list.get(position).getFats());
//Get items from recyclerview when user clicks them. Then send them to FoodFragment
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mCallback != null)
mCallback.onClick(list.get(position));
}
});
}
#Override
public int getItemCount() {
return list.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView foods, carbo, fats, protein;
public ViewHolder(View itemView) {
super(itemView);
carbo = itemView.findViewById(R.id.carbo);
protein = itemView.findViewById(R.id.protein);
fats = itemView.findViewById(R.id.fats);
foods = itemView.findViewById(R.id.food);
}
}
}
Android sometimes is a little complicated, when it involves the full stack:
01 RecyclerView Adapter
/** 01. Some Adapter */
public class SomeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private WeakReference<Context> mContext;
/** Constructor */
public SomeAdapter(#NonNull Context context) {
this.mContext = new WeakReference<>(context);
}
#NonNull
protected Context getContext() {
return this.mContext.get();
}
/** Call to Activity from within the adapter. */
private void someMethod() {
SomeActivity activity = (SomeActivity) getContext();
synchronized(activity) {activity.showLoginDialog();}
}
}
02 AppCompatActivity
/** 02. Some Activity */
public class SomeActivity extends AppCompatActivity {
#Nullable
private BaseFragment currentFragment = null;
/** Constructor */
public SomeActivity() {}
public void setCurrentFragment(Fragment fragment) {
this.currentFragment = fragment;
}
/** Call to the current Fragment. */
public void someMethod() {
if (currentFragment != null) {
currentFragment.someMethod();
}
}
}
03 Fragment
/** Some Fragment */
public class SomeFragment extends Fragment {
/** Constructor */
public SomeFragment() {}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
((BaseActivity) context).setCurrentFragment(this);
}
#Override
public void onDetach() {
super.onDetach();
((BaseActivity) getActivity()).setCurrentFragment(this);
}
}
To get your data from FoodAdapter to TrackingFragment, you can add TrackingFragment (or an interface it implements, ideally) as a parameter to the FoodAdapter constructor, then use that instance to forward your ViewHolder clicks to TrackingFragment for handling.
To get your data from TrackingFragment to FoodFragment, use the setTargetFragment/onActivityResult pattern for fragment <-> fragment communication. This answer has an example: https://stackoverflow.com/a/13733914/3238938

I'm not able to fetch data from fire-base database. I'm using FirebaseRecyclerAdapter with in onStart() method

#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerAdapter <ZedMate,ZedmateViewHolder> FBRA = new FirebaseRecyclerAdapter<ZedMate, ZedmateViewHolder>(
ZedMate.class,
R.layout.zedmate,
ZedmateViewHolder.class,
databaseReference
) {
#Override
protected void populateViewHolder(ZedmateViewHolder viewHolder, ZedMate model, int position) {
viewHolder.setTitle(model.getTitle());
viewHolder.setDesc(model.getDesc());
}
};
recyclerView.setAdapter(FBRA);
}
public static class ZedmateViewHolder extends RecyclerView.ViewHolder{
public ZedmateViewHolder(View itemView){
super(itemView);
View mView = itemView;
}
public void setTitle(String title){
TextView ptitle = (TextView)itemView.findViewById(R.id.mytitle);
ptitle.setText(title);
}
public void setDesc(String desc){
TextView pdesc = (TextView)itemView.findViewById(R.id.mydescription);
pdesc.setText(desc);
}
}

RecyclerVIew onItemClickListener Not working

I am working on RecyclerView and try to using on click listener for each item of recyclcerview using Interface
Here is my Activity class:
public class LegacyHomeActivity extends ActivityBaseDrawer {
private List<LegacyVideo> legacyVideoList = null;
private List<Video> videoList = new ArrayList<>();
private RecyclerView mRecyclerView;
private LegacyModeHomeAdapter adapter;
#Override
public void onNetworkStateChanged(boolean connected) {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
isLegacyMode = true;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_legacy_home);
if (getSupportActionBar() != null) {
setTitle(getString(R.string.footy_legacy_home));
}
ImageView legacy_live_score_imageView = (ImageView) findViewById(R.id.legacy_live_score_imageView);
legacy_live_score_imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(LegacyHomeActivity.this, LegacyLiveScoreActivity.class));
}
});
ImageView legacy_highlight_imageView = (ImageView) findViewById(R.id.legacy_highlight_imageView);
legacy_highlight_imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(LegacyHomeActivity.this, LegacyHighlightsActivity.class));
}
});
ImageView legacy_news_imageView = (ImageView) findViewById(R.id.legacy_news_imageView);
legacy_news_imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(LegacyHomeActivity.this, LegacyNewsActivity.class));
}
});
mRecyclerView = (RecyclerView) findViewById(R.id.legacy_mood_recyclerview);
final LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
adapter = new LegacyModeHomeAdapter(getApplicationContext(), itemClickListener);
mRecyclerView.setAdapter(adapter);
mRecyclerView.setHasFixedSize(true);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setColorSchemeResources(R.color.ThemeColor,
R.color.ThemeColor, R.color.ThemeColor);
swipeRefreshLayout
.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
getLegacyVideoList();
}
});
circularProgressView = (CircularProgressView) findViewById(R.id.circularProgressView);
showLoadingProgress();
getLegacyVideoList();
}
LegacyVideoClickListener itemClickListener = new LegacyVideoClickListener() {
#Override
public void onItemClickListener(int position) {
Video video = videoList.get(position);
VideoPlayerUtil.initVideoPLayer(video, LegacyHomeActivity.this);
}
};
private void getLegacyVideoList() {
FootyLightAPI api = new FootyLightAPI(getApplicationContext(), mResponseListener);
api.getLegacyHomeVideoList();
}
private final FootyLightAPI.ResponseListener mResponseListener = new FootyLightAPI.ResponseListener() {
#Override
public void getResponse(int apiId, final String response) {
switch (apiId) {
case R.integer.ApiLegacyVideoList:
Log.e("Legacy ............", "Response:................" + response);
try {
final ObjectMapper mapper = new ObjectMapper();
legacyVideoList = mapper.readValue(response, new TypeReference<List<LegacyVideo>>() {
});
if (legacyVideoList != null && legacyVideoList.size() > 0) {
videoList.clear();
for (LegacyVideo video : legacyVideoList) {
Log.e("Legacy video", "" + video.getTitle());
Video videoItem = new Video();
if (video.getItemType().equalsIgnoreCase("video")) {
videoItem.setTitle(video.getTitle());
videoItem.setLink(video.getLink());
videoItem.setThumb(video.getThumb());
videoItem.setContentType(video.getContentType());
videoItem.setContentUrl(video.getContentUrl());
videoItem.setDmcaLabel(video.getDmcaLabel());
videoItem.setDmcaContent(video.getDmcaContent());
videoItem.setDmcaDisclaimer(video.getDmcaDisclaimer());
videoItem.setDisplayType(video.getDisplayType());
videoList.add(videoItem);
}
}
}
Log.e("VideoList", "........." + videoList.size());
runOnUiThread(new Runnable() {
#Override
public void run() {
showVideoAdapter();
hideLoadingProgress();
}
});
} catch (Exception e) {
}
break;
default:
break;
}
}
#Override
public void getError(int apiId, int errorCode) {
}
#Override
public void getResponse(String trackingStr, int apiId, String response) {
}
#Override
public void getError(String trackingStr, int apiId, int errorCode) {
}
};
public void showVideoAdapter() {
if (adapter != null) {
adapter.setVideos(videoList);
}
}
}
And here is my Adapter Class
public class LegacyModeHomeAdapter extends RecyclerView.Adapter<LegacyModeHomeAdapter.ItemViewHolder> {
private List<Video> videoList;
private Context mContext;
private LegacyVideoClickListener onVideosRVItemClickListener;
private LayoutInflater getLayoutInflater() {
return LayoutInflater.from(mContext);
}
public LegacyModeHomeAdapter(Context mContext, LegacyVideoClickListener onVideosRVItemClickListener) {
this.mContext = mContext;
this.onVideosRVItemClickListener = onVideosRVItemClickListener;
}
public void setVideos(List<Video> videosList) {
this.videoList = videosList;
notifyDataSetChanged();
}
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = getLayoutInflater().inflate(R.layout.layout_legacy_mode_home_video_item, parent, false);
return new ItemViewHolder(view);
}
#Override
public void onBindViewHolder(ItemViewHolder holder, final int position) {
Video video = videoList.get(position);
Picasso.with(mContext).load(video.getThumb()).into(holder.categoryImage);
holder.categoryName.setText(video.getTitle());
holder.title_image_btn.setText(video.getDisplayType());
holder.VideosItemClickListener(position, onVideosRVItemClickListener);
}
#Override
public int getItemCount() {
if (videoList != null) {
return videoList.size();
}
return 0;
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView categoryName;
private ImageView categoryImage;
private Button title_image_btn;
public ItemViewHolder(View itemView) {
super(itemView);
categoryName = (TextView) itemView.findViewById(R.id.categoryName);
categoryImage = (ImageView) itemView.findViewById(R.id.categoryImage);
title_image_btn = (Button) itemView.findViewById(R.id.title_image_btn);
}
public void VideosItemClickListener(final int position, final LegacyVideoClickListener videosRVItemClickListener) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
videosRVItemClickListener.onItemClickListener(position);
}
});
}
}
}
And finally i am using this interface for listener :
public interface LegacyVideoClickListener {
public void onItemClickListener(int position);
}
This procedure working fine all of my other portion of app but not working this case. I don't know where is the problem . Please help me .
You this approach:
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final String element = mDataset[position];
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//your code
}
});
}
Pass onVideosRVItemClickListener in your ItemViewHolder constructor.
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = getLayoutInflater().inflate(R.layout.layout_legacy_mode_home_video_item, parent, false);
return new ItemViewHolder(view, onVideosRVItemClickListener);
}
#Override
public void onBindViewHolder(ItemViewHolder holder, final int position) {
Video video = videoList.get(position);
Picasso.with(mContext).load(video.getThumb()).into(holder.categoryImage);
holder.categoryName.setText(video.getTitle());
holder.title_image_btn.setText(video.getDisplayType());
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView categoryName;
private ImageView categoryImage;
private Button title_image_btn;
public ItemViewHolder(View itemView, final LegacyVideoClickListener videosRVItemClickListener) {
super(itemView);
categoryName = (TextView) itemView.findViewById(R.id.categoryName);
categoryImage = (ImageView) itemView.findViewById(R.id.categoryImage);
title_image_btn = (Button) itemView.findViewById(R.id.title_image_btn);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
videosRVItemClickListener.onItemClickListener(getAdapterPosition());
}
});
}
}
Check this sample
OnCLick can be achived using Custom Interface
interface Listener {
void performOperation(int Position);
}
in Your Adapter
private Listener mListener;
In your Adapter initialize your listner in constructor like this
mListener = (Listener) context;
In your bindViewHolder method
holder.yourView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mListener.performOperation(position);
}
});
Now in your Activity implement that interface like this
public class LegacyHomeActivity extends ActivityBaseDrawer implements listner {
#Override
public void performOperation(int Position) {
//Do whatever you want to do with this position
}
}
Your interface adapter class should be like this
public class LegacyModeHomeAdapter extends RecyclerView.Adapter<LegacyModeHomeAdapter.ItemViewHolder> {
private List<Video> videoList;
private Context mContext;
public static LegacyVideoClickListener onVideosRVItemClickListener;
private LayoutInflater getLayoutInflater() {
return LayoutInflater.from(mContext);
}
public LegacyModeHomeAdapter(Context mContext, LegacyVideoClickListener onVideosRVItemClickListener) {
this.mContext = mContext;
this.onVideosRVItemClickListener = onVideosRVItemClickListener;
}
public void setVideos(List<Video> videosList) {
this.videoList = videosList;
notifyDataSetChanged();
}
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = getLayoutInflater().inflate(R.layout.layout_legacy_mode_home_video_item, parent, false);
return new ItemViewHolder(view);
}
#Override
public void onBindViewHolder(ItemViewHolder holder, final int position) {
Video video = videoList.get(position);
Picasso.with(mContext).load(video.getThumb()).into(holder.categoryImage);
holder.categoryName.setText(video.getTitle());
holder.title_image_btn.setText(video.getDisplayType());
holder.VideosItemClickListener(position, onVideosRVItemClickListener);
}
#Override
public int getItemCount() {
if (videoList != null) {
return videoList.size();
}
return 0;
}
public class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView categoryName;
private ImageView categoryImage;
private Button title_image_btn;
public ItemViewHolder(View itemView) {
super(itemView);
categoryName = (TextView) itemView.findViewById(R.id.categoryName);
categoryImage = (ImageView) itemView.findViewById(R.id.categoryImage);
title_image_btn = (Button) itemView.findViewById(R.id.title_image_btn);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
onVideosRVItemClickListener.onItemClickListener(getPosition(), v);
}
}
public void setOnItemClickListener(LegacyVideoClickListener clickListener) {
LegacyModeHomeAdapter.onVideosRVItemClickListener = clickListener;
}
public interface LegacyVideoClickListener {
public void onItemClickListener(int position, View v);
}
}
And your adapter usage class should be like this
adapter.setOnItemClickListener(new LegacyModeHomeAdapter.LegacyVideoClickListener() {
#Override
public void onItemClick(int position, View v) {
//Your code
}
});
Using this way of interface settings you can achieve the onclick listener function exactly.
Please let me know if you are having trouble still.
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public Button btMyButton;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// your implementation. In order to get position you can use `getAdapterPosition()` method
}
}
#Override
public void onBindViewHolder(RecyclerViewAdapter.ItemViewHolder holder, int position) {
holder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
Try like this

Categories

Resources