Android Listview滞后于复杂的布局 [英] Android listview lagging with complex layout

查看:78
本文介绍了Android Listview滞后于复杂的布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

就像标题一样,我创建了一个列表视图,其中每个项目都显示图像,三行文本和一个按钮,但是即使在三星银河巨型双核系统中,该视图也是如此落后,这里是我的项目视图xml

Like the title say, i create list view which each item display image, three line text, and a button, but the view is so lagging even in samsung galaxy mega dual core, here my item view xml

<RelativeLayout
    android:gravity="center_vertical"
    android:padding="5.0dip"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:listPreferredItemHeight"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView
        android:id="@+id/compositeListViewItemThumbnailImage"
        android:layout_width="60.0dip"
        android:layout_height="60.0dip"
        android:src="@drawable/ic_launcher"
        android:scaleType="fitCenter"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_alignWithParentIfMissing="true"
        android:contentDescription="@string/_empty_strings" />
    <LinearLayout
        android:orientation="vertical"
        android:id="@+id/compositeListViewItemFirstLinearLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/compositeListViewItemThumbnailImage"
        android:layout_alignTop="@+id/compositeListViewItemThumbnailImage"
        android:layout_alignBottom="@+id/compositeListViewItemThumbnailImage"
        android:layout_alignParentRight="true">
        <TextView
            android:textSize="16.0sp"
            android:gravity="center_vertical"
            android:id="@+id/compositeListViewItemFirstLineText"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello_world"
            android:singleLine="true"
            android:ellipsize="marquee"
            android:lines="1"
            android:inputType="textNoSuggestions" />
        <TextView
            android:textSize="12.0sp"
            android:id="@+id/compositeListViewItemSecondLineText"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello_world"
            android:singleLine="true"
            android:ellipsize="marquee"
            android:lines="1"
            android:inputType="textNoSuggestions" />
        <TextView
            android:textSize="14.0sp"
            android:singleLine="true"
            android:ellipsize="marquee"
            android:lines="1"
            android:layout_gravity="center_vertical"
            android:id="@+id/compositeListViewItemThirdLineText"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello_world"
            android:inputType="textNoSuggestions" />
    </LinearLayout>
    <Button
        android:id="@+id/compositeListViewItemActionButton"
        android:paddingLeft="5.0dip"
        android:paddingTop="5.0dip"
        android:paddingRight="5.0dip"
        android:paddingBottom="5.0dip"
        android:focusable="false"
        android:layout_width="wrap_content"
        android:layout_height="30.0dip"
        android:layout_marginTop="30.0dip"
        android:layout_marginRight="0.0dip"
        android:text="@string/hello_world"
        android:layout_alignParentRight="true"
        style="?android:attr/buttonStyleSmall" />
</RelativeLayout>

因为它可能/可能不受适配器视图的影响,所以我也将其放在此处

as it might / might not be affected by the adapter view, i also put it here

public class SimpleAdapter extends ArrayAdapter implements Serializable {
    private ArrayList<?> items;
    private int itemLayout;
    private String[] itemFieldsName;
    private int[] itemElements;
    private Context ctx;

    public SimpleAdapter(Context ctx, ArrayList<?> items, int itemLayout, int[] itemElements, String[] itemFieldsName) {
        super(ctx, itemLayout, items);
        this.items = items;
        this.itemElements = itemElements;
        this.itemLayout = itemLayout;
        this.itemFieldsName = itemFieldsName;
        this.ctx = ctx;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View itemView = convertView;
        if (itemView == null) {
            itemView = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(this.itemLayout, null);
        }
        Object item = this.items.get(position);
        for (int i = 0; i < this.itemElements.length; i++) {
            Object value = getValue(item, Character.toUpperCase(this.itemFieldsName[i].charAt(0)) + this.itemFieldsName[i].substring(1));
            View elementView = null;
            if (itemView != null) {
                elementView = itemView.findViewById(this.itemElements[i]);
                if ((elementView instanceof TextView)) {
                    ((TextView) elementView).setText(value.toString());
                } else if ((elementView instanceof SmartImageView)) {
                    ((SmartImageView) elementView).setImageUrl(value.toString());
                } else if ((elementView instanceof Button)) {
                    ((Button) elementView).setText(value.toString());
                }
            }
        }
        return itemView;
    }

    private Object getValue(Object obj, String fieldName) {
        ArrayList<String> fieldsName = new ArrayList<String>();
        int length;
        String str = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
        Object value = new Object();
        try {
            value = obj.getClass().getMethod("get" + str, new Class[0]).invoke(obj);
        } catch (Exception ex) {
            value = fieldName;
        }
        return value;
    }

    private String trimString(String string, int length, boolean soft) {
        if(string == null || string.trim().isEmpty()){
            return string;
        }
        StringBuffer sb = new StringBuffer(string);
        int actualLength = length - 3;
        if(sb.length() > actualLength){
            if(!soft)
                return sb.insert(actualLength, "...").substring(0, actualLength+3);
            else {
                int endIndex = sb.indexOf(" ",actualLength);
                return sb.insert(endIndex,"...").substring(0, endIndex+3);
            }
        }
        return string;
    }
}

有人可以告诉我我哪里错了吗?,

Can someone tell me where i was wrong?,

告诉我是否需要更多说明/代码资源

tell me if you need more explanation / code resource

推荐答案

在膨胀的布局内查找内部视图是Android中最常见的操作之一.这通常是通过称为 findViewById()的View方法完成的.该方法将递归地遍历视图树,以查找具有给定IDcode的孩子.在静态UI布局上使用 findViewById()完全可以,但是,正如您所看到的,ListView在滚动时会非常频繁地调用适配器的 getView(). findViewById()可能会影响ListViews的滚动性能,尤其是在行布局不平凡的情况下.

Finding an inner view inside an inflated layout is among the most common operations in Android. This is usually done through a View method called findViewById(). This method will recursively go through the view tree looking for a child with a given IDcode. Using findViewById() on static UI layouts is totally fine but, as you’ve seen, ListView calls the adapter’s getView() very frequently when scrolling. findViewById() might perceivably hit scrolling performance in ListViews—especially if your row layout is non-trivial.

视图持有人模式是关于减少适配器的 getView()中的 findViewById()调用次数.实际上,视图持有人是一个轻量级的内部类,它持有对行中所有内部视图的直接引用.将其充气后,可以将其作为标签存储在行的视图中.这样,您在初次创建布局时只需要使用 findViewById().这是应用了View Holder模式的代码示例:

The View Holder pattern is about reducing the number of findViewById() calls in the adapter’s getView(). In practice, the View Holder is a lightweight inner class that holds direct references to all inner views from a row. You store it as a tag in the row’s view after inflating it. This way you’ll only have to use findViewById() when you first create the layout. Here’s the code sample with View Holder pattern applied:

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

if (convertView == null) {
    convertView = mInflater.inflate(R.layout.your_layout, null);

    holder = new ViewHolder();
    holder.text = (TextView) convertView.findViewById(R.id.text);

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

holder.text.setText("Position " + position);

return convertView;

}

private static class ViewHolder {
public TextView text;

}

这篇关于Android Listview滞后于复杂的布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