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);
Related
I have a situation involving animation of listview's item appearances.
I have a few views in a ScollView , the last of which is the listview. I have attached an appearence animation of the row (a fade in animation).
The problem I have is that when the screen is loaded , the getView() of listview already executes for the initial items , even though the listview is not currently in view.
Hence when a user scroll downs , he sees the list plainly.
I am unsure how to go about this situation . Is there any callback that can be invoked when a row from a listview becomes visible on screen ? .
Yes there is a callback (OnScrollChangeListener), first visible index and last visible index etc. You can achieve what you are trying to using combination of these.
But you need to try that yourself first. No one can simply write a code for you.
You can learn about listview here
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.
I have a ListView and a SimpleCursorAdapter subclass that display data from an SQLite database . I have customized my adapter in such a way that when I click a listitem it expands/collapses to show more details. Everything is working fine, but I discovered a weird behaviour that's using unnecessary processing.
Let's say I have 200 items in my list, all of which are in a collapsed state (this just means that some of the TextViews inside them have visibility="gone"). Now I scroll down the list to item number 100. bindView() gets called for each item, with _id=1, _id=2, ... , _id=99, _id=100 as expected. Now I click item 100 and expand it (change some of it's TextView's to visibility="visible"). One would expect bindView() to get called for _id=100 and perhaps some of the surrounding items like _id=98, _id=99, _id=101, _id=102 because the ListView needs to be redrawn. But here's the weird part - bindView() gets called for _id=1, _id=2, _id=3, _id=4 (which are of course way off the screen). And that's not all - it does this twice, so we've got 8 bindView() calls for the first 4 items in the ListView, which are not anywhere close to being displayed on the screen. The surrounding items don't get a bindView() call, not even item number 100 gets one!
Since everything is working as it should I can live with this, but I'm really curious a as to why this strange behaviour is going on. Anyone have any idea?
I want my ListView to work something like the following:
When I press a button (probably from context-menu), I want the user to be able to select more then one item from ListView (probably using check-boxes), but those check-boxes should not be visible before that.
So, the point is, after the user presses a button (let's say "Delete more items"), the listview, should update itself, and appear on every row of the list, a checkbox should appear (allowing me to select the items ID to pass those to server).
How can I achieve that, without having to recreate the list from zero? (how to setVisibility ON, keeping the other content of the ListView as it is, and not doing another request to server).
PS. If you guys, have another better idea, on achieving the Delete More Items, would be much appreciated!
This is just an idea, haven't tried it myself: you build in a checkbox in your listitem layout. Normally, in the getView of your adapter, you set it invisible with
checkBox.setVisibility(8);
When you want to show them, you set some boolean
showBoxes
of your adapter to true, then in the getView oyu don't hide the checkboxes.
Then
notifyDataSetChanged
on the adapter.
Hope it's clear what I mean.
I need all of the other views in my arrayadapter to check their attributes and return to a default attribute at certain times
use case: listview items (a)(b)(c)(d) , when you touch (a) it's background turns black. This is done in the ontouchListener. But when you touch view (b) it's background turns black BUT (a)'s needs to turn back to the default which is not black
I dabbled around with recalling the arrayadapter at the end of the view.OnClickListener but the problem with this is that it also resets the scroll position of the view, so if this list was much longer - which it is - and user touched item (r) , then it would reset the list and put the user back at item (a) at the top
I was looking at notifydatasetchangedbut I am not sure how to use that and where it should work
insight appreciated
notifyDataSetChanged will do the job. You can call that at any time in your code and this will trigger the adapter to call getView for the visible list items again and so update their content. So basically the only thing you have to do is to update the list item states or information before calling that method.