Start a ListView with the first item clicked - android

I have a layout that consists of 3 contiguous ListViews. Selecting an item in the left most list will start the second list, and so on. I am trying to begin the fragment with the first item in the left most list selected, and because a lot of logic is required, I am attempting to trigger on click instead of redo-ing all the logic. I am using this:
mListView.performItemClick(mListView, 0, mListView.getItemIdAtPosition(0));
Is what I am attempting possible? and if it is, where do I call this?
ANSWER:
So it seems that the reason this wasn't working for me is because I was manually highlighting a View within the row View and it wasn't instantiated yet (or something like that).
I used this code to call it after the ListView was laid out:
mListView.post(new Runnable() {
#Override
public void run() {
mListView.performItemClick(mListView, 0, mListView.getItemIdAtPosition(0));
}
});
EDIT:
I have 4 lists that depend on data being sent from the previous ones before being instantiated, and for some strange reason, this runnable method only works for the first list. For the others, I used this answer: https://stackoverflow.com/a/15399035/1549672. Also, strangely enough, this does not work on the first list. All the lists are nearly identical.

As per earlier comment:
You can try wrapping the selection change in a Runnable and post that to the ListView. That way the selection change will not happen until the ListView (and its children) has been measured and laid out etc. Do make sure you set the adapter before attempting to change the selection.

Related

Issues with small RecyclerView with EditTexts and Checkbox

I have a small list of almost 10 items (and this will not be greater than 20 in any case). It will not be changed after activity is created.
My Current Setup:
I am using a RecyclerView for the list.
I have a Checkbox and 2 EditText (say 1 and 2) in each list item.
I do some calculations based on if checkbox checked and the value of EditText-1 and populate the new values to another EditText-2.
On some cases user edits the Value of EditText-2 and calculations happen again and it will be populated in all other places including EditText-1 of for all the items.
Problems solved:
However, in this situation I was facing issues with the TextWatcher called multiple times. I solved it with this: https://stackoverflow.com/a/31860393/1820644
Changing Checkbox values changing some random other checkboxes. Solved it using this: https://stackoverflow.com/a/38549047/1820644
Another Problem:
Now, as data change of EditText-1 changes values for all other items of RecyclerView, I am calling notifyDatasetChanged() to reflect the changes after doing calculations. But this causes the EditText to loose focus. And it intends as all the views are recreated after notifyDatasetChanged. Even stable ids are also not useful in this situation. (There is bug related this issue: https://code.google.com/p/android/issues/detail?id=204277). The value is not even reflects and EditText looses it focus.
What can I do?:
Is there any workaround? I am seeing strange changes in items values after setting stable ids.
As the Items are fixed and no items are added and removed after onCreate, Using a scroll view with the container and adding items by manually inflating views in loop (and updating also will be ease, I think) will make my life a little easier?
Lets take an array of objects to save the statuses of your EditText along with the values to be populated in your list. For example each of your items in the list might look like this class.
public class ListItemCustom {
// Add some extra parameters to handle the state of the EditTexts
public String textOfEditText1;
public String textOfEditText2;
public boolean focusEditText1;
public boolean focusEditText2;
// Contains original values of your list item
public OriginalListItem mOriginalListItem;
}
Now take an Array or ArrayList of ListItemCustom custom and populate your items there inside onCreate. Then pass this list in your adapter and then handle the EditText and the values accordingly.
Hope this helps.
The solution is simple, don't call notifyDatasetChanged() when your data is changing instead call notifyItemChanged() or notifyItemRangeChanged() which will update only that view which has the changes and your focus will remain as it was.

Android - dynamically update GridView views

I've got a GridView with a custom Adapter, displaying thumbnails of pictures to the user. I can select and deselect pictures (I use setAlpha(0.25) on the views to notify the user of the change), and that's all well and fine.
Now what I want to do next, is have a button on top of the gridview that clears the whole selection, i.e. call setAlpha(1.0) on all views that were changed. So far I can reset my elements in the adapter, and I can setAlpha to 1, but the view doesn't update unless I scroll it out of the display, and then get back to it, or notify the adapter of changes, which redraws all my views, which does not look too pretty if only one element was selected.
I already dynamically set and reset individual elements through the GridView's onClickListener, but can't do this for more. I even tried calling performClick on all selected items through my button, but again it only displays the changes after the views have been out of the screen and are shown again.
Here's how I simulate the clicks:
for (int i = 0; i < mAdapter.getCount(); i++) {
PictureForSelection tempPic = (PictureForSelection) mAdapter.getItem(i);
if (tempPic.isPicSelected()) {
//tempPic.setIfSelected(false);
gridview.performItemClick(mAdapter.getView(i, null, null), i, i);
}
}
EDIT:
Conclusion - don't simulate clicks like this :)
So now I skip click simulation and use this:
gridview.getChildAt(i).setAlpha((float) 1.0);
In general it does exactly what I wanted it to do, except for one case:
If I have for example 3 pictures selected, one is off screen, one is partly shown, and one is fully shown, the ones shown (even partially) don't update their views.
If all the selected pictures are displayed it works flawlessly, but if some are out of the display, the rest do not update until the adapter's getView() gets called by Android. Still, thanks #mmlooloo for getting me so far.
If anyone knows a way around this, please do share :)
After setting your alpha you can call imageview.invalidate(); this causes your imageview to redraw itself.
if notifyDataSetChanged() is not working you can try like this.
i'm not sure whether this works,
1.onclick of the button you set the gridView.setAdapter(null);
2. Then set a new CustomAdapter object to gridview with default values.

