I am using RecyclerView and CardView. I am following the WhatsApp like UI. When the Whatsapp user long presses the Contacts in the Chat Tab of Home Screen it enables the users to select multiple Contacts at the same time.
Whatsapp Multiselect
I want the user to multiselect by clicking anywhere in the cardview just like in whatsapp screen. I am stuck at the clicking of the CardView inside recycler view. I want only the onclick of cardview, rest of the clicks of items inside to be not clickable so that they dont interfere when user is multiselecting. Any help in resolving this issue will be greatly appreciated.
CardView is also a View you can set View.OnClickListener on CardView.
public class MyViewHolder extends RecyclerView.ViewHolder {
public View view;
public MyViewHolder(View view) {
super(view);
this.view = view;
}
}
And in your onBindViewHolder()
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Your Logic
}
});
}
Or You can do this.
CardView in xml
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="#dimen/card_margin"
android:elevation="3dp"
card_view:cardCornerRadius="#dimen/card_album_radius">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_margin="7dp"
android:id="#+id/thumbnail"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_centerHorizontal="true"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:scaleType="fitXY"/>
<TextView
android:id="#+id/channel_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/thumbnail"
android:paddingLeft="#dimen/album_title_padding"
android:paddingRight="#dimen/album_title_padding"
android:paddingTop="#dimen/album_title_padding"
android:textColor="#4c4c4c"
android:textSize="16dp"
android:text="Ary News"
android:fontFamily="sans-serif-smallcaps"
android:gravity="center_horizontal"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Watch Now"
android:layout_below="#id/channel_name"
android:fontFamily="sans-serif-smallcaps"
android:id="#+id/watch_now"
android:textStyle="bold"
android:backgroundTint="#color/colorAccent"/>
<!--This is the view-->
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/view"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
And in your RecyclerView Adapter
public class MyViewHolder extends RecyclerView.ViewHolder {
public View view;
public MyViewHolder(View view) {
super(view);
this.view = findViewById(R.id.view);
}}
In onBindViewHolder()
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context,"Card clicked",Toast.LENGTH_SHORT).show();
}
});
}
Related
I have a layout for a listview item.
I added an ImageButton to the layout, as follows:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/tvTaskName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:textSize="20dp"
android:textColor="#000000"
android:layout_marginTop="5dp"
/>
<TextView
android:id="#+id/tvTaskDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Description"
android:textSize="14sp"
android:textColor="#0E2DF5"
android:layout_marginTop="40dp"
/>
<TextView
android:id="#+id/tvTaskStartTime"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Start time"
android:textSize="14sp"
android:textColor="#44FF00"
android:layout_marginHorizontal="100dp"
android:layout_marginTop="10dp"
/>
<TextView
android:id="#+id/tvTaskDeadLine"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Dead line"
android:textSize="14sp"
android:textColor="#44FF00"
android:layout_marginHorizontal="100dp"
android:layout_marginTop="40dp"
/>
<ImageButton
android:id="#+id/btnTaskDone"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginStart="345dp"
android:background="#drawable/done_button_state_selector"
/>
</FrameLayout>
The problem - when I add the ImageButton - the entire ListView becomes unclickable. I can only click the button.
I need both the ListView and the button to be clickable, because im using them for different purposes.
I tried putting the ImageButton in one FrameLayout, everything else in another FrameLayout, and both of the FrameLayouts in on big FrameLayout. Still nothing
I would be happy to hear any suggestions. Thanks!
I would use a recyclerView instead it allows for more flexibility, you can have your recyclerView in your xml code like so
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/toolbar" />
Then you set it up like so with java code
RecyclerView recycler;
CustomAdapter adapter;
List<CustomModel> models = new ArrayList<>();
private DatabaseReference databaseReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_kids_search);
recycler= findViewById(R.id.recycler);
adapter = new CustomAdapter (models);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recycler.setLayoutManager(layoutManager);
recycler.setAdapter(searchAdapter);
}
So you create a model class to hold variables for each list item to show then you populate the models ArrayList with those models.
Here is how the the most important customAdapter class should look like
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
List<CustomModel> customModels;
Context context;
public CustomAdapter(List<ChildModel> childModels) {
this.childModels = childModels;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_child, parent, false);
context = parent.getContext();
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final CustomModel customModel = customModels.get(position);
holder.tvTaskName.setText(customModel.getTaskName());
holder.tvTaskDescription.setText(customModel.getDescreption());
holder.tvTaskStartTime.setText(customModel.getStartTime());
holder.tvTaskDeadLine.setText(customModel.getDeadLine());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Here the list item is clicked
}
});
holder.btnTaskDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Here the imageButton is clicked
}
});
}
#Override
public int getItemCount() {
return childModels.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvTaskName;
TextView tvTaskDescription;
TextView tvTaskStartTime;
TextView tvTaskDeadLine;
ImageButton btnTaskDone;
public ViewHolder(#NonNull View itemView) {
super(itemView);
tvTaskName = itemView.findViewById(R.id.tvTaskName);
tvTaskDescription = itemView.findViewById(R.id.tvTaskDescription);
tvTaskStartTime = itemView.findViewById(R.id.tvTaskStartTime);
tvTaskDeadLine = itemView.findViewById(R.id.tvTaskDescription);
btnTaskDone = itemView.findViewById(R.id.btnTaskDone);
}
}
}
Hope this helps
This question is already answered but not for cardview I guess, I have already gone through most answers and experimented with them still my problem is not solved.
I have a recyclerview with adapter and a cardview now I have added a button in a cardview and I want to change the visibility of this button to invisible when the button is clicked, but when I do so the visibility of other buttons in other cards like at position=9 get affected and becomes invisible but I never clicked the button at 9th card.
I found some solutions like writing the onClick under onBindViewHolder method. I did so but still its not working please help!
Here is the code for cardview
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/shop_cardview"
android:layout_width="match_parent"
android:layout_height="280dp"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="5dp"
card_view:cardMaxElevation="5dp"
card_view:contentPadding="5dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/btnGrey">
<com.android.volley.toolbox.NetworkImageView
android:id="#+id/shopVolleyImageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#mipmap/pyaa_logo_iii"
card_view:layout_constraintBottom_toBottomOf="parent"
card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintStart_toStartOf="parent"
card_view:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/shopImageNameTV"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginTop="8dp"
android:text="Json Image Name"
android:textAlignment="center"
android:textColor="#000000"
android:textSize="20dp"
card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintStart_toStartOf="parent"
card_view:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Button"
card_view:layout_constraintBottom_toBottomOf="parent"
card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
Here is the code for recyclerviewadapter
public class shopRecyclerViewAdapter extends RecyclerView.Adapter<shopRecyclerViewAdapter.ViewHolder> {
Context context;
List<shopDataAdapter> dataAdapters;
ImageLoader imageLoader;
public shopRecyclerViewAdapter(List<shopDataAdapter> getDataAdapter,Context context){
super();
this.dataAdapters=getDataAdapter;
this.context=context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_shop,parent,false);
ViewHolder vh=new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(final ViewHolder Viewholder, int position) {
shopDataAdapter dataAdapterOBJ= dataAdapters.get(position);
imageLoader=shopImageAdapter.getInstance(context).getImageLoader();
imageLoader.get(dataAdapterOBJ.getshopImageUrl(),
ImageLoader.getImageListener(
Viewholder.VollyImageView,
R.mipmap.ic_launcher,
android.R.drawable.ic_dialog_alert
)
);
Viewholder.VollyImageView.setImageUrl(dataAdapterOBJ.getshopImageUrl(),imageLoader);
Viewholder.ImageTitleTV.setText(dataAdapterOBJ.getshopName());
Viewholder.check.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Viewholder.check.setVisibility(View.INVISIBLE);
}
});
}
#Override
public int getItemCount() {
return dataAdapters.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView ImageTitleTV;
public NetworkImageView VollyImageView;
public Button check;
public ViewHolder(View itemView) {
super(itemView);
ImageTitleTV=itemView.findViewById(R.id.shopImageNameTV);
VollyImageView=itemView.findViewById(R.id.shopVolleyImageView);
check=itemView.findViewById(R.id.button);
}
}
}
You can do like this declare global variable clickPosition = -1
public void onBindViewHolder(final ViewHolder Viewholder, final int position) {
Viewholder.check.setVisibility(View.VISIBLE);
Viewholder.check.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clickPosition = position;
notifyDataSetChanged();
}
});
if(clickPosition == position){
Viewholder.check.setVisibility(View.INVISIBLE);
}
}
Don't forgot to write line Viewholder.check.setVisibility(View.VISIBLE); otherwise it will give strange behavior.
If you can give more explain what particular behavior you want I can give more explanation or exact solution.
So I have a CardView which has a RecyclerView in it, and I have set an OnClickListener to the CardView. The problem is I want to be able to click anywhere in the CardView but I can't click it inside the RecyclerView. I can only click the part of the CardView that's not part of the RecyclerView. How do I fix this?
Thanks.
<android.support.v7.widget.CardView
android:id="#+id/phone_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:foreground="?android:attr/selectableItemBackground">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp">
<TextView
android:id="#+id/phone_card_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/phone_numbers"
android:textAppearance="#style/TextAppearance.AppCompat.Caption" />
<android.support.v7.widget.RecyclerView
android:id="#+id/phone_card_recycler_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/phone_card_title">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
</android.support.v7.widget.CardView>
In your recycler adapater initialize cardview and setonClicklistener for it
example
Viewholder :
public class ViewHolder extends RecyclerView.ViewHolder {
public final CardView cardView ;
public ViewHolder(View view) {
super(view);
cardView = (CardView) view.findViewById(R.id.carView);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.cardView.setOnClickLister(new View.OnClickListener(){
#Override
public void onClick(View view) {
//your logic here
}
});
}
So in my recyclerview, i have a CARDVIEW which consists of
ImageView, EditText and a button. and when i click the button, it will send the text from EditText to PARSE.com. My problem is that, i cannot link that text to it's ImageView
i want when i open the app, i can see the imageView and at the bottom there will be a description for the image. i want the editText to be dynamic. Can Someone guide me?
this is the XML layout:
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/card_view"
android:layout_margin="10dp"
android:layout_marginBottom="30dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/linearLayout">
<ImageView
android:id="#+id/imageViewRecycler"
android:background="#color/border"
android:layout_width="match_parent"
android:layout_height="380dp"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:contentDescription="TODO"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/separator"
android:id="#+id/separator"
android:layout_above="#+id/firstLine"
android:layout_alignParentStart="true" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/grey">
<EditText
android:id="#+id/firstLineText"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignWithParentIfMissing="true"
android:gravity="top"
android:background="#color/colorPrimary"
android:textSize="16sp"
android:textColor="#color/colorAccent"
android:layout_alignParentBottom="true"
android:layout_alignStart="#+id/linearLayout"
android:layout_alignParentTop="true" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="save"
android:id="#+id/firstLineButton"
android:layout_gravity="right"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
this is my recyclerview adapter:
public class myAdapter extends RecyclerView.Adapter<myAdapter.ViewHolder> {
LayoutInflater inflater;
List<imageDescription> data= Collections.emptyList();
private Context context;
ViewHolder holder;
public myAdapter(Context context, List<imageDescription> data){
this.context=context;
this.data=data;
}
#Override
public myAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=inflater.from(context).inflate(R.layout.custom_layout, parent, false);
holder= new ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(myAdapter.ViewHolder holder, int position) {
imageDescription current= data.get(position);
Glide.with(context)
.load(current.url)
.centerCrop()
.override(500,500)
.placeholder(R.drawable.whitebackground)
.into(holder.imageViewRecycler);
holder.firstLineText.setText(current.firstLine);
}
#Override
public int getItemCount() {
return data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageViewRecycler;
EditText firstLineText;
Button firstLineButton;
public ViewHolder(final View itemView) {
super(itemView);
imageViewRecycler=(ImageView)itemView.findViewById(R.id.imageViewRecycler);
firstLineText=(EditText)itemView.findViewById(R.id.firstLineText);
firstLineButton=(Button)itemView.findViewById(R.id.firstLineButton);
firstLineButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ParseObject obj= new ParseObject("newMessage");
obj.put("imageDetail",firstLineText.getText());
obj.saveInBackground();
}
});
}
}
}
I have a recyclerview which includes a checkbox. I had implemented click listener to that checkbox . But my current issue is checkbox is working only when I do a long press.
here my code is.
My Recyclerview item.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#color/cardview_light_background"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp">
<ImageView
android:id="#+id/PROJECT_image"
android:layout_width="match_parent"
android:layout_height="#dimen/list_item_avatar_size"
android:background="#drawable/mirlogo"
android:scaleType="fitXY" />
<RelativeLayout
android:id="#+id/label"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#drawable/labelsale"/>
<CheckBox
android:id="#+id/PROJECT_fav"
android:layout_width="30sp"
android:layout_height="30sp"
android:background="#drawable/selector"
android:button="#null"
android:layout_margin="10dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
</RelativeLayout>
My Adapter
public class HomeDataManager extends RecyclerView.Adapter<HomeDataManager.RecyclerViewHolder> {
public static class RecyclerViewHolder extends RecyclerView.ViewHolder {
TextView mProjectName;
ImageView mImage;
CheckBox mCheck;
RecyclerViewHolder(View itemView) {
super(itemView);
mProjectName = (TextView) itemView.findViewById(R.id.PROJECT_name);
mImage = (ImageView) itemView.findViewById(R.id.PROJECT_image);
mCheck = (CheckBox) itemView.findViewById(R.id.PROJECT_fav);
}
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerview_item, viewGroup, false);
return new RecyclerViewHolder(v);
}
#Override
public void onBindViewHolder(final RecyclerViewHolder viewHolder, int i) {
// get the single element from the main array
final HomeProjects projects = HomeProjects.PROJECTS[i];
// Set the values
viewHolder.mProjectName.setText(projects.get(HomeProjects.Field.NAME));
viewHolder.mImage.setImageResource(projects.geti(HomeProjects.Field.IMAGE));
viewHolder.mCheck.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Snackbar snackbar = Snackbar.make(v, "Item Favorited", Snackbar.LENGTH_SHORT);
snackbar.show();
}
});
}
#Override
public int getItemCount() {
return HomeProjects.PROJECTS.length;
}
}
Remove your custom RecyclerClickListener and implement setOnCheckedChangeListener for checkbox in the constructor of RecyclerViewHolder.
itemView.mCheck.setOnCheckedChangeListener(new OnCheckedChangeListener(){
#Override
public void onCheckedChanged(){
//Implement your code here}});
For handling RecyclerlayoutClicks:
This code should be used in the constructor of RecyclerViewHolder class.
itemView.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
//Your Code}});