My Activity has a cu开发者_运维百科stom title bar and a ListView. The ListView uses a SimpleAdapter showing an array of data, nothing fancy. I noticed that when I keep sliding my finger up and down without leaving the screen, quite often the scrolling stops and the scrollbar disappears. This never happens in Gmail Inbox activity. In NPR News app, the Menu activity suffers the same issue. What did I miss?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:drawable/title_bar"
android:singleLine="true"
android:textAppearance="@android:style/TextAppearance.WindowTitle">
<Button
android:id="@+id/accounts_filter"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
style="@android:style/Widget.Button.Small"
android:maxWidth="200sp"
android:singleLine="true"
android:ellipsize="marquee"
android:onClick="openFilter"/>
</RelativeLayout>
<ListView android:id="@+id/accounts_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
I was curious so I installed the NPR news app and got to replicate your bug.
From what I understand they are caching Bitmaps from the web in their adapter, and it hangs whenever the cache needs to download those bitmaps again (for whatever reason). The thing is, on continuous scrolling events you're expected to scroll through multiple list items at once, so if one item needs to refresh its cached value there is a good chance that the other items need it too. Depending on the adapter implementation there might be some weird concurrent modification happening.
here's the trace of what happens when it hangs: the adapter is getting massively confused.
05-21 08:53:07.570: DEBUG/org.npr.android.news.ImageThreadLoader(6457): Cache hit: http://media.npr.org/assets/img/2011/05/20/machoman_sq.jpg?t=1305913905&s=12
05-21 08:53:07.580: DEBUG/org.npr.android.util.PlaylistProvider(6457): content://org.npr.android.util.Playlist;story_id = ?;[136497574]
05-21 08:53:07.580: DEBUG/org.npr.android.news.ImageThreadLoader(6457): Cache hit: http://media.npr.org/assets/img/2011/05/20/pelosi_flex.jpg?t=1305924952&s=12
05-21 08:53:07.610: DEBUG/org.npr.android.news.DownloadDrawable(6457): Got bitmap
05-21 08:53:07.610: DEBUG/org.npr.android.news.DownloadDrawable(6457): Download complete
05-21 08:53:07.610: DEBUG/org.npr.android.news.DownloadDrawable(6457): Starting download
05-21 08:53:07.620: DEBUG/org.npr.android.util.PlaylistProvider(6457): content://org.npr.android.util.Playlist;story_id = ?;[136507004]
05-21 08:53:07.620: DEBUG/org.npr.android.news.ImageThreadLoader(6457): Cache hit: http://media.npr.org/assets/img/2011/05/20/capitol.jpg?t=1305929989&s=12
05-21 08:53:07.630: DEBUG/org.npr.android.util.PlaylistProvider(6457): content://org.npr.android.util.Playlist;story_id = ?;[136498068]
05-21 08:53:07.630: DEBUG/org.npr.android.news.ImageThreadLoader(6457): Cache hit: http://media.npr.org/assets/img/2011/05/20/ppw1.jpg?t=1305913144&s=12
05-21 08:53:07.640: DEBUG/org.npr.android.news.ImageThreadLoader(6457): Cache hit: http://media.npr.org/assets/img/2011/05/20/levee.jpg?t=1305901869&s=12
05-21 08:53:07.670: WARN/org.npr.android.news.NewsListAdapter(6457): Could not find list item at position 27
05-21 08:53:07.680: DEBUG/org.npr.android.news.ImageThreadLoader(6457): Cache hit: http://media.npr.org/assets/img/2011/05/20/imf.jpg?t=1305915244&s=12
05-21 08:53:07.710: DEBUG/org.npr.android.news.ImageThreadLoader(6457): Cache hit: http://media.npr.org/assets/img/2011/05/20/syria.jpg?t=1305904814&s=12
05-21 08:53:07.750: DEBUG/org.npr.android.news.ImageThreadLoader(6457): Cache hit: http://media.npr.org/assets/img/2011/05/20/netanyahu.jpg?t=1305900960&s=12
05-21 08:53:07.850: DEBUG/org.npr.android.news.DownloadDrawable(6457): Got bitmap
05-21 08:53:07.850: DEBUG/org.npr.android.news.DownloadDrawable(6457): Download complete
05-21 08:53:07.860: DEBUG/org.npr.android.news.DownloadDrawable(6457): Starting download
05-21 08:53:07.880: WARN/org.npr.android.news.NewsListAdapter(6457): Could not find list item at position 28
05-21 08:53:08.510: DEBUG/org.npr.android.news.DownloadDrawable(6457): Got bitmap
05-21 08:53:08.510: DEBUG/org.npr.android.news.DownloadDrawable(6457): Download complete
05-21 08:53:08.550: WARN/org.npr.android.news.NewsListAdapter(6457): Could not find list item at position 29
My suggestion: use placeholders? Have the adapter fetch from the cache only, retrieve a placeholder when it's not found, and trigger a background thread operation when the cache is invalid.
Try using DroidDraw for all your layout problems. Its a drag and drop desktop app for creating android layouts. I always use it whenever i stuck with layouts. And i think you should use Tablelayout
in your layout and put button and list in Tablerow
.
Here is a sample layout which i had created for my app with one button and listview
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/apps"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="@+id/undoApps"
android:layout_height="60dip"
android:layout_width="320dip"
android:text="I AM A BUTTON"
android:textSize="22sp"
android:textStyle="bold"
android:typeface="serif">
</Button>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ListView
android:id="@android:id/list"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:drawSelectorOnTop="false" >
</ListView>
</TableRow>
</TableLayout>
精彩评论