How do i get a specific view inside of a RecyclerView item? For example I have a floating action button inside of a recyclerview item. The recyclerview card can swipe to trigger an event (new activity) and when the user swipes i am making the fab invisible. I want so that when the user returns back to the activity with the recyclerview, the fab is visible again.
I've tried to implement this a few ways, but for some reason it's taking the fab from the NEXT card/item and placing it on the original card/item that was swiped. This is a problem because the next card might have a different colored fab or no fab at all. What is happening is that it's taking the most recent viewholder item, even if the previous one is the one I want to deal with.
So i need a way to reference the fab in the current item. I'm currently setting it to currentFab = holder.mFab (but again, it's taking the most recent holder item even though it's not the one I pressed on). I need a way to reference the fab in a specific item.
I've tried something similar in the past, I've added the Swipe function in "onBindViewHolder ", Using a Swipe Library.
What I have made is, A CardView, Inside it there are 2 Strings, And a Button, this Button will be invisible according to specific conditions, So because it's inside onBindVewHolder, it was easy to make some edits on the button.
Here's a sample :
holder.Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.Button.setVisibility(View.GONE);
}
});
Ofcourse this isn't a "fully working code" it's just an example, Plus you didn't put any code that you have tried.
Related
I want to catch a vertical swipe in an horizontal RecyclerView. Each item is simply a CircleImageView.
I found many resources on internet (like Drag and swipe with RecyclerView, Android - Swipe to delete RecyclerView) but those solutions ends deleting the item. I don't know if the term swipe requires also that the item is deleted or not.
What I want to achieve is to catch the swipe action on an item in the RecyclerView, but without delete the item itself from the RecyclerView.
I think that a good idea is to override the method onChildDraw() like suggested here: How to detect if Recyclerview item is being swiped?, but I can't understand how to achieve the behaviour I want.
My idea is: while the user swipes an item, the item itself moves in that direction; when the user end the touch event, the item has to come back to the original position (maybe changing the background color).
EDIT 1:
How to have swipe to delete and swipe to archive in two colours in Recyclerview Android probably can help, but it doesn't achieve the behaviour that I need. The item has to come back to the original position.
Your RecyclerView has RecyclerView.Adapter attached to it. The adapter determines what information that the RecyclerView can see and display. So, if item number 10, out of a 100-item backing array (managed by you) is swiped, the adapter can report that the array now contains 99 items and not ever present the swiped item to the RecyclerView. That way the item appears to be deleted but is maintained internally and still accessible programmatically. How you manage that internal state is up to you and dependent upon your implementation.
If, however you want to not remove the item from the screen but just change its appearance, I think that you would need to look at the method onItemDismiss that actually removes the item and notifies the adapter of the data change.
public void onItemDismiss(int position) {
mItems.remove(position);
notifyItemRemoved(position);
}
It is here that you would make the change. The item would stay in the adapter. You would also need to flag that position as "swiped" in case the view holders are recycle so you can maintain the visual "swiped" state.
public void onItemDismiss(int position) {
// Change background color, etc.
}
Take a look at code that has a "swipe to delete" function with "undo" for some ideas. Here is an example with a dialog that is called before deletion actually occurs if "Cancel" is clicked. There are many other examples of "undo" available. What you are trying to do can be considered to be an immediate and implicit "undo" with a visual change to the background.
If you want to have the item move back into position after a swipe, the following should work:
public void onItemDismiss(int position) {
notifyItemChanged(position);
}
inception sounds
It might not be the best idea, but here's a 4 second gif of what I'm trying to do and the problem I've run into.
https://i.imgur.com/Z3iAyNc.gifv (sorry, embedding wasn't allowed).
I have a RecyclerView with in each item a LinearLayout with category details and a hidden LinearLayout with another recyclerView. The idea is you see the categories, and once you tap on it, it expands to show the relevant posts. Another tap on the category should open the category detail page and a tap on a post should open the relevant post detail page.
I have it working, but as you can see in the gif, I have to tap at least two times, even though I never wrote it like that. It's the same for the LinearLayout's onClickListener It's like the parent RecyclerView hijacks the first tap.
Here's a schematic rundown of my code
adapter.setOnItemTouchListener(new RecyclerItemListener.RecyclerTouchListener() {
#Override
public void onClickItem(View v, int position) {
final LinearLayout postView = (LinearLayout) v.findViewById(R.id.profileCheckinDetailsView);
// The IF statement prevents reloading the view when it is already open.
if (postView.getVisibility()==View.GONE){
RelativeLayout itemView = (RelativeLayout) v.findViewById(R.id.ItemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
[... etc]
And beneath it there's another setOnItemTouchListener for the child RecyclerView.
Am I doing this right, and if so, how to make sure both items register the first tap as well?
Thanks in advance!
Sometimes typing out a question helps you think differently. I removed the top recyclerview's touch listener and replaced the item layout with this. Both layouts get their own onClickListener. With ((LinearLayout)v.getParent()) I managed to have them control eachother.
Much easier and more effective I believe.
I am trying to attempt the below :
What i am trying to do is whenever a user click on a button, it will add a image to the layout(which the user can scale and move to any position within the layout). The user can repeat this process hence if the user click 6 times on the button, there should be 6 image in the layout.
i have google around, looking for some sample but ain't sure if its the correct one to use. maybe i did not use the correct keyword to search. So far i have seen is endless adapter and RecyclerView but both seen to be mainly for "ListView" type.
Anyone can suggest or share a link/example that i can read up and learn from? It will be a great help.
If you want to add image on button click set on-click listener on it. You need to get how many time the user have clicked the button.
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//get adapter and view
//get image to add
addImage(i); //to desire view
}
});
I added a button in a listview item, and after the button is clicked, I want the button is disabled. I used the below setOnClickListener for my button in the custom adapter, but the problem is when i clicked on a button, the button of another list item will also be disabled. For example, when I clicked the button of item 1, the button of item 1 then is disabled, but the item 4's button will also be disabled at the same time although i didn't click on it.
And also, when I scroll up and down, all item's button just enable and disable randomly.
Anyone know why is this happening?
holder.viewBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.viewBtn.setEnabled(false);
showInfo();
} });
I was so frustrated when I first faced this problem!
The problem here is that the listview just doesn't remember the state of the button. Dunno if it is a bug but anyways I needed a way out and this is what I did.
I believe you are using a custom adapter with a viewholder. Means you are on the right path. You need to keep an array of booleans whose size is equal to the number of items in your list. in your btnClick() set the state of the item in the array.
Now everytime you scroll, or do soemthing that makes the list redraw, getView() is called. Put a check in your getView() for the items state and enable/disable it. One more thing, Make sure you implement both if{} and else{} for the check.
if(checked){
holder.viewBtn.setEnabled(false);
}else{
holder.viewBtn.setEnabled(true);
}
if you don't do this you'll see weird behaviours. One more thing if you are using the
if(convertview == null){
//create the holder
}else{
convertview = getTag();
}
method, make sure you populate the state after the above step.
I have not seen your implementation but I had to pop up a button in the item and then delete the item from the list using it. So I had to take extra care for maintaining the state.
So be careful about the states once the underlying data has changed.
Sorry about the long post but the problem is such :(
I found a link that has the solution in a basic format
This is happening because ListView reuses Views in an erroneous manner. Either implement your own ListAdapter without View reuse or file a bug report with Google
Activity1 has a listView. Clicking one item (let's say item 3) will start Activity2. Activity2 have a back button once clicked will bring user back to Activity1. What I want to achieve is to highlight the item 3 when user back to Activity1 so that the user have a sense where to continue. (May be i need to set the focus to item 3 as well.)
EDIT: Following code works.
public void onResume()
{
super.onResume();
//lastSelectedPosition saved in OnItemClickListener
lv.setSelection(lastSelectedPosition);
lv.requestFocusFromTouch();
}
well its pretty simple. just save the clicked item position of the list to a field when the list is clicked to launch your new activity.
Afterwards in the onResume() method just use myList.setSelection(savedPosition);
as for the highlighting, well focus works kinda bad especially if you have a bit more complex rows(buttons,checkboxes etc) and other ui elements beside the list that can take away the focus. i believe the best way to achieve this is just set the background of that particullar item onResume to the highlighted one and override onScroll listener to just change the background to your default when the list is scrolled. indeed its a workaround but it will work in 100% of the cases opposite to just focusing an item. plus maybe you can add animations on the view so you can make it look really nice and smooth.