I have a ListView backed by customized ArrayAdapter where each item has 2 LinearLayouts - one I call head, and the other one - body.
The body is hidden (gone) until user clicks on the row at which time it slides out. The second click (on the head) will hide the body. However if user clicks on the body it brings another activity. All of this works just fine, here comes the problem:
When user presses on body I want a visual indication of the action just the same way as regular list item will flicker an orange background when pressed. I'm not getting this by default since (my theory) the onPress event is intercepted by body's view and not processed by the list item.
The first thing I tried was to execute body.setBackground('#ff00ff') (never mind the color) in onPress event. That didn't work since (I suspect) there's no repainting after the call. Then I dig a little bit more and decided to use <selector/>-based background. I defined body_background.xml in drawable folder and assigned that to the body's background property.
There I noticed that background will only change if the even is processed by the list. For example if I set <item android:state_selected="true" android:drawable="#drawable/selected"/> then when I press on the head - the background of both elements (head and body) will change, however when I press on body - nothing.
So to summarize my question - how do I change background of the child element in the list item if I assign custom onClick handler to it? Any hints will be greatly appreciated
OK. Here's some more info I dig along the way.
I'm currently trying to switch implementation to ExpandableListView which provides the functionality I had to coded in (sliding body). The problem I may have here is that I have a fancy "endless" list implementation and I'm using ArrayAdapter#add method to dynamically add items to the list while scrolling (see my tutorial on androidguys.com) Well, the add method is missing from the BaseExpandableListAdapter so I need to see if adding items to internal array will work (it didn't for ArrayAdapter) possibly doing ExpandableListView#notifyChanged() will take care of that
The fact that I don't see anything when I'm directly using setBackgroundColor method is probably due to the subsequent call to startActivity call that halts all painting until new Activity is displayed
P.S. this has been resolved by switching to ExpandableListView. And may I add - it's beautiful! No need to invent anything
Related
First of all, I have looked at similar questions (for example, this one: Android RecyclerView ItemTouchHelper revert swipe and restore view holder). This already helped a great deal, until I - more or less, accidentally - noticed my current (and hopefully, final) issue with this screen of mine.
Let's start with the setup:
I have a fragment with a RecyclerView filled with some CardView items (it's a little fancier, but that's what is important right now). I also created an ItemTouchHelper with the implementation of SimpleCallback (nothing in onMove()) to make swiping the items (right) possible. For the record: I am using API 27 right now.
So far, so good.
What I want to achieve:
I want to be able to swipe the items to be notified through the onSwiped() method of my SimpleCallback implementation. Also, I do NOT want the items to disappear, be removed, or otherwise taken out of my list of items in the RecyclerView. I just want to swipe them and have them return to their original position afterward (and yes, I know that it is sort of assumed that swiped items get removed). I am using the notifyItemChanged() method of my adapter in the onSwiped() method (also tried using notifyDataSetChanged()).
The problem:
Funnily enough, that works (mostly thanks to the aforementioned question) - until I hit that "app switch" button (don't know if there's actually one official name for it) and send the app to the background. Once I put it in the foreground again and start swiping, the items will not (visually) return. They are still on the list, and if I scroll or click the "app switch" button again, they will be displayed properly again (but won't return on swiping). Same if I navigate back one screen and come back to the list.
That makes me think something happens when I send the app to the background and recover it. Something different than navigating to that screen (in which case everything works as intended) - which I thought would more or less produce the same results. Any ideas what I might be overlooking here?
After some testing, I finally found the source of the issue:
I had both the RecyclerView and its Adapter initialised through onStart() of the Fragment and not onViewCreated(). After changing that, I got the proper results I wanted.
Lesson learned: Set your RecyclerView's Adapter as early as possible, unless you want to deal with sometimes strange issues.
I would like to start by saying if you can think of a better title for this problem, feel free to change it since I have no clue how to explain this in a short way.
So here is my problem:
For the application I am trying to make I have these schedules, one schedule for today, and one for upcoming days. Both of these are a listview inside a fragment.
(I used those fragments to create tabs to seperate the two.)
Each game (let's call them games because calling them activities would be confusing) on the schedule has a status, and here is where the annoying part comes. I have been asked to check if any game has been started, and if so I need to disable the buttons to start any other game than the one that is already ongoing.
EDIT: The main problem is that I cannot use findViewById on the listview item because apparently it is a null object reference
I made a little "paint"ing to give you more of a graphical representation.
So long story short, I need a way to check the status inside of every listview item inside of the listview inside of the fragment inside the activity to use said status to disable every button except for the one of the ongoing game.
Little side note: If no games have been started yet, all buttons are enabled.
I hope this made sense.
If you want some code to go with this, feel free to ask but be warned, I am making this inside a testing app so a lot of useless testing data and sloppy code.
EDIT:
This is where I am stuck in a more clear example:
The start buttons are enabled but should be disabled.
Scrolling further down the list, there is a started 'game' and right below it, a game with the same status as in the previous picture where the button is disabled as it should be.
This is because the "isStartable" boolean in my code goes to false after the game with status "start" has passed and the following items are disabled.
When I scroll back up, it is how it should be, the items are all disabled but I need them to be like this when the listview gets filled. Any way to refresh the data in this listview and taking the "isStartable" boolean with it?
This is what it looks like after I scroll back up.
create a model class for your listview data items. Set a boolean variable in model class like isGameStarted. Set that variable as per your result.Then in your listview adapter, put a condition as below
if(isGameStarted){
holder.startButton.setEnable(true);
else
holder.startButton.setEnable(false);
I'm using Recyclerview to show a list. I want to delete some items like IOS. In my listview template I have added a button to delete item which is invisible by default. In my activity I have another button attached at bottom (Not part of listview) and on tap of this button I want to make all delete buttons of listview visible.
My Question is how can I get reference to all delete buttons of listview in activity and is it the right way to do this?
Thanks
Assuming you have ViewHolders set up, you already have references to all the buttons in your list. All you have to do is to make them visible for every item in the list with a simple loop.
In case you haven't implemented ViewHolders I suggest you check out the documentation and take a look at some simple tutorials on how to use them.
On a side note. If I understood correctly you're making a bottom tab for your app and since you referenced iOS I gotta say this; Remember that Android and iOS are two unique operating systems with their own ways of handling things. Check out Googles pure Android documentation.
In your question title you say RecyclerView, but in your text you say ListView. The solution is similar either way, but it's best to be perfectly clear what you're doing.
In either case, there are at least two different solutions.
First, you could use a boolean flag to determine if all the the item buttons should be showing or not. You check this flag at the time the item view is inflated or created and toggle the button accordingly. If the boolean flag is ever changed, the easiest thing to do is tell the RecyclerView/ListView that the underlying data has changed and to redraw all the views. Call notifyDatasetChanged on the adapter.
The other thing you can do at the time the item buttons should change is iterate all the visible item views, find the button, and change its visibility. With RecyclerView, you can do this, and with ListView you can do this.
In my application I have requirement like this.I have number of data and I need to show that data on ListView kind of layout,now I have suppose total 6pages on each pages I want to show such data.I have listed number of textview on each page.Suppose i have 7pages so i need to make book kind of layout for that i am using this Code.https://github.com/harism/android_page_curl.
with this i am able to get such effect.As mentioned in below image.
Now my issue is,As OpenGl is converting entire layout to bitmap,i am not able to handle click event of textview.Whenever i click on textview on that time ACTION_DOWN method is called.and offcourse it should be called as entire layout is converting to bitmap thus we can't handle textview click event.
for making solution of this have googled and found some trick from This issue.Here mentioned to make seperate layout for handeling click listener,but not getting what exactly i have to do,as i don't have any experience in OpenGl,so if any one have idea about this issue,any one who can guide me handle click event.
The above solutions depends on your views pages. It may not work if you use ListViews on your pages or any ScrollView, you have to retest your application performance...
What i have done to get it working, is to create an extra root parent with,FrameLayout, place on top the widget, fi.harism.curl.CurlView and add PageContainer(RelativeLayout on may app).
At run time, get the drawable of your view page (View.getDrawingCache()) , and add The real PageView(witch contains click listener) to the PageContainer. Make the PageContainer alpha to 0. You have a duplicate page (transclude) to receive the page clic, the CurlView will still handle touch events for curl.
(FYI, I'm targeting 2.2 Froyo in my project, so any solution would have to work at that build level.)
What I want to do seems quite simple; show a list of items in a ListView, and allow the user to tap to select multiple items before performing an operation on all of them at once.
To provide a little more detail, I am binding a ListView to an array of objects. The screen consists of other controls, with the ListView in the middle. Each list item has several components; two images, and a text label. NO checkbox. Instead, when the user taps an item, the background should change to indicate that it is checked. If the item is tapped again, the background should change back to indicate it is not checked. The user may tap one or more items. If the user scrolls the list off the screen and scrolls it back, the state of those items should be preserved.
From what I've researched, I gather that I need to:
use a Drawable as the background for the list items with selectors for checked, pressed and default states
create a custom class extending LinearLayout or RelativeLayout and implementing Checkable, then use this as the root View for the list item layout
I've found several tutorials online, but none work. Either they have runtime errors, or simple don't do anything... pressing the buttons does not change their appearance to checked.
I found an alternative approach in the O'Reilly "Android Cookbook." Rather than doing all of the above, they add a boolean to the objects the ListView is bound to, then manually add code to change that boolean when a list item is clicked and to change the background in the adapter for an item where the boolean is true. In other words, they don't use Checkable at all. This does not seem like an ideal solution to me; abandoning the Android API in favor of custom hacks often seems to cause bugs later on, and I'm uncomfortable with adding GUI information (whether or not an item is selected) to what should be a purely data-carrying POJO conceptually representing a chunk of information.
My question is this: does anyone have a WORKING tutorial to accomplish what I have described, using Android's Checkable functionality? Or is this so problematic that something like the O'Reilly hack always has to be used?
I have never read Android Cookbook but their strategy is exactly what I would do. I would decline to call this a hack and suggest this is the kind of thing that the Android framework intends to do. A selected state in my opinion is part of the model you wish to protect, I do see how it could be in a gray area as it removes the purity of your POJO's.
There is a second strategy you could use to protect the purity of your POJO's use the state of the background to find if something is selected or not. Additionally you could also use a plain color resource instead of a drawable background.