android開發(fā)教程之使用listview顯示qq聯(lián)系人列表
首先還是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="聯(lián)系人"
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有比較奇怪的性質(zhì):當(dāng)布局中的控件可以超出布局規(guī)定的大小 ,所以這里一行的行寬改成由內(nèi)部的幾個控件
控制,而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="為你我受冷風(fēng)吹"
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類,可以更靈活的實現(xiàn)列表的一些功能,比如和數(shù)據(jù)庫相聯(lián)系,動態(tài)更新數(shù)據(jù)、添加按鈕控件等等,在本例中模仿QQ列表為頭像設(shè)置成了ImageButton,后面的附圖中的一個Toast信息就是點擊圖像做出的相應(yīng),當(dāng)然點擊一行也可以做出相應(yīng),這個后續(xù)可能會對QQ程序做一些擴展,如增加網(wǎng)絡(luò)模塊,聊天窗口等等。到時候再進一步討論。
下面是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;
}
/**
* 剩下的問題就是依次實現(xiàn)BaseAdapter的這幾個類方法就可以了
*/
@Override
public int getCount() { //這個方法返回的是ListView的行數(shù)
// 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) { //點擊某一行時會調(diào)用該方法,其形參由安卓系統(tǒng)提供
// TODO Auto-generated method stub
return itemId;
}
/**
* getView方法為系統(tǒng)在繪制每一行時調(diào)用,在此方法中要設(shè)置需要顯示的文字,圖片,
* 以及為按鈕設(shè)置監(jiān)聽器。
*
* 形參意義:
* position:當(dāng)前繪制的item 的位置(ID);
* convertView,系統(tǒng)在繪制ListView時,如果是繪制第一個Item(即第一行),convertView為null,當(dāng)
* 繪制第二個及以后的Item的convertView不為空,這時可以直接利用這個convertView的getTag()方法,獲得各控件
* 的實例,并進行相應(yīng)的設(shè)置,這樣可以加快繪圖速度。
*
* 為了為convertView設(shè)置附加信息Tag,這里創(chuàng)建一個內(nèi)部類ViewHolder,用于盛放一行中所有控件的引用,將這些引用
* 實例化后作為convertView的附加信息。
*/
class ViewHolder{
public ImageButton ctPhoto=null;
public TextView ctName=null,ctSign=null;
/*
* 從這里可以看出,from和to數(shù)組彼此之間的元素應(yīng)該一一對應(yīng),同時from和to各自元素內(nèi)部的順序不同,最后ListView
* 呈現(xiàn)的位置也會不同!
*/
public ViewHolder(View convertView){
ctPhoto=(ImageButton)convertView.findViewById(to[0]);
/*注意View和Activity都屬于容器類,都需要設(shè)置布局文件,內(nèi)部都含有子控件,且都有findViewById()
* 他們之間沒有明顯的繼承關(guān)系
*/
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;
} //構(gòu)造函數(shù)沒有返回值
@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
/**
* 首先判斷是不是第一次創(chuàng)建Item,若是,則創(chuàng)建convertView實例和ViewHolder對象,并通過fandViewById()方法
* 獲得每一行中所有空間的實例放在ViewHolder對象中,然后對convertView設(shè)置標(biāo)簽
*/
ViewHolder viewHolder=null;
//注意convertView不是隨意創(chuàng)建的,需要有LayoutInflater,根據(jù)list_item布局文件創(chuàng)建
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中的各個控件進行相應(yīng)的設(shè)置
*/
/**
* @author DragonGN
* 這里出現(xiàn)了一個問題:在繪制當(dāng)前行的ListItem時,只需要對當(dāng)前行的控件進行設(shè)置,因此這里不能加一個for
* 循環(huán)對每一個list中的每一個元素進行遍歷,而應(yīng)該根據(jù)當(dāng)前創(chuàng)建的ListItem行的position,然后
* 訪問數(shù)據(jù)庫list中相應(yīng)位置的Map的數(shù)據(jù),進行控件的設(shè)置!
*/
/**
* 注意這里必須是setBackgroundDrawable() 而不是setBackground(),后者會報錯,盡管前者過期了但一樣可用
*/
viewHolder.ctPhoto.setBackgroundDrawable((Drawable)(list.get(position).get(from[0])));
//Map中要添加一個Drawable對象,這里的from和to中的元素應(yīng)該一一對應(yīng),其順序也應(yīng)該對應(yīng)ViewHolder構(gòu)造方法中控件的調(diào)用的順序
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的鍵名 和其對應(yīng)的View子控件的ID
String[] from={"userPhoto","userName","userSign"}; //這里的內(nèi)容對應(yīng)后面HashMap中的鍵
int[] to={R.id.ct_photo,R.id.ct_name,R.id.ct_sign};
//整個ListView所顯示的全部信息和資源數(shù)組
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...","有些事終于想開了","總有一天會尋找到自己的幸福","誰再叫我小胖我跟誰急..."};
//數(shù)據(jù)鏈表和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調(diào)用put方法添加鍵值對
map.put("userPhoto",getResources().getDrawable(photoRes[i]));
map.put("userName", strName[i]);
map.put("userSign",strSign[i]);
list.add(map);
}
//創(chuàng)建自定義的MyAdapter對象
MyAdapter adapter=new MyAdapter(this,R.layout.list_item,list,from,to);
//調(diào)用ListView的setAdapter()方法設(shè)置適配器
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;
}
}

這幾個頭像是我自己下載的圖片,其對應(yīng)的資源地址在 MainActivity中用一個 photoRes數(shù)組表示的~
相關(guān)文章
詳解Android開發(fā)技巧之PagerAdapter實現(xiàn)類的封裝
這篇文章主要介紹了詳解Android開發(fā)技巧之PagerAdapter實現(xiàn)類的封裝,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11android關(guān)于按鈕點擊效果實現(xiàn)的方法
今天小編就為大家分享一篇關(guān)于android關(guān)于按鈕點擊效果實現(xiàn)的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03Android onCreateOptionsMenu的使用方法總結(jié)
這篇文章主要介紹了Android onCreateOptionsMenu的使用方法總結(jié)的相關(guān)資料,在Android下,每一個activity都捆綁了一個Menu,要想定義和使用菜單,都必須在Activity下進行操作,需要的朋友可以參考下2017-08-08Android 實現(xiàn)閃屏頁和右上角的倒計時跳轉(zhuǎn)實例代碼
本文給大家分享一段實例代碼給大家介紹android實現(xiàn)閃屏頁和右上角的倒計時跳轉(zhuǎn)實例代碼,閃屏頁用到了handler和CountDownTimer類,還需配置一下Activity的主題,感興趣的朋友參考下吧2016-02-02Android shell命令行中過濾adb logcat輸出的方法
本文主要介紹Android shell命令行中過濾adb logcat輸出,這里詳細(xì)說明了shell 命令過濾logcat 輸出內(nèi)容,有需要的小伙伴可以參考下2016-08-08