編輯:關於Android編程
一、繼承listActivity、使用arrayAdapter
使用ListView和arrayAdapter布局,是ListView布局中最為簡單的一種,首先我們會建立一個組件用來顯示數據,例如main.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 主界面本身就是一個顯示組件 -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
>
</TextView>
Activity代碼如下
package cn.com.android.grid;
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
public class listViewTest extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String data[] = getData();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.main, data);
this.setListAdapter(arrayAdapter);// ArrayAdapter 繼承自baseAdapter,baseAdapter又繼承自ListAdapter
}
/**
* @author chenzheng_java
* @description 獲取一個數組列表
*/
private String[] getData(){
String[] data = new String[100];
for (int i = 0; i < 100; i++) {
data[i] = "列表項" + i;
}
return data;
}
}
如果這裡activity不想繼承ListActivity,那麼我們可以這樣編寫
package cn.com.android.grid;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class ListViewTest2 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView listView = new ListView(this);
listView.setAdapter(new ArrayAdapter<String>(this,R.layout.main,getData()));
setContentView(listView);
}
/**
* @author chenzheng_java
* @description 獲取一個數組列表
*/
private String[] getData(){
String[] data = new String[100];
for (int i = 0; i < 100; i++) {
data[i] = "列表項" + i;
}
return data;
}
}
廢話連篇:
兩種實現辦法寫的代碼差距很大,有很多初學者可能很暈。不過不要緊,我們一起看下ListActivity到底是怎麼實現的。
代碼摘錄如下
public class ListActivity extends Activity {
/**
* This field should be made private, so it is hidden from the SDK.
* {@hide}
*/
protected ListAdapter mAdapter;
/**
* This field should be made private, so it is hidden from the SDK.
* {@hide}
*/
protected ListView mList;
我們看到了,實際上當我們繼承ListActivity時,實際上裡面已經有一個從ListActivity中繼承的listview了,所以千萬別以為差距很大,本質上,實現的步驟是一摸一樣的。你可以認為,android給你提供了一個免費的工具類。沒什麼稀奇的。
步驟上,還是三大步:
第一步:准備布局文件main.xml
第二步:獲取數據 getData()
第三步:綁定數據源setListAdapter();
二、用simpleAdapter綁定數據
最終效果圖

目錄結構

main.xml主布局文件,代碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:text="@string/name"
android:gravity="center"
android:layout_width="150px"
android:layout_height="wrap_content"
/>
<TextView
android:text="@string/age"
android:gravity="center"
android:layout_width="170px"
android:layout_height="wrap_content"
/>
</LinearLayout>
<ListView
android:id="@+id/listView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
user.xml組件布局文件代碼
<?xml version="1.0" encoding="utf-8"?> <!-- 創建存放一行數據的組件 --> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TableRow> <ImageView android:id="@+id/image" android:layout_width="50px" android:layout_height="50px" ></ImageView> <TextView android:id="@+id/userName" android:gravity="center" android:layout_height="wrap_content" android:layout_width="150px" ></TextView> <TextView android:id="@+id/userAge" android:gravity="center" android:layout_height="wrap_content" android:layout_width="170px" ></TextView> </TableRow> </TableLayout>
主Activity,listView.java代碼
package cn.com.android.listView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class listView extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView listView = (ListView) findViewById(R.id.listView);
/* 參數一多,有些人就頭暈了。這裡解說下,各個參數的意思。
* 第一個參數 this 代表的是當前上下文,可以理解為你當前所處的activity
* 第二個參數 getData() 一個包含了數據的List,注意這個List裡存放的必須是map對象。simpleAdapter中的限制是這樣的List<? extends Map<String, ?>> data
* 第三個參數 R.layout.user 展示信息的組件
* 第四個參數 一個string數組,數組內存放的是你存放數據的map裡面的key。
* 第五個參數:一個int數組,數組內存放的是你展示信息組件中,每個數據的具體展示位置,與第四個參數一一對應
* */
SimpleAdapter adapter = new SimpleAdapter(this, getData(), R.layout.user,
new String[]{"image","userName","userAge"}, new int[]{R.id.image,R.id.userName,R.id.userAge});
listView.setAdapter(adapter);
}
/**
* @author chenzheng_java
* @description 准備一些測試數據
* @return 一個包含了數據信息的hashMap集合
*/
private ArrayList<HashMap<String, Object>> getData(){
ArrayList<HashMap<String, Object>> arrayList = new ArrayList<HashMap<String,Object>>();
for(int i=0;i<10;i++){
HashMap<String, Object> tempHashMap = new HashMap<String, Object>();
tempHashMap.put("image", R.drawable.icon);
tempHashMap.put("userName", "用戶"+i);
tempHashMap.put("userAge", 30-i);
arrayList.add(tempHashMap);
}
return arrayList;
}
}
strings.xml代碼
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">布局列表展示</string> <string name="app_name">列表布局</string> <string name="name">姓名</string> <string name="age">年齡</string> </resources>
廢話連綿:
我們一起看看結構,一個主布局文件,一個組件布局文件,一個Activity類。
依舊分為三步:
第一步:定義布局文件,設計UI,包括尋找合適的圖片了等等……
第二步:獲取數據。這裡用的是simpleAdapter,所以要求數據必須固定格式的;
第三步:綁定數據源。
然後,我們就可以看到我們想要的結果了。
三、有按鈕的ListView
下面我們是要看使用自定義的Adapter綁定數據、通過contextView.setTag綁定數據的方式,最終結果圖:

代碼結構示意圖

vlist2.xml代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5px"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="22px"
/>
<TextView
android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="13px"
/>
</LinearLayout>
<Button
android:id="@+id/view_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click me"
android:gravity="center"
/>
</LinearLayout>
listView3.java代碼
package cn.com.android2.listview;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.ListActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
public class listView3 extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 獲取虛擬的數據,數據的格式有嚴格的要求哦
ArrayList<HashMap<String, Object>> data = getData();
//模仿SimpleAdapter實現的自己的adapter
MyAdapter adapter = new MyAdapter(this, data);
/**
* 有些人很迷糊,我們都知道vlist2.xml相當於存儲一行數據的組件布局,我們在前邊的代碼中,都是有一個主布局文件main.xml的,
* 組件布局文件是放在主布局文件上顯示的,一般代碼中都是通過setContentView()來指定主布局文件的。為何這裡根本就沒有用到
* ,但是listView還能有一個界面來呈現呢。
* 讓我們看看setListAdapter在ListActivity中的實現,
* public void setListAdapter(ListAdapter adapter) {
synchronized (this) {
ensureList();
mAdapter = adapter;
mList.setAdapter(adapter);
}
}
裡面調用了一個ensureList方法,我們再來看看這個方法:
private void ensureList() {
if (mList != null) {
return;
}
setContentView(com.android.internal.R.layout.list_content);
}
現在看到了,這裡有個 setContentView方法,裡面設置了我們的組件在一個android自己提供的界面上顯示。
原來,我們的理論還是適用的,只不過ListActivity給我進行了隱藏實現。
*/
setListAdapter(adapter);
}
/**
* @author chenzheng_java
* @description 准備一些測試數據
* @return 一個包含了數據信息的hashMap集合
*/
private ArrayList<HashMap<String, Object>> getData(){
ArrayList<HashMap<String, Object>> arrayList = new ArrayList<HashMap<String,Object>>();
for(int i=0;i<10;i++){
HashMap<String, Object> tempHashMap = new HashMap<String, Object>();
tempHashMap.put("image", R.drawable.icon);
tempHashMap.put("title", "標題"+i);
tempHashMap.put("info", "描述性信息");
arrayList.add(tempHashMap);
}
return arrayList;
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Log.i("輸出信息",v.toString() );
}
}
zujian.java
package cn.com.android2.listview;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public final class ZuJian {
public ImageView imageView;
public TextView titleView;
public TextView infoView;
public Button button;
}
MyAdapter.java
package cn.com.android2.listview;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
/**
* @author chenzheng_java
* @description 該類的部分實現模仿了SimpleAdapter
*/
public class MyAdapter extends BaseAdapter {
private ArrayList<HashMap<String, Object>> data;
/**
* LayoutInflater 類是代碼實現中獲取布局文件的主要形式
*LayoutInflater layoutInflater = LayoutInflater.from(context);
*View convertView = layoutInflater.inflate();
*LayoutInflater的使用,在實際開發種LayoutInflater這個類還是非常有用的,它的作用類似於 findViewById(),
不同點是LayoutInflater是用來找layout下xml布局文件,並且實例化!
而findViewById()是找具體xml下的具體 widget控件(如:Button,TextView等)。
*/
private LayoutInflater layoutInflater;
private Context context;
public MyAdapter(Context context,ArrayList<HashMap<String, Object>> data) {
this.context = context;
this.data = data;
this.layoutInflater = LayoutInflater.from(context);
}
/**
*獲取列數
*/
public int getCount() {
return data.size();
}
/**
*獲取某一位置的數據
*/
public Object getItem(int position) {
return data.get(position);
}
/**
*獲取唯一標識
*/
public long getItemId(int position) {
return position;
}
/**
* android繪制每一列的時候,都會調用這個方法
*/
public View getView(int position, View convertView, ViewGroup parent) {
ZuJian zuJian = null;
if(convertView==null){
zuJian = new ZuJian();
// 獲取組件布局
convertView = layoutInflater.inflate(R.layout.vlist2, null);
zuJian.imageView = (ImageView) convertView.findViewById(R.id.image);
zuJian.titleView = (TextView) convertView.findViewById(R.id.title);
zuJian.infoView = (TextView) convertView.findViewById(R.id.info);
zuJian.button = (Button) convertView.findViewById(R.id.view_btn);
// 這裡要注意,是使用的tag來存儲數據的。
convertView.setTag(zuJian);
}
else {
zuJian = (ZuJian) convertView.getTag();
}
// 綁定數據、以及事件觸發
zuJian.imageView.setBackgroundResource((Integer) data.get(position).get("image"));
zuJian.titleView.setText((String)data.get(position).get("title"));
zuJian.infoView.setText((String)data.get(position).get("info"));
zuJian.button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
showInfo();
}
});
return convertView;
}
/**
*當用戶點擊按鈕時觸發的事件,會彈出一個確認對話框
*/
public void showInfo(){
new AlertDialog.Builder(context)
.setTitle("我的listview")
.setMessage("介紹...")
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
}
}
廢話連篇:
代碼中的注釋已經解釋的很清楚了,這裡再次強調一遍,三步驟
第一步:准備主布局文件、組件布局文件等
第二步:獲取並整理數據
第三部:綁定數據,這裡我們是通過自己編寫adapter來完成的。
listView在開始繪制的時候,系統首先調用getCount()函數,根據他的返回值得到listView的長度,然後根據這個長度,調用getView()逐一繪制每一行。
如果你的getCount()返回值是0的話,列表將不顯示同樣return 1,就只顯示一行。
系統顯示列表時,首先實例化一個適配器(這裡將實例化自定義的適配器)。當手動完成適配時,必須手動映射數據,這需要重寫getView()方法。系統在繪制列表的每一行的時候將調用此方法。
getView()有三個參數,position表示將顯示的是第幾行,covertView是從布局文件中inflate來的布局。我們用LayoutInflater的方法將定義好的vlist2.xml文件提取成View實例用來顯示。然後將xml文件中的各個組件實例化(簡單的findViewById()方法)。
這樣便可以將數據對應到各個組件上了。但是按鈕為了響應點擊事件,需要為它添加點擊監聽器,這樣就能捕獲點擊事件。至此一個自定義的listView就完成了,現在讓我們回過頭從新審視這個過程。系統要繪制ListView了,他首先獲得要繪制的這個列表的長度,然後開始繪制第一行,怎麼繪制呢?調用getView()函數。在這個函數裡面首先獲得一個View(實際上是一個ViewGroup),然後再實例並設置各個組件,顯示之。好了,繪制完這一行了。那 再繪制下一行,直到繪完為止。在實際的運行過程中會發現listView的每一行沒有焦點了,這是因為Button搶奪了listView的焦點,只要布局文件中將Button設置為沒有焦點就OK了。
詳解Android使用OKHttp3實現下載(斷點續傳、顯示進度)
OKHttp3是如今非常流行的Android網絡請求框架,那麼如何利用Android實現斷點續傳呢,今天寫了個Demo嘗試了一下,感覺還是有點意思准備階段我們會用到OKH
android 項目 local_Test_exam 代碼分享
本android項目是致力於建立一個本地的sqlite數據庫,然後存儲考試的題目,android應用調用sqlite數據庫中的數據,生成相應的答題界面。下面是代碼解析&n
Android學習路線(二十四)ActionBar Fragment運用最佳實踐
通過前面的幾篇博客,大家看到了Google是如何解釋action bar和fragment以及推薦的用法。俗話說沒有demo的博客不是好博客,下面我會介紹一
MPAndroidChart系列源碼解讀(五)
本篇主要是LineChart實戰相關知識和簡單的源碼剖析,相關源碼沒有,自己動手實踐學習才是最有效的方法。LineChart Simple運行效果圖個人感官覺得某些屬性設