Updating specific ListView items when resuming activity

I have 3 activities containing listviews with custom adapters, an item selected at the first one drives the user to the second one, and so on...
At these listviews, some items are highlighted as "new itens" (each time adapter's getView is called, I check at a database if the current item should be highlighted). Once user has reached the 3rd listview, I mark these items as "checked", and want to propagate this change back to the other listviews...
That means, when user comes back, pulling the 2nd and 1st listviews up from the stack, I want the viewed items not to be highlighted anymore.
I've tried this answer on SO, without success. When executing notifyDataSetChanged() from onResume(), my listview simply didn't shows up. And I'd prefer not to use startActivityforResult()...
here's my code to refresh the listview at onResume():
#Override
public void onResume(){
super.onResume();
//I have basically the same code at onCreate()
adapter = new ListingsAdapter(getApplicationContext(), this);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
here's another answer that sounds promising, but I wasn't sure how can I retrieve an specific view from the adapter... I want to check all visible items with adapter.getView(), but it asks for a convertView and a parent ViewGroup and I couldn't get that
Thanks in advance for any hint on this
Why don't you wanna use startActivityforResult()?
You don't need to create a new adapter every time in onResume(). You only need to change the underlying data (set the checked flag for the visited item) and then call adapter.notifyDataSetChanged(). This will trigger the adapters getView() method for all the visible list elements.

How to change ListView item before it is rendered

I have following code that works fine when my ListView is already rendered (eg. when fired by onClick events, etc.)
TextView tv = (TextView)list.getChildAt(position); //list is my ListView
if (tv!=null) {
tv.setPaintFlags(tv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
}
However, sometimes I need to apply this STRIKE_THRU_TEXT_FLAG flag to some items of ListView when activity is being restored (after rotation, restart...). If I try to run this code in onCreate or onStart methods then list.getChild(position) returns null because no ListView item is visible yet (in fact screen is black at this time and actual drawing seems to be done in some later function).
Is there any easy way how to get around this? Maybe getChild function is not the best for this case...Or would you override rendering function of the ListView to make it work (seems like overkill to me)? Thanks
Don't modify the view itself like that; modify the actual data object that represents that list item (for example, if your ListView is backed by an ArrayAdapter, this would be the array item for that list position). You could set a flag or property to denote that the item should be displayed differently, and then add some conditional code to your adapter's getView() method to display the text in the proper style based on the properties of that list item's object.
You can then let the view render itself accordingly the next time it's shown, or trigger the redraw yourself by calling notifyDataSetChanged() on the list adapter.

how does scrolling in android listview work?

I have an android-app with a listview in an activity. The listview has, if I call it so, three data states.
no data loaded from inet -> only one dummy item is visible, saying that data is loading;
data is loaded and shown in list;
one listitem is clicked and now shows more information for this listitem (so it is increased in its height).
On every state change (1 -> 2, 2 -> 3), I call notifyDataSetChanged() on this ListAdapater.
This causes the listview to scroll down to the last item. This is ugly in the first transition and even more ugly in the second because the clicked list item is now out of focus.
As I can see, this happens with a google g1 with android 1.6. An htc touch with the same sdk acts like desired (I will try to figure it out with some more devices).
To avoid this, I tried to read out getScrollY() and set this value back. but this returns 0. The reason for this return value I already found on stackoverflow in other questions.
Has anyone else seen this problem? Why does the listview scroll to the last item? It was mentioned that listview keeps track of the scroll position. but it seems that it does not in my case.
Or maybe I am calling the wrong refresh method? Is notifyDataSetChanged the correct one?
I believe you want:
listview.setTranscriptMode(ListView.TRANSCRIPT_MODE_DISABLED);

Categories

Resources