【问题标题】:Slow and jerky Android Custom Listview缓慢而生涩的 Android 自定义列表视图
【发布时间】:2014-03-22 11:21:39
【问题描述】:

我已经尝试了所有基本的事情,比如将每个繁重的任务转移到异步任务,在 getview() 中使用缓存的视图引用,启用滚动/绘图缓存等,所以请不要推荐它们。我已经确定了使用 ArrayList 的问题。

我正在使用带有 Hashmap 的 ArrayList 来保存数据。

static ArrayList<HashMap<String, String>> mainList = new ArrayList<HashMap<String, String>>();

适配器代码:

public static class LazyAdapter extends BaseAdapter {

    private Activity activity;
    private ArrayList<HashMap<String, String>> data;
    private LayoutInflater inflater = null;
    public ImageLoader imageLoader;

    public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
        activity = a;
        data = d;
        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        imageLoader = new ImageLoader(activity.getApplicationContext());
    }

    public int getCount() {
        return data.size();
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;

        View vi = convertView;
        if (convertView == null) {
            vi = inflater.inflate(R.layout.list_row, null);

            holder = new ViewHolder();
            holder.title = (TextView) vi.findViewById(R.id.title);
            holder.artist = (TextView) vi.findViewById(R.id.artist);
            holder.duration = (TextView) vi.findViewById(R.id.duration);
            holder.newsid = (TextView) vi.findViewById(R.id.newsid);
            holder.thumb_image = (ImageView) vi
                    .findViewById(R.id.list_image);

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

        HashMap<String, String> song = new HashMap<String, String>();

        try {
            song = data.get(position);

            // Setting all values in listview

            if (song.get(MainActivity.TAG_SELECTED)
                    .equalsIgnoreCase("true")) {

                final CheckBox chk = (CheckBox) vi.findViewById(R.id.tick);
                chk.setChecked(false);
            } else {
                final CheckBox chk = (CheckBox) vi.findViewById(R.id.tick);
                chk.setChecked(true);
            }

            holder.newsid.setText(song.get(MainActivity.TAG_ID));

            holder.title.setText(song.get(MainActivity.TAG_TITLE));
            holder.title.setTypeface(myTypeface);
            holder.title.setTextSize(16);
            holder.artist.setText(song.get(MainActivity.TAG_DESCRIPTON));
            holder.artist.setTypeface(myTypeface);
            holder.artist.setTextSize(13);
            holder.duration.setText(song.get(MainActivity.TAG_CREATED));
            holder.duration.setTextSize(12);

            imageLoader.DisplayImage(song.get(MainActivity.TAG_IMAGE),
                    holder.thumb_image);

        } catch (Exception e) {
        }

        return vi;
    }
}

我怎样才能做到这一点?

【问题讨论】:

  • 那你遇到了什么问题
  • 能贴出适配器的代码吗?
  • @rajshree 列表视图在滚动时非常缓慢且生涩。不流畅。
  • 对于每个视图,上面的细节都是相同的,然后放在 viewHolder 类中,这样它就会设置一次..
  • 你在使用 View holder 模式吗???

标签: android listview arraylist hashmap


【解决方案1】:

我在这里设置TypeFace 和一些默认设置一次,并使用它们整个listview..

确保创建一次 TypeFace 并在每个地方使用它。创建 TypeFace 也需要更多资源和时间..

克里特岛ViewHolder里面Adapeter这样..

public static class ViewHolder {

    private TextView title;
    private TextView artist;
    private TextView duration;
    private TextView newsid;
    private ImageView thumb_image;
    private CheckBox chk;

    public ViewHolder(View vi) {
        title = (TextView) vi.findViewById(R.id.title);
        artist = (TextView) vi.findViewById(R.id.artist);
        duration = (TextView) vi.findViewById(R.id.duration);
        newsid = (TextView) vi.findViewById(R.id.newsid);
        thumb_image = (ImageView) vi.findViewById(R.id.list_image);
        chk = (CheckBox) vi.findViewById(R.id.tick);

        title.setTypeface(myTypeface);
        title.setTextSize(16);
        artist.setTypeface(myTypeface);
        artist.setTextSize(13);
        duration.setTextSize(12);
    }
}

你的getView() 方法会像这样..

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    View vi = convertView;
    if (convertView == null) {
        vi = inflater.inflate(R.layout.list_row, null);
        holder = new ViewHolder(vi);
        vi.setTag(holder);
    } else {
        holder = (ViewHolder) vi.getTag();
    }

    HashMap<String, String> song ;
    try {
        song = data.get(position);
        // Setting all values in listview
        if (song.get(MainActivity.TAG_SELECTED).equalsIgnoreCase("true")) {
            holder.chk.setChecked(false);
        } else {
            holder.chk.setChecked(true);
        }
        holder.newsid.setText(song.get(MainActivity.TAG_ID));
        holder.title.setText(song.get(MainActivity.TAG_TITLE));
        holder.duration.setText(song.get(MainActivity.TAG_CREATED));
        imageLoader.DisplayImage(song.get(MainActivity.TAG_IMAGE),
                holder.thumb_image);
        holder.artist.setText(song.get(MainActivity.TAG_DESCRIPTON));
    } catch (Exception e) {
    }

    return vi;
}

使用一个 Util 类来加载这样的字体..

