Android開發之ListView使用經驗分享

yungfan發表於2016-05-25

在Android開發中,ListView是使用最廣泛的元件之一,雖然谷歌推出了RecycleView,但是很多專案中依舊在使用ListView,本文將總結一下使用過程中遇到的一些問題,與大家共勉~~~

一、ListView 與 Adapter

ListVeiw本身是一個容器元件,需要通過Adapter來完成資料的顯示,即通過setAdapter方法完成,而這個方法的引數是ListAdapter介面的物件,如 ArrayAdapter, CursorAdapter, SimpleAdapter,其中ArrayAdapter只適用於陣列操作,對於複雜的效果無法實現

二、SimpleAdapter

主要功能是將List集合的資料轉換成ListView可以支援的資料,其建構函式如下

SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)

引數含義:

context:關聯SimpleAdapter執行著的檢視的上下文。
resource: 引數值指定的佈局就是ListView中每一個列表項 。
data: 引數就是要載入到ListView中的資料。
(假設每一個列表項所對應的佈局檔案中包含了兩個元件:TextView和EditText,id分別為textview和edittext。 那麼在載入列表項時,需要通過元件的id和data引數中List元素中的Map物件對應)
from: 引數是Map物件的key
to :表示元件的id
(假設from = new String[]{"userId", "userName"},to = new int[]{R.id.userId,R.id.userName}。意思是將Map物件中key為userId 的value繫結到 R.id.userId上,userName的value繫結到 R.id.userName上)
三、android ListView幾個比較特別的屬性
1、stackFromBottom屬性,設定該屬性為true之後你做好的列表就會顯示到最下面

2、cacheColorHint屬性,很多人希望能夠改變一下它的背景,使他能夠符合整體的UI設計,改變背景背很簡單隻需要準備一張圖片然後指定屬性 android:background="@drawable/bg",不過不要高興地太早,當你這麼做以後,發現背景是變了,但是當你拖動,或者點選list空白位置的時候發現ListItem都變成黑色的了,破壞了整體效果。如果你只是換背景的顏色的話,可以直接指定android:cacheColorHint為你所要的顏色,如果你是用圖片做背景的話,那也只要將android:cacheColorHint指定為透明(#00000000)就可以了
android:cacheColorHint="@android:color/transparent"

3、divider屬性,該屬性作用是每一項之間需要設定一個圖片做為間隔,或是去掉item之間的分割線
android:divider="@drawable/list_driver",其中  @drawable/list_driver 是一個圖片資源,如果不想顯示分割線,只要設定為android:divider="@drawable/@null" 就可以了

4、fadingEdge屬性,上邊和下邊有黑色的陰影時設定 android:fadingEdge="none" 設定後沒有陰影了

5、scrollbars屬性,作用是隱藏listView的滾動條,android:scrollbars="none"

6、fadeScrollbars屬性,android:fadeScrollbars="true" 時可以實現滾動條的自動隱藏和顯示。
四、如何獲取ListView中單擊某個item後的資訊,onItemClick函式如下:
public void onItemClick(AdapterView<?> parent, View view, int position, long id)

舉例:X, Y是兩個listview,X裡有1,2,3,4這4個item,Y裡有a,b,c,d這4個item。如果你點了b這個item。如下:

AdapterView<?> parent   // parent相當於listview  Y介面卡的一個指標,可以通過它來獲得Y裡裝著的一切東西
View view    // view是你點b item的view的控制程式碼,就是你可以用這個view,來獲得b裡的控制元件的id後操作控制元件
int position   // position是b在Y介面卡裡的位置
long id    // id是b在listview Y裡的第幾行的位置,大部分時候position和id的值是一樣的
注意:

在點選事件中,經常遇到的一個坑是:ListView不能響應onItemClick事件
發生原因:當listview中包含button,checkbox等控制元件的時候,android會預設將focus給了這些控制元件,
也就是說listview的item根本就獲取不到focus,所以導致onitemclick事件不能觸發。
解決辦法:在Item佈局的根佈局加上android:descendantFocusability=”blocksDescendants”

五、ScrollView巢狀ListView只顯示一行的問題

解決方案:重寫ListView類的onMeasure方法(該方法同樣適用於巢狀GridView)

public class MyListView extends ListView
{
   private boolean haveScrollbar = true;
   public MyListView(Context context, AttributeSet attrs, int defStyle)
   {
      super(context, attrs, defStyle);
   } 
   public MyListView(Context context, AttributeSet attrs)
   {
      super(context, attrs);
   } 
   public MyListView(Context context)
   {
      super(context);
   }
   /**
    * 設定是否有ScrollBar,當要在ScollView中顯示時,應當設定為false。預設為 true
    *
    * @param haveScrollbars
    */
   publicvoid setHaveScrollbar(boolean haveScrollbar)
   {
      this.haveScrollbar = haveScrollbar;
   }
   @Override
   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
   {
      if (haveScrollbar == false)
      {
        // 根據模式計算每個child的高度和寬度
        int expandSpec = MeasureSpec.makeMeasureSpec(
              Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
      }
      else
      {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      }
   } 
}
六、繼承ListActivity完成ListView顯示

如果java類繼承了ListActivity,那麼表明該類只能存在一個ListView控制元件,可以通過getListView()方法取得預設的控制元件,但是在相應的xml檔案中,定義的ListView必須指明固定的id,android:id=”@android:id/list”

七、Header 和 Footer(一個ListView只有一個)

通過ListView的addHeaderView();和addFooterView();方法可以新增列表的頭部和尾部,但是注意:

1、head和footer是listview的列表項,如果你有一個head的話,那麼他的position就是0

2、在使用header和footer的過程中,如果需要動態的顯示和隱藏header和footer的話,如果直接設定GONE,雖然元素隱藏了,但是還是佔用著那個區域。此時需要給footer再加上一個layout或者是父級的view才可以,如下所示:

ListView listView = new ListView(context); 
TextView footer = new TextView(context);
LinearLayout footerParent = new LinearLayout(context); 
footerParent.addView(footer);
listView.addFooterView(footerParent); 
footer.setVisibility(View.GONE);

3、如何設定head和footer不可點選

public void addHeaderView (View v, Object data, boolean isSelectable)
public void addFooterView (View v, Object data, boolean isSelectable)

將第三個引數設定為flase即可

八、去除或替換listview 預設的點選選中時的顏色

1、去除預設的點選選中時的顏色

  • 設定列表layout的backgroudcolor屬性就OK了。
  • 設定
android:focusable="false" 
android:focusableInTouchMode="false"
android:cacheColorHint="#00000000" 
android:listSelector="#00000000"

2、替換listview 預設的點選選中時的顏色
設定listivew的listSelector屬性就可以了,如果要求點選變色,鬆開以後恢復,則需要用為該屬性指定一個xml檔案,裡面設定selector,為按下和鬆開設定顏色。

九、獲取ListView中某個Item中Button,併為其設定click事件

很多朋友喜歡繼承BaseAdapter適合器進行處理,其實直接繼承SimpleAdapter重寫getView方法進行處理即可

public View getView(int position, View convertView, ViewGroup parent) {
   View view = super.getView(position, convertView, parent);
   Button btn = (Button) v.findViewById(R.id.btn);
   //給當前的按鈕設定Tag,方便知道點選的是哪一個item的按鈕
   btn.setTag(position);
   btn.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
          Toast.makeText(mContext, "您點選了" + v.getTag(), Toast.LENGTH_LONG).show();
       }
    });
   return view;
}


相關文章