java - 自定义ListView + getView方法

标签 java android listview listadapter

我需要有关使用 getView() 方法的自定义适配器的帮助。当适配器在每次渲染时调用 getView() 方法创建一个列表时,例如 holder.textEpisode.setTextColor() 等。这会带来沉重的负载,并且列表开始变慢。
请帮我解决这个问题。谢谢!

public class myAdapterDouble extends ArrayAdapter<Order> {

private int[] colorWhite = new int[] { -0x1 };
private int[] colors = new int[] { -0x1, -0x242425 };
private int[] colorBlack = new int[] { -0x1000000 };
private int[] colorTransparent = new int[] { android.R.color.transparent };
private LayoutInflater lInflater;
private ArrayList<Order> data;
private Order o;
private DisplayImageOptions options;
private ImageLoader imageLoader;
private ImageLoaderConfiguration config;
private Context ctx;
private Typeface tf;

public myAdapterDouble(Context c, int listItem, ArrayList<Order> data) {
super(c, listItem, data);
lInflater = LayoutInflater.from(c);
this.data = data;
ctx = c;

tf = Typeface.createFromAsset(ctx.getAssets(), "meiryo.ttc");

imageLoader = ImageLoader.getInstance();
options = new DisplayImageOptions.Builder()
        .showStubImage(R.drawable.no_image)
        .showImageForEmptyUri(R.drawable.no_image).cacheOnDisc()
        .cacheInMemory().build();

config = new ImageLoaderConfiguration.Builder(c.getApplicationContext())
        .threadPriority(Thread.NORM_PRIORITY - 2)
        .memoryCacheSize(2 * 1024 * 1024)  // 2 Mb
        .memoryCacheExtraOptions(100, 100)
        .denyCacheImageMultipleSizesInMemory()
        .discCacheFileNameGenerator(new Md5FileNameGenerator())
        .tasksProcessingOrder(QueueProcessingType.LIFO).enableLogging()
        .build();
ImageLoader.getInstance().init(config);
}

SharedPreferences sharedPref;
boolean posters, fixFont;
float headerSize, timeSize, dateSize;
int imageWSize;

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

ViewHolder holder = null;
o = data.get(position);

sharedPref = PreferenceManager.getDefaultSharedPreferences(ctx);
posters = sharedPref.getBoolean("poster", true);
fixFont = sharedPref.getBoolean("fix_font", false);

if (convertView == null) {
    convertView = lInflater.inflate(R.layout.double_list_item, null);
    holder = new ViewHolder();
    holder.textName = (TextView) convertView.findViewById(R.id.text);   
    if (fixFont) {
        try {
            holder.textName.setTypeface(tf);
        } catch (Exception e) {
            Toast.makeText(ctx, e.toString(), Toast.LENGTH_SHORT).show();
        }
    } else {
        try {
            holder.textName.setTypeface(Typeface.DEFAULT);
        } catch (Exception e) {
            Toast.makeText(ctx, e.toString(), Toast.LENGTH_SHORT).show();
        }
    }
    holder.textEpisode = (TextView) convertView.findViewById(R.id.text2);
    holder.img = (ImageView) convertView.findViewById(R.id.image);

    String width = sharedPref.getString("image_width", "70");
    imageWSize = Integer.parseInt(width); // ширина
    final float scale = getContext().getResources().getDisplayMetrics().density;
    int px = (int) (imageWSize*scale + 0.5f);

    holder.img.getLayoutParams().height = LayoutParams.WRAP_CONTENT;
    holder.img.getLayoutParams().width = px;
    if(imageWSize == 0) {
        holder.img.getLayoutParams().width = LayoutParams.WRAP_CONTENT;
    }
    holder.img.setPadding(5, 5, 5, 5);

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

headerSize = Float.parseFloat(sharedPref.getString("headsize", "20"));
holder.textName.setTextSize(headerSize); // размер названия
timeSize = Float.parseFloat(sharedPref.getString("timesize", "15"));
holder.textEpisode.setTextSize(timeSize); // размер времени

if (posters) {
    holder.img.setVisibility(View.VISIBLE);
    try {
        imageLoader.displayImage(o.getLink(), holder.img, options);
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
} else {
    holder.img.setVisibility(View.GONE);
}

holder.img.setTag(o);
holder.textName.setText(o.getTextName());
holder.textEpisode.setText(o.getTextEpisode());
holder.textEpisode.setTextColor(Color.BLACK);

if (o.getTextEpisode().toString().contains(ctx.getString(R.string.final_ep))) { 
    String finaleColor = sharedPref.getString("finale_color", "1");
    if (finaleColor.contains("default")) {
        holder.textEpisode.setTextColor(Color.parseColor("#2E64FE"));
    }
    if (finaleColor.contains("yelow")) {
        holder.textEpisode.setTextColor(Color.YELLOW);
    }
    if (finaleColor.contains("red")) {
        holder.textEpisode.setTextColor(Color.RED);
    }
    if (finaleColor.contains("green")) {
        holder.textEpisode.setTextColor(Color.GREEN);
    }
    if (finaleColor.contains("white")) {
        holder.textEpisode.setTextColor(Color.WHITE);
    }
    if (finaleColor.contains("gray")) {
        holder.textEpisode.setTextColor(Color.GRAY);
    }           
} else {
    holder.textEpisode.setTextColor(Color.parseColor("#2E64FE"));
}

String chooseColor = sharedPref.getString("colorList", "");
if (chooseColor.contains("white")) {
    int colorPos = position % colorWhite.length;
    convertView.setBackgroundColor(colorWhite[colorPos]);
}
if (chooseColor.contains("black")) {
    int colorPos = position % colorBlack.length;
    convertView.setBackgroundColor(colorBlack[colorPos]);
    holder.textName.setTextColor(Color.parseColor("#FFFFFF"));
}
if (chooseColor.contains("whitegray")) {
    int colorPos = position % colors.length;
    convertView.setBackgroundColor(colors[colorPos]);
}
if (chooseColor.contains("transparent")) {
    int colorPos = position % colorTransparent.length;
    convertView.setBackgroundColor(colorTransparent[colorPos]);
}

return convertView;
}

最佳答案

每次滚动加载下一个项目时,都会调用 getView() 方法。

sharedPref = PreferenceManager.getDefaultSharedPreferences(ctx);
posters = sharedPref.getBoolean("poster", true);
fixFont = sharedPref.getBoolean("fix_font", false);

这会减慢滚动速度,因为每次都需要读取和解析首选项。

所有这些首选项是否已作为某些变量加载一次。

如果仍然没有解决问题,请尝试 Method Profiling并检查 getView 方法的 Incl% 内容,并查看 getView 中哪些方法占用了更多 cpu 使用率。

已编辑

public class myAdapterDouble extends ArrayAdapter<Order> {
    private int[] colorWhite = new int[] { -0x1 };
    private int[] colors = new int[] { -0x1, -0x242425 };
    private int[] colorBlack = new int[] { -0x1000000 };
    private int[] colorTransparent = new int[] { android.R.color.transparent };
    private LayoutInflater lInflater;
    private ArrayList<Order> data;
    private Order o;
    private DisplayImageOptions options;
    private ImageLoader imageLoader;
    private ImageLoaderConfiguration config;
    private Context ctx;
    private Typeface tf;


    boolean posters, fixFont;
    float headerSize, timeSize, dateSize;
    int imageWSize;
    private String finaleColor;
    private String chooseColor;
    private String final_ep;

    public myAdapterDouble(Context c, int listItem, ArrayList<Order> data) {
        super(c, listItem, data);
        lInflater = LayoutInflater.from(c);
        this.data = data;
        ctx = c;

        tf = Typeface.createFromAsset(ctx.getAssets(), "meiryo.ttc");

        imageLoader = ImageLoader.getInstance();
        options = new DisplayImageOptions.Builder().showStubImage(R.drawable.no_image).showImageForEmptyUri(R.drawable.no_image).cacheOnDisc().cacheInMemory().build();

        config = new ImageLoaderConfiguration.Builder(c.getApplicationContext()).threadPriority(Thread.NORM_PRIORITY - 2).memoryCacheSize(2 * 1024 * 1024)
                // 2 Mb
                .memoryCacheExtraOptions(100, 100).denyCacheImageMultipleSizesInMemory().discCacheFileNameGenerator(new Md5FileNameGenerator()).tasksProcessingOrder(QueueProcessingType.LIFO)
                .enableLogging().build();
        ImageLoader.getInstance().init(config);

        SharedPreferences sharedPref;

        sharedPref = PreferenceManager.getDefaultSharedPreferences(ctx);
        posters = sharedPref.getBoolean("poster", true);
        fixFont = sharedPref.getBoolean("fix_font", false);

        String width = sharedPref.getString("image_width", "70");
        imageWSize = Integer.parseInt(width); // ширина
        headerSize = Float.parseFloat(sharedPref.getString("headsize", "20"));
        timeSize = Float.parseFloat(sharedPref.getString("timesize", "15"));

        finaleColor = sharedPref.getString("finale_color", "1");
        chooseColor = sharedPref.getString("colorList", "");
        final_ep = ctx.getString(R.string.final_ep);
    }

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

        ViewHolder holder = null;
        o = data.get(position);

        if (convertView == null) {
            convertView = lInflater.inflate(R.layout.double_list_item, null);
            holder = new ViewHolder();
            holder.textName = (TextView) convertView.findViewById(R.id.text);
            if (fixFont) {
                try {
                    holder.textName.setTypeface(tf);
                }
                catch (Exception e) {
                    Toast.makeText(ctx, e.toString(), Toast.LENGTH_SHORT).show();
                }
            }
            else {
                try {
                    holder.textName.setTypeface(Typeface.DEFAULT);
                }
                catch (Exception e) {
                    Toast.makeText(ctx, e.toString(), Toast.LENGTH_SHORT).show();
                }
            }
            holder.textEpisode = (TextView) convertView.findViewById(R.id.text2);
            holder.img = (ImageView) convertView.findViewById(R.id.image);


            final float scale = getContext().getResources().getDisplayMetrics().density;
            int px = (int) (imageWSize * scale + 0.5f);

            holder.img.getLayoutParams().height = LayoutParams.WRAP_CONTENT;
            holder.img.getLayoutParams().width = px;
            if (imageWSize == 0) {
                holder.img.getLayoutParams().width = LayoutParams.WRAP_CONTENT;
            }
            holder.img.setPadding(5, 5, 5, 5);

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


        holder.textName.setTextSize(headerSize); // размер названия

        holder.textEpisode.setTextSize(timeSize); // размер времени

        if (posters) {
            holder.img.setVisibility(View.VISIBLE);
            try {
                imageLoader.displayImage(o.getLink(), holder.img, options);
            }
            catch (NullPointerException e) {
                e.printStackTrace();
            }
        }
        else {
            holder.img.setVisibility(View.GONE);
        }

        holder.img.setTag(o);
        holder.textName.setText(o.getTextName());
        holder.textEpisode.setText(o.getTextEpisode());
        holder.textEpisode.setTextColor(Color.BLACK);


        if (o.getTextEpisode().toString().contains()) {

            if (finaleColor.contains("default")) {
                holder.textEpisode.setTextColor(Color.parseColor("#2E64FE"));
            }
            if (finaleColor.contains("yelow")) {
                holder.textEpisode.setTextColor(Color.YELLOW);
            }
            if (finaleColor.contains("red")) {
                holder.textEpisode.setTextColor(Color.RED);
            }
            if (finaleColor.contains("green")) {
                holder.textEpisode.setTextColor(Color.GREEN);
            }
            if (finaleColor.contains("white")) {
                holder.textEpisode.setTextColor(Color.WHITE);
            }
            if (finaleColor.contains("gray")) {
                holder.textEpisode.setTextColor(Color.GRAY);
            }
        }
        else {
            holder.textEpisode.setTextColor(Color.parseColor("#2E64FE"));
        }


        if (chooseColor.contains("white")) {
            int colorPos = position % colorWhite.length;
            convertView.setBackgroundColor(colorWhite[colorPos]);
        }
        if (chooseColor.contains("black")) {
            int colorPos = position % colorBlack.length;
            convertView.setBackgroundColor(colorBlack[colorPos]);
            holder.textName.setTextColor(Color.parseColor("#FFFFFF"));
        }
        if (chooseColor.contains("whitegray")) {
            int colorPos = position % colors.length;
            convertView.setBackgroundColor(colors[colorPos]);
        }
        if (chooseColor.contains("transparent")) {
            int colorPos = position % colorTransparent.length;
            convertView.setBackgroundColor(colorTransparent[colorPos]);
        }

        return convertView;
    }
}

关于java - 自定义ListView + getView方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15871891/

相关文章:

c# - ListView 作为日志文件

java - org.apache.catalina.core.StandardContext 重新加载后 transient 变量为空

android - 如何从 Android 中的 GPS 或网络提供商获取位置

android - 如何检查 Activity 是否存在多个实例

java - Android 中的类扩展自 BaseAdapter 中的 StartActivity 失败?

flutter - 按日期分组的 ListView Dart

java - TextView.post Runnable 并不总是有效

java - 使用 JPA(带注释的实体)和 liquibase 进行 hibernate

java - Vaadin:如何显示 MySQL 数据库中的数据?

java - 为什么小的 JPopupMenu 会导致视觉伪影,而较大的则不会?