public class TypeFaceUtil {

public static Typeface typeface;

public static Typeface getTypeface(Context context) {
    if (typeface == null) {
        typeface = Typeface.createFromAsset(context.getAssets(),
                "arabic_font.otf");
    }
    return typeface;
}
}

并加载一次字体并在整个应用程序中使用它。

【讨论】:

  • 我不能投票,因为我的声誉较低。但是非常感谢!这有效!
  • 但还是不完美,虽然比之前的版本有很好的改进。我还能做些什么来提高性能?
  • 您在哪里创建字体以及如何创建字体??
  • 创建时 - myTypeface = Typeface.createFromAsset(getAssets(), "arabic_font.otf");
  • 谢谢。与此同时,你在工作吗?还是找工作?
【解决方案2】:

不要像下面的代码那样设置自定义字体和字体大小

public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder holder;

    View vi = convertView;
    if (convertView == null) {
        vi = inflater.inflate(R.layout.list_row, null);

        holder = new ViewHolder();
        holder.title = (TextView) vi.findViewById(R.id.title);
        holder.artist = (TextView) vi.findViewById(R.id.artist);
        holder.duration = (TextView) vi.findViewById(R.id.duration);
        holder.newsid = (TextView) vi.findViewById(R.id.newsid);
        holder.thumb_image = (ImageView) vi
                .findViewById(R.id.list_image);

    holder.title.setTypeface(myTypeface);
        holder.title.setTextSize(16);
    holder.artist.setTypeface(myTypeface);
        holder.artist.setTextSize(13);
        holder.duration.setText(song.get(MainActivity.TAG_CREATED));
        holder.duration.setTextSize(12);

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

    HashMap<String, String> song = new HashMap<String, String>();

    try {
        song = data.get(position);

        // Setting all values in listview

        if (song.get(MainActivity.TAG_SELECTED)
                .equalsIgnoreCase("true")) {

            final CheckBox chk = (CheckBox) vi.findViewById(R.id.tick);
            chk.setChecked(false);
        } else {
            final CheckBox chk = (CheckBox) vi.findViewById(R.id.tick);
            chk.setChecked(true);
        }

        holder.newsid.setText(song.get(MainActivity.TAG_ID));
        holder.title.setText(song.get(MainActivity.TAG_TITLE));
        holder.artist.setText(song.get(MainActivity.TAG_DESCRIPTON));

        imageLoader.DisplayImage(song.get(MainActivity.TAG_IMAGE),
                holder.thumb_image);

    } catch (Exception e) {
    }

    return vi;
}

【讨论】:

    【解决方案3】:

    您需要进行一些更改以提高性能,

    > set typeface and textsize in holder
    
    > utilize the object song instead of creating it everytime
    

    代码:

    public static class LazyAdapter extends BaseAdapter {
    
    private Activity activity;
    private ArrayList<HashMap<String, String>> data;
    private LayoutInflater inflater = null;
    public ImageLoader imageLoader;
    
    //create an object of song
    private static HashMap<String, String> song = new HashMap<String, String>();
    
    public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
        activity = a;
        data = d;
        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        imageLoader = new ImageLoader(activity.getApplicationContext());
    }
    
    public int getCount() {
        return data.size();
    }
    
    public Object getItem(int position) {
        return position;
    }
    
    public long getItemId(int position) {
        return position;
    }
    
    public View getView(int position, View convertView, ViewGroup parent) {
    
        ViewHolder holder;
    
        View vi = convertView;
        if (convertView == null) {
            vi = inflater.inflate(R.layout.list_row, null);
    
            holder = new ViewHolder();
            holder.title = (TextView) vi.findViewById(R.id.title);
            holder.artist = (TextView) vi.findViewById(R.id.artist);
            holder.duration = (TextView) vi.findViewById(R.id.duration);
            holder.newsid = (TextView) vi.findViewById(R.id.newsid);
            holder.thumb_image = (ImageView) vi
                    .findViewById(R.id.list_image);
    
            // set typeface and textsize
            holder.title.setTypeface(myTypeface);
            holder.title.setTextSize(16);
            holder.artist.setTypeface(myTypeface);
            holder.artist.setTextSize(13);
            holder.duration.setTextSize(12);
    
    
            vi.setTag(holder);
        } else {
            holder = (ViewHolder) vi.getTag();
        }
    
        // instead of creating object of song everytime,do it once only and then assign the data into that
    
        try {
            song = data.get(position);
    
            // Setting all values in listview
    
            if (song.get(MainActivity.TAG_SELECTED)
                    .equalsIgnoreCase("true")) {
    
                final CheckBox chk = (CheckBox) vi.findViewById(R.id.tick);
                chk.setChecked(false);
            } else {
                final CheckBox chk = (CheckBox) vi.findViewById(R.id.tick);
                chk.setChecked(true);
            }
    
            holder.newsid.setText(song.get(MainActivity.TAG_ID));
    
            holder.title.setText(song.get(MainActivity.TAG_TITLE));
            holder.artist.setText(song.get(MainActivity.TAG_DESCRIPTON));
            holder.duration.setText(song.get(MainActivity.TAG_CREATED));
    
            imageLoader.DisplayImage(song.get(MainActivity.TAG_IMAGE),
                    holder.thumb_image);
    
        } catch (Exception e) {
        }
    
        return vi;
    
    
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多