缓慢而生涩的Android Custom Listview

时间:2014-02-21 05:31:57

标签: android listview arraylist hashmap

我已经尝试了所有基本的东西,例如将每个繁重的任务移动到异步任务,使用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;
    }
}

我该如何使这项工作?

3 个答案:

答案 0 :(得分:3)

我在这里设置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;
}
}

然后加载一次字体并将其整个应用程序使用。

答案 1 :(得分: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;
}

答案 2 :(得分:1)

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

> 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;


   }
}