1. 程式人生 > >Android widget之ListView

Android widget之ListView

簡介

ListView是一個檢視組,顯示可滾動專案的列表。
並將每個專案結果轉換為放置到列表中的檢視。
一般,自定義列表需要與(android.widget.BaseAdapter)配合使用!

屬性

xml屬性 相關方法 作用效果
android:divider setDivider(Drawable) 可在列表項之間繪製顏色
android:dividerHeight 在列表項之間繪製顏色的高度
android:entries 引用將填充ListView的陣列資源
android:footerDividersEnabled 當設定為false時,ListView將不會在每個頁尾檢視之前畫出分隔符
android:headerDividersEnabled 當設定為false時,ListView將不會在每個頭部檢視之後繪製分隔符

簡單使用

可以配合(android.widget.ArrayAdapter)進行簡單的資料列表顯示(構造方法與引數詳情):
  • ArrayAdapter (Context context, int resource)
    context(當前上下文)
    resource(一個佈局檔案的資源ID,其中包含一個在例項化檢視時使用的TextView)

  • ArrayAdapter (Context context, int resource, int textViewResourceId)
    context(當前上下文)
    resource(佈局檔案的資源ID,其中包含在例項化檢視時使用的佈局)
    textViewResourceId(要填充的佈局資源中的TextView的id)

  • ArrayAdapter (Context context, int resource, T[] objects)
    context(當前上下文)
    resource(佈局檔案的資源ID,其中包含在例項化檢視時使用的佈局)
    objects(在ListView中表示的物件,即 資料來源)

  • ArrayAdapter (Context context, int resource, int textViewResourceId, T[] objects)
    context(當前上下文)
    resource(佈局檔案的資源ID,其中包含在例項化檢視時使用的佈局)
    textViewResourceId(要填充的佈局資源中的TextView的id)
    objects(在ListView中表示的物件,即 資料來源)

  • ArrayAdapter (Context context, int resource, List objects)
    context(當前上下文)
    resource(佈局檔案的資源ID,其中包含在例項化檢視時使用的佈局)
    objects(在ListView中表示的物件,即 資料來源)

  • ArrayAdapter (Context context, int resource, int textViewResourceId, List objects)
    context(當前上下文)
    resource(佈局檔案的資源ID,其中包含在例項化檢視時使用的佈局)
    textViewResourceId(要填充的佈局資源中的TextView的id)
    objects(在ListView中表示的物件,即 資料來源)

舉一個簡單的例子:

xml佈局:
<ListView
    android:id="@+id/xListView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@color/colorAccent"
    android:dividerHeight="1dp"></ListView>
適配資料來源:
ListView listView = (ListView) findViewById(R.id.xListView);

String[] data = new String[20];
for (int i = 0; i < 20; i++) {
    data[i] = "張-" + i;
}

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data);

listView.setAdapter(adapter);
效果圖如下:

這裡寫圖片描述

常用方法

  • setAdapter(ListAdapter adapter)
    匹配這個列表檢視的資料

  • addFooterView(View v)或者addFooterView(View v, Object data, boolean isSelectable)
    在列表的底部新增一個固定的檢視,可以多次新增

  • addHeaderView(View v)或者addHeaderView(View v, Object data, boolean isSelectable)
    在列表的頂部新增一個固定的檢視,可一次新增,若第二次新增,則第二次新增的使徒不會顯示在頂部,而是會排列在第一次新增的頂部佈局下

  • smoothScrollToPosition(int position)
    滾動到指定的介面卡位置

  • removeHeaderView(View v)
    刪除先前新增的指定頭部檢視

  • removeFooterView(View v)
    刪除之前新增的指定頁尾檢視

  • getFooterViewsCount()
    獲取列表中頁尾檢視的數量

  • getHeaderViewsCount()
    獲取列表中頭檢視的數量

  • setOnScrollListener( AbsListView.OnScrollListener l)
    這是一個繼承至(android.widget.AbsListView)的方法,用它來監聽檢視滾動(每次列表滾動時都會收到通知的監聽器)

  • setFriction(float friction)
    用於摩擦的摩擦量,即控制滾動條的速度

自定義介面卡

自定義的xml佈局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:paddingBottom="16dp"
    android:paddingTop="16dp">

    <TextView
        android:id="@+id/item_test_name"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:text="阿西吧" />

    <TextView
        android:id="@+id/item_test_phone"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="4"
        android:gravity="center_vertical"
        android:text="18756935824" />

</LinearLayout>
為此佈局建立相對應的實體類:
/**
 * 簡單解釋一下Parcelable:相當與java的Serializable序列化
 * Parcelable是Android中特有的介面來實現類的序列化操作.
 * 因此在絕大多數的情況下,Android還是推薦使用Parcelable來完成對類的序列化操作的.
 */
public class ContactInfo implements Parcelable {
    private String name;
    private String phone;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
        dest.writeString(this.phone);
    }

    public ContactInfo() {
    }

    public ContactInfo(String name, String phone) {
        this.name = name;
        this.phone = phone;
    }

    protected ContactInfo(Parcel in) {
        this.name = in.readString();
        this.phone = in.readString();
    }

    public static final Parcelable.Creator<ContactInfo> CREATOR = new Parcelable.Creator<ContactInfo>() {
        @Override
        public ContactInfo createFromParcel(Parcel source) {
            return new ContactInfo(source);
        }

        @Override
        public ContactInfo[] newArray(int size) {
            return new ContactInfo[size];
        }
    };
}
建立相應的介面卡:
public class TestAdapter extends BaseAdapter {
    private Context context;
    private List<ContactInfo> list;

