Below code of adapter of RecyclerView
public interface SelectMarket {
void selectMarket(DataMarket dataMarket);
}
public class viewHolder extends RecyclerView.ViewHolder{
TextView marketTitleName;
public viewHolder(#NonNull View itemView) {
super(itemView);
marketTitleName = itemView.findViewById(R.id.market_title_custom);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
selectMarket.selectMarket(marketName.get(getAdapterPosition()));
Toast.makeText(ctx, "id "+getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
}
}
In the code I shows you the ViewHolder
where I set onClickListener
I want to click on that and then go to other Fragment called SelectRoomFragment
and in Method of SelectMarket() I wrote inside the codes which will help me to go the the Next Fragment like this :
#Override
public void selectMarket(DataMarket dataMarket) {
SelectRoomFragment selectRoomFragment= new SelectRoomFragment();
Bundle args = new Bundle();
args.putString("market",dataMarket.getTitle());
selectRoomFragment.setArguments(args);
getFragmentManager().beginTransaction().add(R.id.fragment_container,
selectRoomFragment).commit();
}
The Output Is
Which is not looking Good like I want.
move the code below to onBindViewHolder
marketTitleName = itemView.findViewById(R.id.market_title_custom);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
selectMarket.selectMarket(marketName.get(getAdapterPosition()));
Toast.makeText(ctx, "id "+getAdapterPosition(),Toast.LENGTH_SHORT).show();
}
});
Related
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//
}
});
Now, it is impossible to use startActivityForResult.
I have to use a launcher, but I don't know what to do because it's a click event that happens in the item view and I'm going to put the image in the item view
I tried various methods, but they were all for activities, so they didn't work.
You need either to cast the context to Activity, or to pass the onClickListener to the adapter as following
Create the clickListener
public interface MyClickListener {
void onItemClick(MyModel model);
}
In your adapter class:
public class MyAdapter extends RecyclerView.Adapter<ViewHolder> {
private MyClickListener onClickListener;
public MyAdapter(MyClickListener onClickListener) {
this.onClickListener = onClickListener;
}
...
}
In your method:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onClickListener.onItemClick(myModel);
}
});
In your activity:
MyAdapter adapter = new MyAdapter(new MyClickListener() {
public void onItemClick(MyModel model) {
/// here you can call startActivityForResult
}
});
I need to pass some data of my adapter to bottom navigation view activity. Just like this:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, RestaurantDetailsActivity.class);
intent.putExtra("restaurantUid", uid);
context.startActivity(intent);
}
});
I don't know where to put my button to use setOnClickListener
You should not change activities in Adapter. Rather, you should create an interface for your click listener and implement that in your Activity:
Create a Click Listener interface class ItemClickListenerInterface.Java
public interface ItemClickListener {
void onClick(View view, int position);
}
Then, in your viewHolder inside your AdapterClass, bind this click listener to the view Like this:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private ItemClickListener clickListener;
public void setClickListener(ItemClickListener itemClickListener) {
this.clickListener = itemClickListener;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (clickListener != null) clickListener.onClick(view, getAdapterPosition());
}
}
}
Then in Your ActivityClass.Java, implement this click list
public class CityActivity extends Activity implements ItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
mAdapter.setClickListener(this);
}
#Override
public void onClick(View view, int position) {
final Resturant resturant=resturantsList.get(position)
Intent intent = new Intent(context, RestaurantDetailsActivity.class);
intent.putExtra("restaurantUid", resturant.uid);
context.startActivity(intent)
}
}
I have multiple card views in my Main Fragment that go to different fragments within the app usin onClickListener functionality.
However, when the cardviews are selected the fragment that shows is always the last replaced.
Ex: In main activity all the card views, when selected, show the affirmations fragment. No matter if they have been connected to their proper fragment.
MainActivity.java
#Override
public void onCardSelected() {
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_fragment, new ProfileFragment());
fragmentTransaction.replace(R.id.container_fragment, new BibleFragment());
fragmentTransaction.replace(R.id.container_fragment, new ShopFragment());
fragmentTransaction.replace(R.id.container_fragment, new NotiFragment());
fragmentTransaction.replace(R.id.container_fragment, new CalFragment());
fragmentTransaction.replace(R.id.container_fragment, new AffFragment());
fragmentTransaction.commit();
}
MainFragment.java
public class MainFragment extends Fragment {
private onFragmentBtnSelected listener;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_main,container,false);
CardView clickCardProfile = view.findViewById(R.id.cardProfile);
CardView clickCardBible = view.findViewById(R.id.cardBible);
CardView clickCardShop = view.findViewById(R.id.cardShop);
CardView clickCardNoti = view.findViewById(R.id.cardNotifications);
CardView clickCardCalendar = view.findViewById(R.id.cardCalendar);
CardView clickCardAffirmations = view.findViewById(R.id.cardAffirmations);
/*Button clickme = view.findViewById(R.id.clickHF);
clickme.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onBtnSelected();
}
});
return view;*/
clickCardProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onCardSelected();
}
});
//return view;
clickCardBible.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onCardSelected();
}
});
//return view;
clickCardShop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onCardSelected();
}
});
clickCardNoti.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onCardSelected();
}
});
clickCardCalendar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onCardSelected();
}
});
clickCardAffirmations.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onCardSelected();
}
});
return view;
}
#Override
public void onAttach(#NonNull Context context){
super.onAttach(context);
if(context instanceof onFragmentBtnSelected ){
listener =(onFragmentBtnSelected) context;
}
else {
throw new ClassCastException(context.toString() + " must implement listiner");
}
}
public interface onFragmentBtnSelected{
//public void onBtnSelected();
public void onCardSelected();
}
Would I need to create an interface method for each of the buttons, and separate the respective replace statements or is there a way to have them all in the same method and switch from fragment to fragment?
I am trying to create an adapter for a RecyclerView, where each view contains some information and two buttons, one for removing the view and one for updating the information. I set the listener as follows, and I get the actions to work as I want to (i.e. the removeRecepie and chooseNewRandomRecepie does what I want them to do).
However, sometimes, seemingly randomly, the getAdapterPosition sends the incorrect position. Thus the removal or updating happens to the incorrect view (I have tested the output of getAdapterPosition, and the output is consistent with the view that changes, i.e. the wrong one). I have written the setListener as follows:
void setListener(View view){
Button removeButton = view.findViewById(R.id.remove_button);
removeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
removeRecepie(getAdapterPosition());
}
});
Button newRandomButton = view.findViewById(R.id.new_random);
newRandomButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
chooseNewRandomRecepie(getAdapterPosition());
}
});
}
I would be really grateful for any help, or pointers to help. Please let me know if there is any further information I can include to help you help me :)
You should be use onBindViewHolder.
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.removeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
removeRecepie(position);
}
});
holder.removeButton.SetOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
chooseNewRandomRecepie(position);
}
});
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
Button removeButton;
Button newRandomButton;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
removeButton = itemView.findViewById(R.id.removebutton);
newRandomButton = itemView.findViewById(R.id.newRandomButton);
}
}
I have Googled a number of possibilities on how to get the item which is clicked in a recycler view but none of them seem to work. The code below should work but I dont understand why its not. In android studio, the getPosition() method is crossed out. I am running out of ideas, Is there a way i can at least toast the name of the recycler view is clicked?
ViewHolder
public class ShoppingListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public CardView cv;
public TextView name;
public TextView description;
Context context;
public ShoppingListViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.cardView);
name = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("RecyclerView", "onClick:" + getPosition());
}
});
}
public void bindView(int position) {
}
#Override
public void onClick(View v) {
Log.d("TAG", "onClick " + getPosition() + " " + name);
}
Adapter
public class MainShoppingListViewActivity extends AppCompatActivity {
List<Data> list = new ArrayList<>();
RecyclerView recyclerView;
ShoppingListViewAdapter adapter;
Context context;
EditText listName;
Firebase ref;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_shoppinglist_view);
Firebase.setAndroidContext(this);
ref = new Firebase("https://shoppinglistshare.firebaseio.com/");
// Getting the recycler view, using the Recycler View
recyclerView = (RecyclerView) findViewById(R.id.shopping_list_recycler_view);
// The setLayoutManager which contains the main container where the Recycler View is contained
recyclerView.setLayoutManager(new LinearLayoutManager(MainShoppingListViewActivity.this));
// Floating action bar initiated, background color is set and then onClickListener to act when the
// button is pressed to which the createDialogBox(); method is called
FloatingActionButton addFloat = (FloatingActionButton) findViewById(R.id.fab);
addFloat.setBackgroundTintList(ColorStateList.valueOf(Color
.parseColor("#3F51B5")));
addFloat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Click action
createDialogBox();
}
});
}
/*
* This method is used to add a new item to the Recycler View
*/
public void addNewShoppingListItem(String val) {
ref = new Firebase("https://shoppinglistshare.firebaseio.com/");
adapter = new ShoppingListViewAdapter(list, MainShoppingListViewActivity.this);
recyclerView.setAdapter(adapter);
adapter.addItem(new Data(val, "Created by: Me"));
ref.child("List Name: ").setValue(val);
}
/*
* This method is used to add a new item to the Recycler View
*/
public void removeShoppingListItem(String val) {
adapter = new ShoppingListViewAdapter(list, MainShoppingListViewActivity.this);
recyclerView.setAdapter(adapter);
adapter.addItem(new Data(val, "Created by: Me"));
}
/*
* This method is called inside the float action bar to create a dialog box when the floating action button is pressed.
*/
public void createDialogBox() {
// Alert Dialog Builder
AlertDialog.Builder builder = new AlertDialog.Builder(this);
// Using Layout Inflater class and assigned to a variable and using getLayout
LayoutInflater inflater = this.getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout.
// Using the view class to inflate the layout.
View rootView = inflater.inflate(R.layout.custom_alert_dialog, null);
listName = (EditText) rootView.findViewById(R.id.ShoppinglistName);
// Using the AlertDialog Builder created above as "builder" to set the view.
builder.setView(rootView)
.setPositiveButton("Create", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String val = listName.getText().toString();
if (!val.isEmpty()) {
addNewShoppingListItem(val);
} else {
Toast.makeText(MainShoppingListViewActivity.this, "Please enter a value", Toast.LENGTH_SHORT).show();
}
}
})
// Show the dialog
.show();
}
}
Logs
FATAL EXCEPTION: main
Process: familyshopshare.com.familyshopshare, PID: 17889
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at android.widget.Toast.<init>(Toast.java:102)
at android.widget.Toast.makeText(Toast.java:259)
at familyshopshare.com.familyshopshare.ShoppingListViewHolder$1.onClick(ShoppingListViewHolder.java:33)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Made small changes, here is the solution i got. I am going to alter the onClick onto another method instead of where it is. If there are any suggestions on how i can make the code better please let me know, any advise is much appreciated :)
public class ShoppingListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public CardView cv;
public TextView name;
public TextView description;
Context context;
public ShoppingListViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.cardView);
name = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Data test = new Data(name.getText().toString(), description.getText().toString());
Toast.makeText(v.getContext(), "onClick " + test.getName(), Toast.LENGTH_SHORT).show();
Log.d("RecyclerView", "onClick is this:" + getAdapterPosition());
}
});
}
#Override
public void onClick(View v) {
Toast.makeText(context, "onClick " + getAdapterPosition() + " " + name, Toast.LENGTH_SHORT).show();
}
}
There are a few ways you can do it. Personally, I like to set the listener in the onBindViewHolder inside of the adapter class(wherever you have your viewholder):
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.YourTargetObject.setOnClickListener(new View.onClickListener(){
public void onClick(View view){
//do something
}
});
}