Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/190.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 滚动时ListView太慢_Android_Listview_Android Asynctask - Fatal编程技术网

Android 滚动时ListView太慢

Android 滚动时ListView太慢,android,listview,android-asynctask,Android,Listview,Android Asynctask,这似乎是一个常见的问题,但我还没有能够实现我找到的任何解决方案。我有一个带有自定义适配器的列表视图,该适配器在一行中显示缩略图和文本字段。这些缩略图来自我之前创建的文件夹,并将我从应用程序中拍摄的照片放入其中 以下是我的活动列表: private LayoutInflater mInflater; private Vector<RowData> data; private CustomAdapter adapter; private RowData rd; static File

这似乎是一个常见的问题,但我还没有能够实现我找到的任何解决方案。我有一个带有自定义适配器的
列表视图
,该适配器在一行中显示缩略图和文本字段。这些缩略图来自我之前创建的文件夹,并将我从应用程序中拍摄的照片放入其中

以下是我的活动列表:

private LayoutInflater mInflater;
private Vector<RowData> data;
private CustomAdapter adapter;
private RowData rd;

static File path = Environment.getExternalStorageDirectory();
static File fnames = new File(path, "MyImages");

static String[] title = fnames.list();

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_blog);

    mInflater = (LayoutInflater) getSystemService(
    Activity.LAYOUT_INFLATER_SERVICE);
    setListName();
    data = new Vector<RowData>();
    for(int i=0;i<title.length;i++){
        try {
            rd = new RowData(i,title[i]);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        data.add(rd);
    }

    getListView().setTextFilterEnabled(true);
    getListView().setScrollingCacheEnabled(false);
}

public void onRestart()
{
    super.onRestart();
    setListName();
}

private Vector<RowData> setListName()
{
    data = new Vector<RowData>();
    String[] title = fnames.list();

    //get the databases textblog
    DatabaseHandler db = new DatabaseHandler(this);
    List<TextBlog> textBlogs = db.getAllText();
    int positionRaw = textBlogs.size();

    for (int i=0;i<textBlogs.size(); i++) {
        rd = new RowData(i, textBlogs.get(i).getText());
        data.add(rd);
    }

    for(int i=0;i<title.length;i++) {
        try {
            rd = new RowData(positionRaw,title[i]);
            positionRaw++;
        } catch (ParseException e) {
            e.printStackTrace();
        }

        data.add(rd);
    }

    adapter = new CustomAdapter(this, R.layout.list,R.id.title, data);
    setListAdapter(adapter);
    getListView().setTextFilterEnabled(true);
    adapter.notifyDataSetChanged();

    return data;
}


//Create thumbnail from file picture
private Bitmap decodeFile(File f) {
    try {
        //Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

        //The new size we want to scale to
        final int REQUIRED_SIZE=70;

        //Find the correct scale value. It should be the power of 2.
        int scale=1;
        while (o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
            scale*=2;

        //Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {

    }

    return null;
}

//Set row object
private class RowData 
{
    protected int mId;
    protected String mTitle;
    RowData(int id,String title){
    mId=id;
    mTitle = title;
}

@Override
public String toString() {
    return mId+" "+mTitle+" ";
}
private layoutiner mInflater;
专用矢量数据;
专用自定义适配器;
私家路;;
静态文件路径=Environment.getExternalStorageDirectory();
静态文件fnames=新文件(路径“MyImages”);
静态字符串[]title=fnames.list();
@凌驾
创建时的公共void(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_blog);
mInflater=(LayoutInflater)getSystemService(
活动。布局(充气机和服务);
setListName();
数据=新向量();

对于(inti=0;i您试图在这里实现ViewHolder模式,但是您的实现看起来是错误的

此模式的思想是减少对
findViewById()
的调用,这会对性能产生影响。只有当行为null(convertView)时,才应调用
findViewById()
,否则应重用与
setTag()一起保存的上一个视图

让我们看看您的代码:

if(null == convertView){
    convertView = mInflater.inflate(R.layout.list, null);
    holder = new ViewHolder();
    convertView.setTag(holder);
}

// .......          
title = holder.gettitle();
// .........
thumb=holder.getImage();
请注意,
holder.getTitle()
holder.getImage()
if
语句之后被调用。这意味着无论
convertView
是否为null,它们都将被每次调用。
现在,看看这些getter,我们看到它们包含调用
findViewById();

例如,对于
getTitle()

因此,基本上,这里不使用ViewHolder模式,只使用一些混合代码,最后每次调用
findViewById()
,这会降低
ListView的性能。

要正确执行此操作,应仅在
convertView
为空时调用
findViewById()
。 例:

这是实现
ViewHolder
模式的正确方法


(附言:您需要将标题thumb…的访问修饰符更改为public。)

您可以看到类似的问题,这里有一个小技巧:大量混合了索引、空格和括号样式,这使得代码有点难以阅读。在将代码复制到问题中之前,您可以在Eclipse中按
Ctrl+Shift+F
轻松格式化代码。格式更好的代码更易于阅读,并将提高您获取的机会正在等待答案。(其他IDE可能有类似的功能,但我不知道从我的头顶上)@Yul谢谢,我要采取行动了look@alextsc谢谢你的提示,我不知道title=holder.gettitle();和title=holder.gettitle();使用findViewById()在它们里面。findViewById相当昂贵,试着使用一次。否则你的HolderView就没有意义了。也可以使用ImageCache,就像在惰性加载图像中一样。你已经有了链接。我认为问题是在
适配器中获取位图。
。他应该使用
异步任务
@Yul,很可能是影响ListView的另一个因素performance@AndyRes非常感谢您的时间和解释。我尝试过,但遗憾的是,它没有改变任何东西,然后我尝试不加载缩略图,它工作得非常好,因此我真的需要通过AsyncTask获取这些缩略图有关AsyncTask的一些参考:,
if(null == convertView){
    convertView = mInflater.inflate(R.layout.list, null);
    holder = new ViewHolder();
    convertView.setTag(holder);
}

// .......          
title = holder.gettitle();
// .........
thumb=holder.getImage();
public TextView gettitle() {
     if(null == title){
          title = (TextView) mRow.findViewById(R.id.title);
     }
     return title;
} 
if(null==convertView){
    convertView = mInflater.inflate(R.layout.list, null);
    holder = new ViewHolder();

    // Getting a refernce to the views with findViewById()
    title = holder.gettitle();
    thumb=holder.getImage();

    convertView.setTag(holder);
}else{
     holder = (ViewHolder) convertView.getTag();
}

// Then you set the appropriate values to your views through the holder:
holder.title.setText("");
holder.thumb.setImageBitmap(...);