Android适配器getView()中2个布局的动态膨胀

时间:2014-05-08 11:30:17

标签: android android-layout listview android-listview

我的最终结果是一个简单的聊天气泡样式ListView。

  1. 我有两个左右气泡布局文件
  2. 在我的Adapter的getView中,我会检查标志并使所需的布局膨胀
  3. 我也在使用持有人概念。

    public class Holder {
        TextView userName;
        TextView message;
        CheckBox box;
    }    
    
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        Holder holder;
        OneComment coment = getItem(position);
    
        if (row == null) {
            holder = new Holder();
            if (coment.left) {
                row = inflater.inflate(R.layout.listitem_left_chat, null, false);
                holder.message = (TextView) row.findViewById(R.id.comment);
                holder.box = (CheckBox) row.findViewById(R.id.checkBox1);
            } else {
                row = inflater.inflate(R.layout.listitem_right_chat, null, false);
                holder.message = (TextView) row.findViewById(R.id.comment2);
                holder.box = (CheckBox) row.findViewById(R.id.checkBox2);
            }
        holder.message.setText(coment.comment);
        holder.box.setChecked(coment.left);
        }
        return row;
    }
    
  4. 我得到了理想的结果。我仍然想知道这种方法是否正确。如果没有,哪种方法最好?

2 个答案:

答案 0 :(得分:3)

适配器可以使用不同的视图。您应该覆盖两种方法:getViewTypeCount()getItemViewType(int position)。在你的情况下:

private static final int TYPES_COUNT = 2;
private static final int TYPE_LEFT = 0;
private static final int TYPE_RIGHT = 1;

@Override
public int getViewTypeCount() {
    return TYPES_COUNT;
}

@Override
public int getItemViewType (int position) {
    if (getItem(position).left) {
        return TYPE_LEFT;
    }
    return TYPE_RIGHT;
}

public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    Holder holder;
    OneComment coment = getItem(position);

    if (row == null) {
        holder = new Holder();
        if (getItemViewType (position) == TYPE_LEFT) {
            row = inflater.inflate(R.layout.listitem_left_chat, null, false);
            holder.message = (TextView) row.findViewById(R.id.comment);
            holder.box = (CheckBox) row.findViewById(R.id.checkBox1);
        } else {
            row = inflater.inflate(R.layout.listitem_right_chat, null, false);
            holder.message = (TextView) row.findViewById(R.id.comment2);
            holder.box = (CheckBox) row.findViewById(R.id.checkBox2);
        }

        row.setTag(holder);
    } else {
        holder = (Holder)row.getTag();
    }

    holder.message.setText(coment.comment);
    holder.box.setChecked(coment.left);

    return row;
}

public class Holder {
    TextView userName;
    TextView message;
    CheckBox box;
}

<强> UPD:

说明:

getItemViewType应该返回一个整数,该整数标识getView(int, View, ViewGroup)为指定项创建的View类型。如果可以在getView中将一个视图转换为另一个视图,则两个视图应返回相同的结果。

getViewTypeCount应返回一个整数,其中包含适配器将处理的视图类型数。

在幕后,Android使用View类型来确定应将哪种类型的View传递到getView方法。您可以将其视为创建多个可以重复使用的视图存储桶,从而避免每次新列表项变为可见时对新视图进行充气的惩罚。

当用户向下滚动ListView时,框架将回收不再可见的行,并将它们添加到适当的存储桶中以供重用。当一个新的Header或Event项进入视图时,框架将检查其中一个视图是否已存在于循环视图的桶中,如果是,它将作为convertView传递给getView方法

答案 1 :(得分:0)

// try this way,hope this will help you...

See below how to use single layout instead of two separate layout.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/lnrRightChat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:padding="5dp"
        android:layout_marginRight="20dp">

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">
            <TextView
                android:id="@+id/txtRightMessage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Right Side Chat Message "/>
        </LinearLayout>
        <CheckBox
            android:id="@+id/chkRight"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/lnrLeftChat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:gravity="center_vertical"
        android:padding="5dp"
        android:layout_marginLeft="20dp">
        <CheckBox
            android:id="@+id/chkLeft"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">
            <TextView
                android:id="@+id/txtLeftMessage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Left Side Chat Message"/>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

See below how to use above layout in adapter.

public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if(convertView==null){
                convertView = LayoutInflater.from(context).inflate(R.layout.activity_main,null,false);
                holder = new ViewHolder();
                holder.lnrLeftChat = (LinearLayout) convertView.findViewById(R.id.lnrLeftChat);
                holder.lnrRightChat = (LinearLayout) convertView.findViewById(R.id.lnrRightChat);
                holder.txtRightMessage = (TextView) convertView.findViewById(R.id.txtRightMessage);
                holder.txtLeftMessage = (TextView) convertView.findViewById(R.id.txtLeftMessage);
                holder.chkRight = (CheckBox) convertView.findViewById(R.id.chkRight);
                holder.chkLeft = (CheckBox) convertView.findViewById(R.id.chkLeft);
                convertView.setTag(holder);
            }else{
                holder = (ViewHolder) convertView.getTag();
            }
            OneComment coment = getItem(position);
            if(coment.left){
                holder.lnrLeftChat.setVisibility(View.VISIBLE);
                holder.lnrRightChat.setVisibility(View.VISIBLE);
                holder.txtLeftMessage.setText(coment.comment);
                holder.chkLeft.setText(coment.left);
            }else{
                holder.lnrRightChat.setVisibility(View.VISIBLE);
                holder.lnrRightChat.setVisibility(View.VISIBLE);
                holder.txtRightMessage.setText("");
            }
            return convertView;
}