列表视图滚动不流畅。

4
我有一个自定义的列表视图,用于显示用户和他们的照片。我从API中检索数据,该API返回JSON格式的输出。
我的问题是列表视图滚动不流畅,会在卡顿一秒后才能滚动,这种情况会一直重复,直到滚动到底部。
我认为可能是因为我正在UI线程上运行与网络相关的操作,但即使在加载完成后,它仍然会继续发生?
我的自定义ListView的结构如下:
 <TextView  style="@style/photo_post_text"
             android:id="@+id/photo_post_text"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="demotext"
           />


        <ImageView
            android:id="@+id/userimage"
           android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:scaleType="fitXY"

            android:adjustViewBounds="true"
           android:src="@drawable/pi" 
           />

1
使用Traceview、StrictMode和其他工具(http://www.curious-creature.org/2012/12/01/android-performance-case-study/)来确定问题的源头。 - CommonsWare
3个回答

7
使用AsyncTask来加载图片,如果在UI线程中执行此类任务,滚动将不会流畅。
可以查看本教程,它将帮助您了解需要实现的内容,而无需使用其他库。还要记住,在滚动时,行会不断地重绘,没有真正的“完成”加载。您还可以考虑使用图像缓存,例如使用ConcurrentHashMap来存放已加载的图片。

3

为了让图片加载更快,可以使用这个库,它可以更快速地加载图片。 https://github.com/bumptech/glide

为了让列表滚动更加平滑,可以在activity的onCreate()方法中使用严格模式。

protected void onCreate(Bundle savedInstanceState) {

    //StrictMode for smooth list scroll
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    /*----- 
        ListView 
        Custom Adapter set data....
    ------*/}

在onCreate()方法中还有一件事要添加。
listView.setOnScrollListener(new OnScrollListener() {
public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCoun) {
}
public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState != 0)
            listView.getAdapter()).isScrolling = true;
        else {
            adapter.isScrolling = false;
            adapter.notifyDataSetChanged();
        }
} });

添加到适配器类中

public static Boolean isScrolling = true;

2
ListView滑动不流畅可能有很多原因。您可以确保使用以下最佳实践之一:
  1. 在列表适配器的getView()中使用Holder模式和重用视图
  2. 为下载在ListView中显示的图像使用异步图像加载库?例如Universal Image Loader
  3. 使用AsyncTask从网络下载JSON并将所有与网络相关的处理都放在单独的线程中。
一旦您确保已覆盖上述内容,它应该可以很好地工作了。

很高兴它有用。 - jagmohan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接