    public TestAdapter(Context context, List<ContactInfo> list) {
        this.context = context;
        this.list = list;
    }

    /**
     * 返回資料來源的 大小(長度)
     */
    @Override
    public int getCount() {
        //這是使用三目運算,防止 空指標 異常
        return list == null ? 0 : list.size();
    }

    /**
     * 返回當前 item 的資料
     */
    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    /**
     * 返回當前 item 的Id
     */
    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (null == convertView) {
            holder = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(R.layout.item_test, parent, false);
            holder.name = (TextView) convertView.findViewById(R.id.item_test_name);
            holder.phone = (TextView) convertView.findViewById(R.id.item_test_phone);
            convertView.setTag(holder);//setTag可以用來在檢視中儲存資料
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        ContactInfo info = list.get(position);
        holder.name.setText(info.getName());
        holder.phone.setText(info.getPhone());
        return convertView;
    }

    /**
     * 建立ViewHolder主要為了實現佈局重用
     */
    class ViewHolder {
        TextView name;
        TextView phone;
    }
}
測試程式碼:
ListView listView = (ListView) findViewById(R.id.listView);

List<ContactInfo> list = new ArrayList<>();

list.add(new ContactInfo("張三", "18756935824"));
list.add(new ContactInfo("李四", "18756935825"));
list.add(new ContactInfo("王五", "18756935826"));
list.add(new ContactInfo("校長", "18756935827"));
list.add(new ContactInfo("是否", "18756935828"));
list.add(new ContactInfo("返回", "18756935829"));
list.add(new ContactInfo("水岸", "18756935820"));
list.add(new ContactInfo("東方", "18756935814"));
list.add(new ContactInfo("諸葛", "18756935834"));
list.add(new ContactInfo("無極", "18756935844"));
list.add(new ContactInfo("小時", "18756935854"));
list.add(new ContactInfo("山東", "18756935864"));
list.add(new ContactInfo("煎餅", "18756935874"));
list.add(new ContactInfo("撒旦", "18756935884"));
list.add(new ContactInfo("挖人", "18756935899"));
list.add(new ContactInfo("非官", "18756935804"));
list.add(new ContactInfo("薩達", "18756935234"));
list.add(new ContactInfo("薩芬", "18756935324"));
list.add(new ContactInfo("收費", "18756935424"));
list.add(new ContactInfo("聖埃", "18756935524"));

adapter = new TestAdapter(this, list);
listView.setAdapter(adapter);
效果圖:

這裡寫圖片描述

拓展

我改變一下主介面佈局,並且利用addHeaderView(View v)與setOnScrollListener( AbsListView.OnScrollListener l) :
activity_main.xml   
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="#000"
        android:dividerHeight="1dp"
        android:scrollbars="none" />

    <View
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:background="#8c4e4e"
        android:visibility="gone" />

</RelativeLayout>
item_herder.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="24dp"
        android:paddingTop="24dp"
        android:text="這是一個測試test" />

</LinearLayout>
item_suspend.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <View
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:background="#8c4e4e" />

</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
    private ListView listView;
    private List<ContactInfo> list;
    private TestAdapter adapter;
    private View view;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        view = findViewById(R.id.view);
        listView = (ListView) findViewById(R.id.listView);

        list = new ArrayList<>();

        list.add(new ContactInfo("張三", "18756935824"));
        list.add(new ContactInfo("李四", "18756935825"));
        list.add(new ContactInfo("王五", "18756935826"));
        list.add(new ContactInfo("校長", "18756935827"));
        list.add(new ContactInfo("是否", "18756935828"));
        list.add(new ContactInfo("返回", "18756935829"));
        list.add(new ContactInfo("水岸", "18756935820"));
        list.add(new ContactInfo("東方", "18756935814"));
        list.add(new ContactInfo("諸葛", "18756935834"));
        list.add(new ContactInfo("無極", "18756935844"));
        list.add(new ContactInfo("小時", "18756935854"));
        list.add(new ContactInfo("山東", "18756935864"));
        list.add(new ContactInfo("煎餅", "18756935874"));
        list.add(new ContactInfo("撒旦", "18756935884"));
        list.add(new ContactInfo("挖人", "18756935899"));
        list.add(new ContactInfo("非官", "18756935804"));
        list.add(new ContactInfo("薩達", "18756935234"));
        list.add(new ContactInfo("薩芬", "18756935324"));
        list.add(new ContactInfo("收費", "18756935424"));
        list.add(new ContactInfo("聖埃", "18756935524"));

        adapter = new TestAdapter(this, list);
        listView.setAdapter(adapter);

        listView.addHeaderView(LayoutInflater.from(this).inflate(R.layout.item_herder, null));
        listView.addHeaderView(LayoutInflater.from(this).inflate(R.layout.item_suspend, null));

        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (firstVisibleItem > 0) {
                    if (!MainActivity.this.view.isShown()) {
                        MainActivity.this.view.setVisibility(View.VISIBLE);
                    }
                } else {
                    if (MainActivity.this.view.isShown()) {
                        MainActivity.this.view.setVisibility(View.GONE);
                    }
                }
            }
        });
    }
}
效果圖:

這裡寫圖片描述

驚喜嗎?這麼高大上的效果,就這樣實現了!

知識貴在分享!