使用多线程(Android API 10)使用图像制作更快的ListView

时间:2016-06-06 11:46:09

标签: android multithreading listview lazy-loading

我已经搜索了答案,但在我的案例中似乎没有任何帮助。 App min sdk - API 10

问题 - 带有图像的ListView慢。

原因 - 数据加载在UI线程上(没有图像,一切顺利),以及我得到图像资源ID的方式。

我有一个带有两个TextView和一个ImageView的ListView。我使用SQLiteAssetHelper从插入的数据库填充ListView文本。

表格示例:

-----------------
content_ref_table
-----------------
content_id(pk) | title | description | content_url | thumb_icon | category_id(fk) | course_id(fk) | subject_id(fk)    

-----------------
course_ref_table
-----------------
course_id(pk) | course

-----------------
subject_ref_table 
-----------------
subject_id(pk) | subject  

-----------------  
cateory_ref_table  
-----------------
category_id(pk) | category  

图片加载

我将PNG图像保存在 drawable 文件夹中。

我从数据库中的数据中获取图像资源ID:

in specie_table.db“Regulus regulus” - > getImageName(name)返回“regulus_regulus” - > getResId(name,class)返回drawable id - > setImage(ImageView,name)设置ImageView的资源

我应该采用不同的方法吗?

List_item.xml

specie_table
_id | LITHUANIAN          |   LATIN
0   | Paprastasis varnėnas| Sturnus vulgaris
1   | Juodasis strazdas   | Turdus merula

SpecieCursorAdapter.java

<ImageView
    android:id="@+id/icon"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_marginTop="6dip"
    android:layout_marginLeft="6dip"
    android:layout_marginRight="10dip"
    android:src="@drawable/ic_bird_grey"
    />

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="100dp"
    android:orientation="vertical"
    android:layout_toRightOf="@id/icon"
    android:paddingTop="15dp">

    <TextView
        android:id="@+id/firstLine"
        android:layout_width="match_parent"
        android:layout_height="35sp"
        android:text="Lithuanian title"
        android:textSize="20sp"
        />
    <TextView
        android:id="@+id/secondLine"
        android:layout_width="match_parent"
        android:layout_height="24dp"
        android:text="Latin title"
        android:textSize="12sp" />

</LinearLayout>

ListActivity.java

public class SpecieCursorAdapter extends CursorAdapter {


SpecieCursorAdapter(Context context, Cursor cursor) {
    super(context, cursor, 0);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    return LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
}

@Override
public void bindView(View view, Context context, Cursor cursor) {

    SpecieHolder holder = null;

    holder = new SpecieHolder();
    holder.imgIcon = (ImageView) view.findViewById(R.id.icon);
    holder.txtTitle1 = (TextView) view.findViewById(R.id.firstLine);
    holder.txtTitle2 = (TextView) view.findViewById(R.id.secondLine);

    String nameLT = cursor.getString(cursor.getColumnIndex(SpecieTable.LIT_COL));
    String nameLOT = cursor.getString(cursor.getColumnIndex(SpecieTable.LAT_COL));


    holder.txtTitle1.setText(nameLT);
    holder.txtTitle2.setText(nameLOT);
    setImage(holder.imgIcon, nameLOT);  //this makes everything laggy but i dont know how to make it as seperate thread.

}
static class SpecieHolder
{
    ImageView imgIcon;
    TextView txtTitle1;
    TextView txtTitle2;
}

public void setImage(ImageView mainImage, String resource){ //these methods are for getting the image resource id from String (latin name).

    int id = getResId(getImageName(resource), R.drawable.class);
    if(id != -1)
        mainImage.setImageResource(id);
    else
        mainImage.setImageResource(R.drawable.ic_bird_grey);

}
public int getResId(String resourceName, Class<?> c) {
    try {
        Field idField = c.getDeclaredField(resourceName);
        return idField.getInt(idField);
    } catch (Exception e) {
        return -1;
    }
}
public String getImageName(String resource){
    String string = resource.toLowerCase();
    string = string.replace(' ', '_');
    string = string.replace(".", "");
    return string;
}}

示例有助于实现!我将插入任何所需的额外代码。

4 个答案:

答案 0 :(得分:0)

尝试使用Volley HTTP库来加快数据传输和图像加载。 Volley是一个HTTP库,它使Android应用程序的网络更容易,最重要的是,更快。

请按照以下链接

https://developer.android.com/training/volley/index.html

An example listview with image loading using Volley library

答案 1 :(得分:0)

您可以使用@abhilash提议的现有库,也可以在您自己的

上实施

在android中,在listview中显示带有图像的项目就像这样(例子):

  • 列表视图需要显示位于#35
  • 的项目
  • listview向其适配器询问位于#35的项目的已填充listviewitemview
  • listviewitemview可以从旧的listviewitemview中回收,该listviewitem视图不再可见,或者创建了新的listviewitemview
  • 每个listviewitemview都有一个带有imageID和bitmap-gui元素的相应viewHolder
  • listviewitemview中的图片最初加载了占位符图像,该图像在成像完成之前可见。
  • 适配器启动在后台加载图像(async-task),使用imageID获取viewHolder。
  • 当在后台加载图像时,viewholder-gui元素获取加载的图像。

GridView和ListView的工作方式相同。

以下是APhotoManager的工作示例。它包含GalleryCursorFragment,其gridview具有嵌入式GridCellViewHolder

答案 2 :(得分:0)

根据@Neil和@shelll的建议,我使用了 Glide 库。我相应地修改了我的代码:

添加到build.gradle

compile 'com.github.bumptech.glide:glide:3.7.0'

通过更改

修改了bindView()方法
setImage(holder.imgIcon, nameLOT);

int imageId = getResId(getImageName(nameLOT), R.drawable.class);
if(imageId == -1)
    imageId = R.drawable.ic_bird_grey;

Glide
        .with(holder.imgIcon.getContext())
        .load(imageId)
        .into(holder.imgIcon);

答案 3 :(得分:-1)

对于异步图像加载(和缓存),请使用为此创建的库,如GlideFresco