Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發系列(六) ListView使用教程二——QQ聯系人列表

Android開發系列(六) ListView使用教程二——QQ聯系人列表

編輯:關於Android編程

上一篇講了ListView的基本使用方式,是通過SimpleAdapter適配器來設置,但是這種方法無法實現在每一行添加按鈕,添加圖片,動態添加或者刪除某一行,或者使滾動條自動滑動到最底端的要求,因此需要自定義一個適配器類繼承BaseAdapter進而實現更加豐富的方法。     另外由於這已經不是我第一次做這個總結了,為了增加一點挑戰,這次就做一個 QQ好友列表的ListView          首先還是xml布局文件,在其中添加ListView控件:   主布局layout_main.xml   復制代碼 <RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"     android:paddingLeft="@dimen/activity_horizontal_margin"     android:paddingRight="@dimen/activity_horizontal_margin"     android:paddingTop="@dimen/activity_vertical_margin"     android:background="#00aaff"     tools:context=".MainActivity" >       <TextView         android:id="@+id/myText"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="聯系人"         android:textSize="7pt"         android:layout_centerHorizontal="true"         android:textColor="#ffffff"         android:textStyle="bold" />     <ListView          android:id="@+id/qq_list"         android:layout_width="match_parent"         android:layout_height="match_parent"         android:layout_below="@id/myText"/>       </RelativeLayout> 復制代碼 然後是每一行ListItem的布局,采用LinerLayout布局,一些注意的點都在裡面:   復制代碼 <?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="wrap_content"     android:background="#efefef" >          <!-- LinerLayout有比較奇怪的性質:當布局中的控件可以超出布局規定的大小 ,所以這裡一行的行寬改成由內部的幾個控件     控制,而LinerLayout的layout_height改成wrap_content ..  -->               <ImageButton          android:id="@+id/ct_photo"         android:layout_height="70dip"         android:layout_width="70dip"         android:layout_margin="5dip"         android:background="@drawable/contact_0"/>     <TextView          android:id="@+id/ct_name"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:padding="5dip"         android:layout_toRightOf="@id/ct_photo"         android:layout_alignTop="@id/ct_photo"         android:text="為你我受冷風吹"         android:textSize="8pt"         android:textStyle="bold"         android:maxLength="7"/>          <TextView          android:id="@+id/ct_sign"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:padding="5dip"         android:layout_toRightOf="@id/ct_photo"         android:layout_alignBottom="@id/ct_photo"         android:text="為什麼受傷的總是我"         android:textColor="#888888"/>       <!-- 注意不是layout_padding -->                       </RelativeLayout> 復制代碼 因為這裡使用的是自己定義的MyAdapter類,可以更靈活的實現列表的一些功能,比如和數據庫相聯系,動態更新數據、添加按鈕控件等等,在本例中模仿QQ列表為頭像設置成了ImageButton,後面的附圖中的一個Toast信息就是點擊圖像做出的相應,當然點擊一行也可以做出相應,這個後續可能會對QQ程序做一些擴展,如增加網絡模塊,聊天窗口等等。到時候再進一步討論。   下面是MyAdapter類,這個類最好和MainActivity類放在同一個包裡。   復制代碼 package com.example.android_qqlist;   import java.util.*;   import android.annotation.SuppressLint; import android.content.Context; import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.*;   public class MyAdapter extends BaseAdapter{     private Context context=null;     private int resources;     private ArrayList<HashMap<String,Object>> list=null;     private String[] from;     private int[] to;               /**      * 這裡仿照的是SimpleAdapter的形參列表      * @param context      * @param Resources      * @param list      * @param from      * @param to      */          public MyAdapter(Context context, int resources,             ArrayList<HashMap<String, Object>> list, String[] from, int[] to) {         super();         this.context = context;         this.resources = resources;         this.list = list;         this.from = from;         this.to = to;     }       /**      * 剩下的問題就是依次實現BaseAdapter的這幾個類方法就可以了      */          @Override     public int getCount() {        //這個方法返回的是ListView的行數         // TODO Auto-generated method stub         return list.size();     }              @Override     public Object getItem(int arg0) {      //這個方法沒必要使用,可以用getItemId代替         // TODO Auto-generated method stub         return null;     }       @Override     public long getItemId(int itemId) {     //點擊某一行時會調用該方法,其形參由安卓系統提供         // TODO Auto-generated method stub         return itemId;     }       /**      * getView方法為系統在繪制每一行時調用,在此方法中要設置需要顯示的文字,圖片,      * 以及為按鈕設置監聽器。      *       * 形參意義:      * position:當前繪制的item 的位置(ID);      * convertView,系統在繪制ListView時,如果是繪制第一個Item(即第一行),convertView為null,當      * 繪制第二個及以後的Item的convertView不為空,這時可以直接利用這個convertView的getTag()方法,獲得各控件      * 的實例,並進行相應的設置,這樣可以加快繪圖速度。      *       * 為了為convertView設置附加信息Tag,這裡創建一個內部類ViewHolder,用於盛放一行中所有控件的引用,將這些引用      * 實例化後作為convertView的附加信息。      */     class ViewHolder{         public ImageButton ctPhoto=null;         public TextView ctName=null,ctSign=null;                  /*          * 從這裡可以看出,from和to數組彼此之間的元素應該一一對應,同時from和to各自元素內部的順序不同,最後ListView          * 呈現的位置也會不同!          */         public ViewHolder(View convertView){             ctPhoto=(ImageButton)convertView.findViewById(to[0]);                 /*注意View和Activity都屬於容器類,都需要設置布局文件,內部都含有子控件,且都有findViewById()              * 他們之間沒有明顯的繼承關系              */             ctName=(TextView)convertView.findViewById(to[1]);             ctSign=(TextView)convertView.findViewById(to[2]);                      }              }          class ImageListener implements OnClickListener{           private int position;                  public ImageListener(int position){             this.position=position;         }                          //構造函數沒有返回值                  @Override         public void onClick(View v) {             // TODO Auto-generated method stub             String str=list.get(position).get(from[1]).toString();             Toast.makeText(context,str+" is Clicked" , Toast.LENGTH_LONG).show();                      }              }            @Override     public View getView(int position, View convertView, ViewGroup arg2) {         // TODO Auto-generated method stub                  /**          * 首先判斷是不是第一次創建Item,若是,則創建convertView實例和ViewHolder對象,並通過fandViewById()方法          * 獲得每一行中所有空間的實例放在ViewHolder對象中,然後對convertView設置標簽          */         ViewHolder viewHolder=null;                  //注意convertView不是隨意創建的,需要有LayoutInflater,根據list_item布局文件創建         if(convertView==null){             LayoutInflater inflater=LayoutInflater.from(context);             convertView=inflater.inflate(resources,null);    //這裡的null是一個ViewGroup形參,基本用不上             viewHolder=new ViewHolder(convertView);             convertView.setTag(viewHolder);                      }         else{             viewHolder=(ViewHolder)convertView.getTag();    //通過getTag()方法獲得附加信息         }         /**          * 這裡對viewHolder中的各個控件進行相應的設置          */         /**          * @author DragonGN          * 這裡出現了一個問題:在繪制當前行的ListItem時,只需要對當前行的控件進行設置,因此這裡不能加一個for          * 循環對每一個list中的每一個元素進行遍歷,而應該根據當前創建的ListItem行的position,然後          * 訪問數據庫list中相應位置的Map的數據,進行控件的設置!          */           /**          * 注意這裡必須是setBackgroundDrawable() 而不是setBackground(),後者會報錯,盡管前者過期了但一樣可用          */             viewHolder.ctPhoto.setBackgroundDrawable((Drawable)(list.get(position).get(from[0])));              //Map中要添加一個Drawable對象,這裡的from和to中的元素應該一一對應,其順序也應該對應ViewHolder構造方法中控件的調用的順序                          viewHolder.ctName.setText((String)(list.get(position).get(from[1])));             viewHolder.ctSign.setText((String)(list.get(position).get(from[2])));                 viewHolder.ctPhoto.setOnClickListener(new ImageListener(position));                           return convertView;     //把這個每一行的View對象返回     }   } 復制代碼     最後就是MainActivity類了,與因為MyAdapter的封裝方式與SimpleAdpter是一樣額,因此這裡MainActivity的操作基本不變。   復制代碼 package com.example.android_qqlist;   import java.util.*;   import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.ListView;   public class MainActivity extends Activity {       //每一列的列名/Map的鍵名  和其對應的View子控件的ID     String[] from={"userPhoto","userName","userSign"};           //這裡的內容對應後面HashMap中的鍵     int[] to={R.id.ct_photo,R.id.ct_name,R.id.ct_sign};          //整個ListView所顯示的全部信息和資源數組     int[] photoRes={R.drawable.contact_0,R.drawable.contact_1,R.drawable.contact_2,R.drawable.contact_3};     String[] strName={"暗夜之殇","街角的幸福","靜悄悄","憤怒的小胖"};     String[] strSign={"Where is my love...","有些事終於想開了","總有一天會尋找到自己的幸福","誰再叫我小胖我跟誰急..."};          //數據鏈表和Map容器     ArrayList<HashMap<String,Object>> list=null;     HashMap<String,Object> map=null;          ListView listView=null;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         listView=(ListView)findViewById(R.id.qq_list);         list=new ArrayList<HashMap<String,Object>>();                  for(int i=0; i<4; i++){             map=new HashMap<String,Object>();    //map調用put方法添加鍵值對             map.put("userPhoto",getResources().getDrawable(photoRes[i]));             map.put("userName", strName[i]);             map.put("userSign",strSign[i]);             list.add(map);                 }                  //創建自定義的MyAdapter對象         MyAdapter adapter=new MyAdapter(this,R.layout.list_item,list,from,to);                  //調用ListView的setAdapter()方法設置適配器         listView.setAdapter(adapter);                       }       @Override     public boolean onCreateOptionsMenu(Menu menu) {         // Inflate the menu; this adds items to the action bar if it is present.         getMenuInflater().inflate(R.menu.main, menu);         return true;     }   } 復制代碼
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved