listview 中的不同 item 實現

原文 鏈接 http://android.leocardz.com/multiple-layout-listview/


Basically, you have to follow these steps:

  • Create the custom layous;
  • Create a custom adapter;
  • Override getViewTypeCount() method in your custom adapter with the amount of layouts you're gonna use in your listview;
  • Override getItemViewType(int position) method also in your custom adapter to return the current item's view type;
  • Additionally, it's essential to use a view holder to avoid memory leaks.

Take a look in the code below.

First, we create custom layouts. In this case, four types.

首先,要按照下面的步驟:

1,創建自定義佈局

2,新建自定義adpter

3,override getViewTypeCount()方法,返回值就是item的種類數

4,override getItemViewType(int position) 方法,返回當前position item類型

5,使用view holder避免內存泄露

首先創建自定義佈局

// even
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="#ff500000"
    android:layout_height="match_parent">
 
    <TextView
        android:id="@+id/text"
        android:textColor="@android:color/white"
        android:layout_width="match_parent"
        android:layout_gravity="center"
        android:textSize="24sp"
        android:layout_height="wrap_content" />
 
 </LinearLayout>
// odd
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="#ff001f50"
    android:gravity="right"
    android:layout_height="match_parent">
 
    <TextView
        android:id="@+id/text"
        android:textColor="@android:color/white"
        android:layout_width="wrap_content"
        android:layout_gravity="center"
        android:textSize="28sp"
        android:layout_height="wrap_content"  />
 
 </LinearLayout>


// white
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="#ffffffff"
    android:gravity="right"
    android:layout_height="match_parent">
 
    <TextView
        android:id="@+id/text"
        android:textColor="@android:color/black"
        android:layout_width="wrap_content"
        android:layout_gravity="center"
        android:textSize="28sp"
        android:layout_height="wrap_content"   />
 
 </LinearLayout>


// black
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="#ff000000"
    android:layout_height="match_parent">
 
    <TextView
        android:id="@+id/text"
        android:textColor="@android:color/white"
        android:layout_width="wrap_content"
        android:layout_gravity="center"
        android:textSize="33sp"
        android:layout_height="wrap_content"   />
 
 </LinearLayout>
然後新建一個listviewitem.class存放item數據

public class ListViewItem {
        private String text;
        private int type;
 
        public ListViewItem(String text, int type) {
            this.text = text;
            this.type = type;
        }
 
        public String getText() {
            return text;
        }
 
        public void setText(String text) {
            this.text = text;
        }
 
        public int getType() {
            return type;
        }
 
        public void setType(int type) {
            this.type = type;
        }
 
    }

在然後,新建一個viewholer .強烈推薦.因爲可以讓系統保持item layout重用參考當item消失和顯示時.如果不使用,每一次顯示item的時候,系統都回去新建一個item 參考,導致app內存泄露

After that, we create a view holder. It's strongly recommended because Android OS keeps the layout reference to reuse your item when it disappears and appears back on the screen. If you don't use this approach, every single time that your item appears on the screen Android OS will create a new one and causing your app to leak memory.

public class ViewHolder {
        TextView text;
 
        public ViewHolder(TextView text) {
            this.text = text;
        }
 
        public TextView getText() {
            return text;
        }
 
        public void setText(TextView text) {
            this.text = text;
        }
 
    }

Finally, we create our custom adapter overriding getViewTypeCount() and getItemViewType(int position).

最後,overriding getViewTypeCount() 和 getItemViewType(int position)方法

public class CustomAdapter extends ArrayAdapter {
        public static final int TYPE_ODD = 0;
        public static final int TYPE_EVEN = 1;
        public static final int TYPE_WHITE = 2;
        public static final int TYPE_BLACK = 3;
        private ListViewItem[] objects;
        @Override
        public int getViewTypeCount() {
            return 4;
        }
        @Override
        public int getItemViewType(int position) {
            return objects[position].getType();
        }
        public CustomAdapter(Context context, int resource, ListViewItem[] objects) {
            super(context, resource, objects);
            this.objects = objects;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder = null;
            ListViewItem listViewItem = objects[position];
            int listViewItemType = getItemViewType(position);
            if (convertView == null) {
                if (listViewItemType == TYPE_EVEN) {
                    convertView = LayoutInflater.from(getContext()).inflate(R.layout.type_even, null);
                } else if (listViewItemType == TYPE_ODD) {
                    convertView = LayoutInflater.from(getContext()).inflate(R.layout.type_odd, null);
                } else if (listViewItemType == TYPE_WHITE) {
                    convertView = LayoutInflater.from(getContext()).inflate(R.layout.type_white, null);
                } else {
                    convertView = LayoutInflater.from(getContext()).inflate(R.layout.type_black, null);
                }
                TextView textView = (TextView) convertView.findViewById(R.id.text);
                viewHolder = new ViewHolder(textView);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            viewHolder.getText().setText(listViewItem.getText());
            return convertView;
        }
    }


activity 文件


public class MainActivity extends ActionBarActivity {
 
    private ListView listView;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        setContentView(R.layout.activity_main); // here, you can create a single layout with a listview
 
        listView = (ListView) findViewById(R.id.listview);
 
        final ListViewItem[] items = new ListViewItem[40];
 
        for (int i = 0; i < items.length; i++) {
            if (i == 4) {
                items[i] = new ListViewItem("White " + i, CustomAdapter.TYPE_WHITE);
            } else if (i == 9) {
                items[i] = new ListViewItem("Black " + i, CustomAdapter.TYPE_BLACK);
            } else if (i % 2 == 0) {
                items[i] = new ListViewItem("EVEN " + i, CustomAdapter.TYPE_EVEN);
            } else {
                items[i] = new ListViewItem("ODD " + i, CustomAdapter.TYPE_ODD);
            }
        }
 
        CustomAdapter customAdapter = new CustomAdapter(this, R.id.text, items);
        listView.setAdapter(customAdapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView adapterView, View view, int i, long l) {
                Toast.makeText(getBaseContext(), items[i].getText(), Toast.LENGTH_SHORT).show();
            }
        });
 
    }
}



效果圖


代碼地址 github




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章