Suppose I have a listview with 3 rows. If the user clicks a button in row 1, it expands a menu (it's just a linear layout that's shown/hidden). If they then click on an item in row 2, I'd like to be able to collapse the menu in row 1. Is this possible? If so, how?
Save a reference to the View you would like to manipulate later. Probably wrap in a final variable, then you will be easy to change.
You can always use getContext() on the View to get a reference to the containing Activity, which you can cast to a ListActivity (assuming you're using that) and call the usual methods to get the data at that position in the ListAdapter:
((ListActivity) v.getContext()).getListAdapter().getItem(1)
Then you can manipulate your data however you want to and call notifyDataSetChanged() on your ListAdapter.
But it'd probably be a lot easier for you and your users to just use ExpandableListView, which gives you expandable lists with predictable interactions your users already know. You can check the history activity in the Browser source code in AOSP for a real life example. And if it doesn't exactly meet your needs, you can always yank the code for ExpandableListView itself from the Android source.
Related
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.
If you are creating a very dynamic list, say, where every row can have a different set of input types plus optional buttons, and the list length is based on another dynamic value, is it better to do this in a list adapter or creating a custom view in a scroll window?
After struggling with list adapters for quite a while now something finally occurred to me- this seems dumb. It seems like I am going through a lot of work keeping track of what spinner is set to what value, which row was clicked and so forth.
For example, say you are showing something like a contacts screen with various details that can be entered about a contact. Some rows will have text inputs (name, address etc), some will have spinners (ie. state, group), some will have checkboxes (like 'favorite' or something). Also, there is an 'add' button that allows you to add another field to edit. Is it worth making this in a list adapter or is it better to populate a custom view, and if the "add" button is clicked, we re-create the custom view, adding a view of the type they want to add?
I hope this is clear.
ListViews (and List Adapters) are meant for data that is to be displayed in mainly similar views. For your example, it is much easier and more natural to have a predefined layout file with the screen and use view visibility so select which views are to be shown. If you need to add views to the screen you can do this dynamically by using findViewById on the layout and then using it's addView method.
Let me know if you need more clarification or sample code...
My problem is similar to ListView getChildAt returning null for visible children, but despite searching I cannot find a solution.
I have a ListView with a Scroll. The ListView has 10 items, 7 of which are visible and 3 are hidden by scroll. I also have an external method (out of adapter) that must get all of the children from this ListView (e.g. using getChildAt()).
I need all 10 of the items, but the last 3 are null objects. I've tried code like the following:
getListView().smoothScrollToPosition();
But this doesn't work.
I think that I don't need to post the rest of my code, as the description says everything?
As you have already seen you can't get all the child row views from a ListView simply because a ListView holds only the views for the visible rows(plus some recycled rows but you can't reach those). The correct way to do what you want is to store whatever data in the adapter's data and retrieve it from there.
But the ListView doesn't keep the current values from RadioGroup in
running time.
I've seen that you have some problems with this so I've adapted some old code to build a basic example, code that you can find here.
I don't think so you need to add scroll view for a listView. Scroll automatically works on ListView. Try your application without adding scroll view and I'm sure it'll work as you needed.
The reason those children are null it's because they really do not exist and they will never exist, if only 7 children are on the screen at one time, the system will only create 7 and re-use by passing the convertView back to the adapter getView() method.
If you want to grab information regarding your whole dataset you should search on the dataset itself, instead of the views on the screen. E.g. if it's an ArrayAdapter, loop the array; if it's a CursorAdapter, loop the cursor; etc.
The non-visible children of a listView don't actually exist. When they become visible, one of the redundant views is recycled or a new view is generated. So you can't actually access all the views. Why do you want to? Whatever changes you want to make should be made to the data that populates the views rather than the views themselves.
There are a few point that you need to take care of:
1. List view provides inbuilt scroll functionality, So don't use Scroll view. It will only mess up things.
2. List view doesn't contain ALL the children. When you scroll it, it creates only visible items on run time.
3. If you want to get all the children altogether, Better keep an ArrayList of the child objects that your list has. You can add or remove children to this ArrayList as per requirement.
I'm making an app in which the user can log simple timesheet-like transactions into a list. I have done this with a listview which is connected to a sqlite query with a custom CursorAdapter descendent. So far it is working well.
What I am trying to do next is let the user add any number of "tags" to an individual transcation (think labels against emails in gmail). I have a many-many-relationship table to link tags to transactions, but i'm unsure how to modify my existing listview and cursor arrangement so that each individual record can load and display its tags.
One thing that comes to mind is to load all the data into a two-tiered object structure, then use that as the datasource for the listview. I don't like this idea though because it will certainly cause a delay in loading, whereas using a CursorAdapter seems to be better for performance.
The way I was intending to display the tags within each listview item was just as plain text, linearly along the bottom of the row with different colours using Html.fromHtml(). I already have this part working so i was hoping to stick with the existing listview (if possible). My problem is purely about finding the best and most efficient way of getting the tags out of the DB and making them available to each row in the listview.
I'm very new to android - is there a clever way to do this or is it going to be a manual exercise?
There's no shortcut for this. You're going to have to create a View by subclassing LinearLayout, RelativeLayout or whatever you want. In your View class expose a public method like 'setTag(tag)' which takes an argument as to what tag to set the corresponding data to. In your View you'll have to have some field which maintains a reference to that View. In other words, somewhere before you return your view in getView in your Adapter, you can bind the data to the View and then alter its state from within the View.
I want to design a list with options to sort it in ascending or descending orders. I am able to do that using different intents. Is there a way to do that without having a new intent?
The example that comes to my mind is Manage Applications in android. Sort by name and size happen on the same screen. How is that done?
Edit - I have a list of say 20 items. Right now, I am sorting the list items and displaying only the top 5 items. I want to add an option to display the bottom 5 items too. I have done that by creating a new class exactle the same as prev class with top array replaced by bottom array.
You can re-sort the underlying data structure before setting it in the adapter.
Usually a list is displayed using a ListView.
ListViews usually have an adapter associated with them. The Views are listed in the order they exist in the adapter. So to change the order of elements in the list , all you have to do is set a new adapter to it where the the elements are ordered as you wish (You could also try to change of the order of elements of the existing adapter, but I don't know if it can be done).
You can see the ListView Hello World Example to have a better understanding of ListViews.
Umang, I don't have eclipse on hand now and I just want to express my train of thought to solve your problem. Please write the codes yourself and test it.
There must be an adapter associated with your listview, inside it, you can set a variable to moniter the order mode, like: private int mode;
Inside the getView() method of the adapter, based on the mode, return the items as you want.
I think you have finished the steps above, since you can change the order already.
In the first Activity, you can set some event for the user to chage the order, i.e, via the Menu. So you override public boolean onCreateOptionsMenu (Menu menu).
In the corresponding public boolean onOptionsItemSelected (MenuItem item), you set the mode value based on the item index the user selected.
Call adapter.notifyDataSetChanged() to notify the system that the data for the listView has been changed.
call listView.invalidate() to show the new ListView.
The ArrayAdapter class has a built-in method for sorting via "sort (Comparator comparator)", provided you are willing to go to the trouble to write the Comparators that you need to do the sorting. I use this method to sort "in place", without having to re-load the adapter with an externally re-ordered list.
Check out http://developer.android.com/reference/android/widget/ArrayAdapter.html
and http://developer.android.com/reference/java/util/Comparator.html