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
Related
I need the functionality to update the data in the item in the recycler view. right now, If we notify the whole item it shows some fluctuation and we want to avoid refreshing the whole item on the UI.
I am using the ListAdapter with diff utils.
There are many ways to achieve your goal.
self-managing items. Adapter doesn't know anything about content of the items, it only puts items into RecyclerView. Content is managed by the item itself, so your problem is already solved.
custom adapter. Adapter has intricate knowledge about every item and can update selected ones accordingly.
AsyncListDiffer You can add differ to your adapter and it will take care of not updating parts that need no update.
Without seeing your code, we can't tell which way would be the most appropriate for you, but I guess adding differ is the simplest on already working code.
You need to create custom Adapter:
https://developer.android.com/develop/ui/views/layout/recyclerview
If you're talking about updating specific list items, and you're not using a DiffUtil (which will handle it for you) then you need to call the appropriate notify* method on your Adapter.
They fall into two categories, item change events (where the item list stays the same, but the displayed data for one or more of those items changes) and structural change events (where the actual list of items changes in some way, e.g. insertion/removal, or reordering).
I'm assuming you just want to update the displayed data for an item, so you should use one of the notifyItemChanged or notifyItemRangeChanged methods to inform the adapter that a certain item (or range of items) needs to update. If any of those items are currently being displayed in a ViewHolder, then onBindViewHolder will get called again for those items - which is where you set all your text, images etc depending on the item you're displaying. So you'll update them with the current data.
Both those methods have a version that takes a payload Object/Any, where you can pass in some data to be used in a partial bind - basically, onBindViewHolder can receive that data and be smarter about the update, which means you can avoid things like reloading images, etc. by passing in some stuff and checking for it during the binding process. More info about that here in the other version of onBindViewHolder you can implement, if you need to.
When it comes to a screen that contains 2 different lists depending on the state of say a checkbox at the top, is it better to use 2 listviews that you hide/show when the checkbox is selected or should I have 2 different adapters and attach/detach each from a single listview?
Are there any benefits/downsides to either of these solutions?
You should go with 2 adapters and 1 ListView. the reason is simple - either way you are going to have 2 Adapters (as per your question). Having one ListView would make the code simpler and there will only be a single instance in your xml file. Depending upon the state of the checkbox, you just need to change the adapter the listview points to and notify of this change.
If you had two list views, you would have to hide one. Just because the ListView is hidden doesn't mean that Android does not have to bother about it. You just have an object (size will depend) consuming resources sitting in the background.
Both of the proposals are wrong.
If we assume that you have same Object type to be listed in a ListView (Let's say a user object with name and id fields), then you need to have one ListView and one Adapter. When user wants to switch the data, what you need to do is to send the new data set to your adapter and then refresh it by calling notifyDataSetChanged(); method of adapter.
The title doesn't really cover it all. It's basically the following use case:
Select a bunch of items in a listview
Move to the next activity
Show the selected items in this new activity in a listview
If the user decides to move to the previous section the same items should still be checked
If I were using POJOs I could simply add an OnItemClickListener to the ListView and add the items to an array each time user clicks an item and ship this array to the new Activity. However the ListView is populated using a Loader which gets the data from a ContentProvider and puts it in a SimpleCursorAdapter.
In the current state I can think of a few possible solutions:
1) Add an extra column to the relevant table of the objects in the ListView. Each time the user selects an item this column is updated to indicate it is selected.
This has a few advantages:
Once I have moved to the next Activity I can simply query for all selected items.
When moving to the previous activity I can use this column to show a selected view.
But also a few disadvantages:
Requires an update each time an item is clicked, triggering the loader.
Requires a custom adapter which uses the state of the new column to decide whether it should or should not be shown as checked. Possibly creating a delay between clicking an item and actually showing it as checked.
The default check options in the ListView will be unusable
2) Track the IDs of checked items (using OnItemClickedListener or getCheckedItemIds) and pass them to the next Activity. In the new activity I then create a selection argument of "ID = ? OR " repeating N times (and excluding the last OR) and use the given array as the selection arguments.
Advantages:
No need to keep updating the database.
No extra columns in the database.
Item checking has no extra delay.
Default check options from the listview still usable
Disadvantages:
Moving to the previous activity is now harder. I could return the list of selected item IDs, but the listview only has the option setItemChecked which takes a position. So I'd have to iterate over the entire adapter to find the positions of the items and set them as checked.
I'm probably capable of implementing them without any hassle. At the moment I'm gravitating towards the second option.
So ultimately I have the following questions:
Is there an easier way to do this in Android.
What would be a good way to recheck the items (see the disadvantage in the second suggestion and if there's no better way to do it).
This ListView will also get a search function which will probably again make it a bit harder because if I'm not mistaken filtering resets it every time. So I'd also have to recheck items every time (ideally during filtering).
Your disadvantage "Requires an update each time an item is clicked, triggering the loader." is not quite true it will trigger only if your ContentProvider calls notifyChange you could have it not to call notifyChange in some specific cases
and pressing back by going to the previous activity shouldn't be that hard only if you explicitly call finish() on your activity, otherwise it should be able to save its state onSaveInstanceState
Either way i would use a third approach and simply wouldn't use a second activity but would keep everything inside a single activity use pearhaps two Fragments one for the initial check list and the second one for your second preselected list and would use callbacks and let the activity manage all,is that possible for your use case ?
I'm writing my first Android app and want to pick up good coding practices. I have an Activity which contains a 2-column grid of all the data items available in the app (listActivity). There's an Activity to create a new data item (createActivity), which is triggered from the listActivity. Now, when the createActivity finishes, what is the best way to handle this situation with respect to the following:
Should the createActivity store the new data item in the permanent storage and return only the ID of the newly created item to the listActivity OR should it return all the data fields of the item as putExtras() of the returnIntent?
Should the listActivity 'repaint' the entire data view or should it simply append the newly created data item dynamically? Will the answer to this question change if the listActivity also has to handle delete & edit events? What if the list view is NOT a 2-column grid but a single column list?
Should the createActivity store the new data item in the permanent storage and return only the ID of the newly created item to the listActivity OR should it return all the data fields of the item as putExtras() of the returnIntent?
That depends on what your listActivity needs to know about the new item. Generally saving the data in storage and only sending back the ID should be enough - based on my answer to some of your following questions. You might also need some indicator of the action that has been performed (Create, edit or delete).
Should the listActivity 'repaint' the entire data view or should it simply append the newly created data item dynamically?
Yes, if something in the underlying Adapters data set has changed a repaint is most probably needed (or at least calling notifyDataSetChanged() on the Adapter). If the order of the items in the list does not matter, you could just append the item to the list - but I still recommend that you save it in storage and then retrieve it when you want to add it to the Adapter. This is also why you would only need to pass the ID around. Also in order to append you would need some way of knowing if the last listitem has one or two columns filled.
Will the answer to this question change if the listActivity also has to handle delete & edit events?
The edit functionality is basicly the same as created (except the fields have values when you open the edit view). If you delete an item from the list a full repaint of the list is probably the best thing to do, as to not confuse the order of the items.
What if the list view is NOT a 2-column grid but a single column list?
Appending would be easier - but there is not much difference. In a single column list you might be able to avoid some full repaints that would be needed in a 2-column list - though I don't think it will make much difference.
I want to have a Button that when clicked, removes all the checked items in the ListView. I already have all the xml items set up, I just don't know how to write the java code.
The ListView displays data that comes from an Adapter. In order to remove items from the view the item needs to be removed from the Adapter and the view notified. In android the Adapter notifies the view by calling notifyDataSetChanged().
How to remove an item from the adapter depends on your particular adapter. The SimpleCursorAdapter gets its data from an underlying Cursor. To remove an item, the item should be removed from the underlying Cursor. For example using a SQLiteCursor a row in the database needs to be deleted.
If you use the ArrayAdapter just call remove(T object) on the adapter. It will automagically call notifyDataSetChanged() for you.
update:
I saw the code at git hub. Here are some pointers as how to get your app working as soon as possible.
Try refactoring your code in to smaller graspable parts. Start with extracting some methods to give parts of the large method understandable names.
The problem is that there might by hundreds of rows in the database and only enough views to fill the screen. Nowhere is it remebered what rows are checked, hence its not possible to remove them. You probably need to extend BaseAdapter or SimpleCursorAdapter to hold the state (checked or not) of the rows. Read up on the excellent android documentation.
My point here is there is a distinction between the view, your CheckBox, and the model containing the data to display. So check out Model-View-Controller. You can ignore the concept of controller for now.