Help
the problem is that when running the application nothing appears in my recyclerview, only error android studio : E/RecyclerView: No adapter attached; skipping layout
Salon ListActivity
public class SalonListActivity extends AppCompatActivity implements IOnLoadCountSalon, IBranchLoadListener {
IOnLoadCountSalon iOnLoadCountSalon;
IBranchLoadListener iBranchLoadListener;
AlertDialog dialog;
#BindView(R.id.txt_salon_count)
TextView txt_salon_count;
#BindView(R.id.recycler_salon)
RecyclerView recycler_salon;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_salon_list);
ButterKnife.bind(this);
initView();
init();
loadSalonBaseOnCity(Common.state_name);
}
private void loadSalonBaseOnCity(String name) {
dialog.show();
FirebaseFirestore.getInstance().collection("AllSalon")
.document(name)
.collection("Branch")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful())
{
List<Salon> salons = new ArrayList<>();
iOnLoadCountSalon.onLoadCountSalonSuccess(task.getResult().size());
for(DocumentSnapshot salonSnapShot : task.getResult())
{
Salon salon = salonSnapShot.toObject(Salon.class);
salons.add(salon);
}
iBranchLoadListener.onBranchLoadSuccess(salons);
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
iBranchLoadListener.onBranchLoadFailed(e.getMessage());
}
});
}
private void init() {
dialog = new SpotsDialog.Builder().setContext(this).setCancelable(false).build();
iOnLoadCountSalon=this;
iBranchLoadListener = this;
}
private void initView() {
recycler_salon.setHasFixedSize(true);
recycler_salon.setLayoutManager(new GridLayoutManager(this,2));
recycler_salon.addItemDecoration(new SpacesItemDecoration(8));
}
#Override
public void onLoadCountSalonSuccess(int count) {
txt_salon_count.setText(new StringBuilder("Cantidad Salones (").append(count).append(")"));
}
#Override
public void onBranchLoadSuccess(List<Salon> salonList) {
MySalonAdapter salonAdapter = new MySalonAdapter(this,salonList);
recycler_salon.setAdapter(salonAdapter);
dialog.dismiss();
}
#Override
public void onBranchLoadFailed(String message) {
Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
dialog.dismiss();
}}`
Salon Adapter
public class MySalonAdapter extends RecyclerView.Adapter<MySalonAdapter.MyViewHolder> {
Context context;
List<Salon> salonList;
List<CardView> cardViewList;
LocalBroadcastManager localBroadcastManager;
public MySalonAdapter(Context context, List<Salon> salonList) {
this.context = context;
this.salonList = salonList;
cardViewList = new ArrayList<>();
localBroadcastManager = LocalBroadcastManager.getInstance(context);
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(context).inflate(R.layout.layout_salon, viewGroup, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder myViewHolder, int i) {
myViewHolder.txt_salon_name.setText(salonList.get(i).getName());
myViewHolder.txt_salon_address.setText(salonList.get(i).getAddress());
if (!cardViewList.contains(myViewHolder.card_salon))
cardViewList.add(myViewHolder.card_salon);
myViewHolder.setiRecyckerItemSelectedListener(new IRecyclerItemSelectedListener() {
#Override
public void onItemSelected(View view, int position) {
}
});
}
#Override
public int getItemCount() {
return salonList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
IRecyclerItemSelectedListener iRecyckerItemSelectedListener;
TextView txt_salon_name, txt_salon_address;
CardView card_salon;
public void setiRecyckerItemSelectedListener(IRecyclerItemSelectedListener iRecyckerItemSelectedListener) {
this.iRecyckerItemSelectedListener = iRecyckerItemSelectedListener;
}
public MyViewHolder(#NonNull View itemView) {
super(itemView);
card_salon = (CardView) itemView.findViewById(R.id.card_salon);
txt_salon_name = (TextView) itemView.findViewById(R.id.txt_salon_name);
txt_salon_address = (TextView) itemView.findViewById(R.id.txt_salon_address);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
iRecyckerItemSelectedListener.onItemSelected(v, getAdapterPosition());
}
}
}
Sorry for my English I hope you can help me, I will be very grateful
The message is saying that the adapter is not attached at the time the layout is rendered. Which is true because you've attached it within a callback method
Instead, you can attach it immediately if you create a field of loaded salons and the adapter
IBranchLoadListener iBranchLoadListener;
List<Salon> mSalons = new ArrayList<>();
RecyclerView.Adapter<MySalonAdapter.MyViewHolder> mAdapter;
Use that list in the callback rather than make a new list
if(task.isSuccessful())
{
mSalons.clear();
List<DocumentSnapshot> result = task.getResult();
iOnLoadCountSalon.onLoadCountSalonSuccess(result.size());
for(DocumentSnapshot salonSnapShot : result)
{
Salon salon = salonSnapShot.toObject(Salon.class);
mSalons.add(salon);
}
iBranchLoadListener.onBranchLoadSuccess(mSalons);
}
And then initialize and attach your adapter immediately within the onCreate or init methods rather than wait for the callback
Within onBranchLoadSuccess you should notify the adapter that it needs updated
Related
I need to add ClickListener to RecyclerView in my project but I couldn't.
I tried for days and failed :(
Help me, please.
(the variables are in Italian)
RecyclerView class:
public class ListaNonConsegnate extends AppCompatActivity{
private androidx.recyclerview.widget.RecyclerView recyclerView;
EditText searchBox;
DatabaseReference nonConsegnate;
private ArrayList<dati> list;
private String nomeUtente;
private SwipeRefreshLayout swipeRefreshLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lista_non_consegnate);
Bundle extras = getIntent().getExtras();
nomeUtente = extras.getString("KEY_nomeUtente"); //variable from the previous activity
searchBox = findViewById(R.id.searchBox); //for filtered list
nonConsegnate = FirebaseDatabase.getInstance().getReference().child(nomeUtente + "/00-b-Non consegnate"); //path on the database
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
searchBox.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
ArrayList<dati> myList = new ArrayList<>();
//add filter
AdapterClass adapterClass = new AdapterClass(myList);
recyclerView.setAdapter(adapterClass);
}
});
}
#Override
protected void onStart() {
super.onStart();
if (nonConsegnate != null) {
nonConsegnate.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
list = new ArrayList<>();
for (DataSnapshot ds : snapshot.getChildren()) {
list.add(ds.getValue(dati.class));
}
AdapterClass adapterClass = new AdapterClass(list);
recyclerView.setAdapter(adapterClass);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(ListaNonConsegnate.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
}
Adapter class:
public class AdapterClass extends RecyclerView.Adapter<AdapterClass.MyViewHolder>{
ArrayList<dati> list;
public AdapterClass(ArrayList<dati> list){
this.list = list;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_items, viewGroup, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.bolla.setText(list.get(position).getDDT());
}
#Override
public int getItemCount() {
return list.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView bolla;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
bolla = itemView.findViewById(R.id.textViewBolla);
}
}
}
(OnClick will have to open a new activity by passing it the "nomeUtente" and "DDT" variables)
Thank you.
(StackOverflow tells me I need to add more details but there's nothing more to say so I write useless sentences) lol
1- Add this Code To Your Activity :
public void onClickCalled() {
// Your Code
}
2- and this in your adapter :
holder.nomeUtente.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
((YourNewActivity) context).onClickCalled();
}
});
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;
}
}
}
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 stuck in a project which I need to get the data from document in a collection. I'm currently using Firestore for Android Studio. The fact is that my query shows the toast just after the task.isSuccessful but the For loop is not getting the data from the Cloud, not even showing the test Toast I put inside the loop. Everything works fine till get to the For loop. The RecyclerView only shows content if I put parameters manually
for test so Adapter is working fine but when I try to show the data from the firestorm it shows nothing! Any idea? It does not show any error!
public class MostrarConteudoFragment extends AppCompatActivity {
RecyclerView recyclerView2;
List<Compras> listaCompras = new ArrayList<>();
Compras compras;
FirebaseFirestore db;
FirebaseUser user;
FirebaseAuth mAuth;
SavedFragment savedFragment;
public String idUpdate = ""; // id do item para o update
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mostrar_conteudo_fragment);
db = FirebaseFirestore.getInstance();
mAuth = FirebaseAuth.getInstance( );
user = mAuth.getCurrentUser( );
recyclerView2 = findViewById(R.id.recyclerView2);
savedFragment = new SavedFragment();
}
protected void onStart(){
super.onStart();
if(listaCompras.size() > 0)
listaCompras.clear();
db.collection("Usuario").document(user.getUid()).collection("ItensSalvos")
.whereEqualTo("id", idUpdate).get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful()) {
Toast.makeText(MostrarConteudoFragment.this, "task succcessful", Toast.LENGTH_SHORT).show( );
for (QueryDocumentSnapshot doc : task.getResult( )) {
Toast.makeText(MostrarConteudoFragment.this, "doc succcessful", Toast.LENGTH_SHORT).show( );
compras = new Compras(doc.getString("id"),
doc.getString("inputNome"),
doc.getString("inputQtd"),
doc.getString("inputPreco"),
doc.getBoolean("checkBoxOk"));
listaCompras.add(compras);
}
//Configurar adapter
AdapterMostrarConteudo mostrarConteudo = new AdapterMostrarConteudo(MostrarConteudoFragment.this, listaCompras);
//Configurar RecyclerView
RecyclerView.LayoutManager layoutManager1 = new LinearLayoutManager(getApplicationContext( ));
recyclerView2.setLayoutManager(layoutManager1);
recyclerView2.setHasFixedSize(true);
recyclerView2.setAdapter(mostrarConteudo);
}
}
});
}
}
public class AdapterSave extends RecyclerView.Adapter {
List<DataHora> listaDataHora;
SavedFragment savedFragment;
MostrarConteudoFragment mostrarConteudo;
public AdapterSave(SavedFragment savedFragment, List<DataHora> listaDataHora) {
this.savedFragment = savedFragment;
this.listaDataHora = listaDataHora;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemLista = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.lista_salvas, viewGroup, false);
mostrarConteudo = new MostrarConteudoFragment();
return new MyViewHolder(itemLista);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.data.setText(listaDataHora.get(i).getData());
myViewHolder.hora.setText(listaDataHora.get(i).getHora());
myViewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
mostrarConteudo.idUpdate = listaDataHora.get(position).getId();
Intent intent = new Intent(savedFragment.getActivity(), MostrarConteudoFragment.class);
savedFragment.startActivity(intent );
Toast.makeText(savedFragment.getContext(), mostrarConteudo.idUpdate, Toast.LENGTH_SHORT).show( );
}
});
}
#Override
public int getItemCount() {
return listaDataHora.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnCreateContextMenuListener {
TextView data, hora;
ItemClickListener itemClickListener;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
itemView.setOnClickListener(this);
itemView.setOnCreateContextMenuListener(this);
data = itemView.findViewById(R.id.textData);
hora = itemView.findViewById(R.id.textHora);
}
// Metodo construtor da interface ItemClickListener
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
#Override // Permite abrir o menu com o click
public void onClick(View view) {
itemClickListener.onClick(view, getAdapterPosition(), false);
}
#Override // Cria o menu quando item é clicado
public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
}
}
}
enter image description here
enter image description here
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