Android中的listview目測是一個使用頻率很高的組件,因此今天來總結一下listview的基礎的用法。java
1、最基本的綁定android
java代碼:網絡
package com.tmnw; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends Activity { /*----ListView MVC實現----*/ // model List<String> data; // view ListView lv; // controller ArrayAdapter<String> adapter; int size = 1; // 初始化組件 private void initWidget() { lv = (ListView) findViewById(R.id.list); } // 初始化綁定數據 private void initData() { if (lv == null) return; // 第一步:獲取數據源(model) data = new ArrayList<String>(); appendData(); // 第二步:new一個適配器(controller) // 參數1:Context // 參數2:listview的item佈局 // 參數3:數據填充在item佈局下的那個控件id // 參數4:填充的數據 adapter = new ArrayAdapter<String>(this, R.layout.simple_text, R.id.text1, data); // 第三步:給listview設置適配器(view) lv.setAdapter(adapter); } // 添加數據 private void appendData() { if (data == null) return; for (int i = 0; i < 10; i++) { data.add("" + size++); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initWidget(); initData(); } }
xml代碼:ide
activity_main.xml
佈局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1" > </ListView> </LinearLayout>
simple_text.xml
ui
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp" android:textIsSelectable="false" />
畫面效果:this
2、給ListView添加頭和尾部spa
java代碼:線程
// 初始化組件 private void initWidget() { lv = (ListView) findViewById(R.id.list); header = getLayoutInflater().inflate(R.layout.simple_text, null); ((TextView) header.findViewById(R.id.text1)).setText("這是一個頭部"); footer = getLayoutInflater().inflate(R.layout.simple_text, null); ((TextView) footer.findViewById(R.id.text1)).setText("加載中..."); } // 初始化綁定數據 private void initData() { if (lv == null) return; // 第一步:獲取數據源(model) data = new ArrayList<String>(); appendData(); // 第二步:new一個適配器(controller) // 參數1:Context // 參數2:listview的item佈局 // 參數3:數據填充在item佈局下的那個控件id // 參數4:填充的數據 adapter = new ArrayAdapter<String>(this, R.layout.simple_text, R.id.text1, data); // 第三步:給listview設置適配器(view) // addHeaderView和addFooterView必定要有一個在setAdapter以前調用,或者2個都在setAdapter以前調用 lv.addHeaderView(header); lv.setAdapter(adapter); // 這裏的參數null是數據,false說明是不能被選中的 lv.addFooterView(footer, null, false); // 設置尾部無分割線,頭部不想要分割線同理 lv.setFooterDividersEnabled(false); }
畫面效果:
3、給ListView添加下滑加載中的一種實現方式
由於listview要滾動,因此給它添加滾動監聽,爲了書寫簡便,我讓本Activity實現了OnScrollListener
public class MainActivity extends Activity implements OnScrollListener
java代碼:
先增長几個變量
Button scrollInfo; Thread currentThread;
初始化組件代碼修改下
lv = (ListView) findViewById(R.id.list); scrollInfo = (Button) findViewById(R.id.scroll_info); header = getLayoutInflater().inflate(R.layout.simple_text, null); ((TextView) header.findViewById(R.id.text1)).setText("這是一個頭部"); footer = getLayoutInflater().inflate(R.layout.simple_text, null); ((TextView) footer.findViewById(R.id.text1)).setText("加載中...");
在onCreate中添加
lv.setOnScrollListener(this);
實現OnScrollListener方法:
@Override public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState) { // 手指接觸屏幕滑動 case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: // 手指離開屏幕作慣性滑動 case OnScrollListener.SCROLL_STATE_FLING: // 當滑動要最後一行時加載數據 if (view.getLastVisiblePosition() == view.getCount() - 1) { // 能夠經過網絡加載數據等。 // 判斷是否仍是在加載中 if (currentThread == null || !currentThread.isAlive()) { // 添加listview尾部控件加載中 lv.addFooterView(footer, null, false); // 啓動線程加載數據 currentThread = new DataLoadThread(); currentThread.start(); } } break; // 不滑動 case OnScrollListener.SCROLL_STATE_IDLE: break; } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // firstVisibleItem:第一個顯示的item位置 // visibleItemCount:當前顯示的item個數 // totalItemCount:listview的item總個數 scrollInfo.setText("first:" + firstVisibleItem + " visible:" + visibleItemCount + " total:" + totalItemCount); }
添加加載數據的線程
// 模擬加載數據 class DataLoadThread extends Thread { @Override public void run() { try { Thread.sleep(2000); appendData(); // 由於Android控件只能經過主線程(ui線程)更新,因此用此方法 runOnUiThread(new Runnable() { @Override public void run() { // 加載完畢,移除尾部控件 lv.removeFooterView(footer); // 當數據改變時調用此方法通知view更新 adapter.notifyDataSetChanged(); } }); } catch (InterruptedException e) { e.printStackTrace(); } } }
畫面效果:
4、給ListView添加item點擊事件
爲了書寫簡便,我讓本Activity實現了OnItemClickListener
public class MainActivity extends Activity implements OnScrollListener, OnItemClickListener
java代碼:
而後實現其方法
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText( this, "position:" + position + " item:" + parent.getItemAtPosition(position).toString(), Toast.LENGTH_LONG).show(); }
給listview添加監聽
lv.setOnItemClickListener(this);
畫面效果:
(模擬器出問題了使用了真機調試,沒想到圖片這麼大,不過比模擬器快多了)
5、自定義適配器的使用
java代碼:
// 自定義基礎適配器 class MyAdapter extends BaseAdapter { // listview顯示的個數,若是有數據源有10條,而返回5,那麼lv永遠只能顯示5條 // 因此最好就返回數據源的條數就行了 @Override public int getCount() { return data.size(); } // 獲取item綁定的數據時調用 @Override public Object getItem(int position) { return data.get(position); } // itemId @Override public long getItemId(int position) { return position; } // lv顯示幾個item就會調用幾回此方法,而後返回一個view對象顯示 // position:位置 // convertView:若是lv不能顯示所有的數據,那麼滾動後會把從顯示到不顯示的View傳進來複用 @Override public View getView(int position, View convertView, ViewGroup parent) { View view; if (convertView == null) { view = getLayoutInflater().inflate(R.layout.simple_text, null); } else { view = convertView; } TextView tv = (TextView) view.findViewById(R.id.text1); tv.setText(data.get(position)); // 隔行變色,能夠爲所欲爲 if ((position & 1) == 1) { tv.setBackgroundResource(android.R.color.holo_green_light); } else { tv.setBackgroundResource(android.R.color.holo_red_light); } return view; } }
而後修改一下setAdapter()
// adapter = new ArrayAdapter<String>(this, R.layout.simple_text, // R.id.text1, data); adapter = new MyAdapter();
畫面效果: