編輯:關於Android編程
ListView是Android開發中比較常用的一個組件,它以列表的形式展示信息,並能根據信息的長度自適應顯示。比如說我們手機裡的通訊錄就用到了ListView顯示聯系人信息。在大量的場合下,我們都需要使用這個控件。雖然在Android 5.0時代,RecyclerView在很多地方都在逐漸取代ListView,但ListView的使用范圍依然非常的廣泛。我們也不能跳過ListView直接去學習RecyclerView,對ListView的透徹理解是十分有必要的。
首先來看ListView在View樹中所處的位置:
ListView的官方解釋:
A view that shows items in a vertically scrolling list.
The items come from the {@link ListAdapter} associated with this view.
即:一種在垂直滾動列表中顯示項目的視圖。
顯示的項目(數據)通過ListAdapter適配器來與視圖關聯。
數據適配器是連接數據源和視圖界面的橋梁,它用來把復雜的數據(數組、鏈表、數據庫、集合等)填充在指定視圖界面上。數據適配器的實現過程為:1.新建適配器–>2.添加數據源到適配器–>3.視圖加載適配器。
那麼ListAdapter是什麼適配器呢?Adapter是所有適配器的祖先接口,下圖為ListAdapter在所有適配器繼承樹中的位置:
自定義數據適配器的時候用到了BaseAdapter類,那麼ListAdapter和BaseAdapter是什麼關系呢?只看名字好像BaseAdapter是ListAdapter的長輩,但實際上ListAdapter是所有可以用於ListView的適配器的祖先,且僅僅為一個接口。下面為ListAdapter的繼承樹:
這樣,顯示的項目(數據)通過ListAdapter適配器來與視圖關聯這句話的含義便很易理解了,不管是ArrayAdapter、SimpleAdapter、SimpleCursorAdapter或者自定義BaseAdapter,只要這些適配器實現了ListAdapter接口,就可以統稱為ListAdapter適配器,繼而用於ListView的數據適配,下面為展開的繼承樹:
這下我們就不用去詢問別人ListView有哪幾種適配器了,我們已經自己推導出上圖除紅鎖標記的私有類外的其他適配器都可以給ListView用。下面來看比較常用的四種適配器:ArrayAdapter、SimpleAdapter、SimpleCursorAdapter以及自定義BaseAdapter。
ArrayAdapter(數組適配器)
用於綁定格式單一的數據,數據源可以是集合或數組。
布局文件:
MainActivity.java 如下:
package com.example.listview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;
public class MainActivity extends AppCompatActivity {
private ListView mListView;
private ArrayAdapter arrayAdapter;
private String[] data = new String[]{"熊大", "熊二", "跳跳","熊大", "熊二", "跳跳",
"熊大", "熊二", "跳跳","熊大", "熊二", "跳跳"};//數據源
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.listView);
//1.新建數據適配器 2.添加數據源到適配器
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, data);
//3.視圖加載適配器
mListView.setAdapter(arrayAdapter);
}
}
運行效果如下:
到這裡對ArrayAdapter的一個簡單示例就完成了,那對ArrayAdapter的學習到這就可以結束了嗎?可以跳到SimpleAdapter的學習了嗎?本來是這麼打算的,畢竟最常用的是自定義BaseAdapter數據適配器,ArrayAdapter了解一下就可以了啦。可是…可是我看到了這個:
記得面試官問我缺點的時候我說我的缺點是不求甚解的反面,導致學習進度很慢…BaseAdapter萬能適配器什麼鬼的你們在後邊等著我吧…我們接著來看ArrayAdapter……
上面示例新建數據適配器的方式是上圖中的第三種創建方式,要掌握其他創建方式,先要了解參數含義:
context : 當前上下文
resource : item的布局文件
textViewResourceId : item布局文件中的TextView的ID (可不指定)
objects : 數據源 (可不指定)
如果參數resource設置為只含有一個TextView控件(可為TextView衍生出的控件如CheckedTextView)的布局文件,則可不指定textViewResourceId參數,比如上面示例中的android.R.layout.simple_list_item_1就是一個TextView,Item內容直接顯示在resource布局中,也就是TextView中。
如果參數resource沒有設置成僅含有一個TextView的布局文件,則必須在這個布局文件中包含一個TextView,且必須設置參數textViewResourceId指定其中的TextView的ID。此時Item就不再只是單調的TextView布局,而可以在resource指定的布局文件中自定義。但數據只能顯示在其中的TextView中,示例如下:
Item布局文件:
新建適配器代碼修改為下:
arrayAdapter = new ArrayAdapter(this, R.layout.item,R.id.textView,data);
運行效果:
看來一開始對ArrayAdapter的定義還是挺准確的:用於綁定格式單一的數據,數據源可以是集合或數組。格式單一的是數據,布局可以自己定義,但是數據只能在一個TextView上顯示。這種也可以記作樣式豐富但內容簡單的,而第一個示例可以記作樣式和內容都簡單的。如果我們需要展示的內容是僅一個textview承載不了的,還需要其它組件,怎麼辦?那麼有沒有一個方法可以實現樣式和內容都是豐富的呢?有,但是原生的ArrayAdapter無法實現這個功能,需要自定義一個ArrayAdapter類並重寫getView()方法才能實現。
豐富的內容通過User類來實現:
package com.example.listview;
/**
* Created by yinghao on 2016/6/10.
*/
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
豐富的布局通過自定義item布局文件來實現:
將豐富的內容顯示在豐富的控件上通過自定義ArrayAdapter類來實現:
package com.example.listview;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* Created by yinghao on 2016/6/10.
*/
public class MyArrayAdapter extends ArrayAdapter {
private int resourceId;
public MyArrayAdapter(Context context, int resource, User[] objects) {
super(context, resource, objects);
this.resourceId = resource;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
User user = getItem(position);
LinearLayout userListItem = new LinearLayout(getContext());
String inflater = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater vi = (LayoutInflater)getContext().getSystemService(inflater);
vi.inflate(resourceId, userListItem, true);
TextView name = (TextView) userListItem.findViewById(R.id.tv_name);
TextView age = (TextView) userListItem.findViewById(R.id.tv_age);
name.setText(user.getName());
age.setText(String.valueOf(user.getAge()));
return userListItem;
}
}
MainActivity.java 文件代碼如下:
package com.example.listview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
private ListView mListView;
private User[] users = new User[10];//數據源
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//准備數據源
for (int i = 0;i<10;i++) {
User user = new User("name"+i,15+i);
users[i] = user;
}
mListView = (ListView) findViewById(R.id.listView);
//1.新建數據適配器 // 2.添加數據源到適配器
MyArrayAdapter arrayAdapter = new MyArrayAdapter(this, R.layout.item, users);
//3.視圖加載適配器
mListView.setAdapter(arrayAdapter);
}
}
顯示結果如下:
總結:以上學習了ListView與listAdapter適配器的概念及其關系,然後演繹了ArrayAdapter的三種實現方式,分別是樣式和內容都是簡單的、樣式豐富但內容簡單的、樣式和內容都豐富的三種。其中前兩種用原生的ArrayAdapter就可以實現,通過對原生ArrayAdapter幾種構造方法的研究得出了數據只能顯示在TextView上的結論;第三種方式需要自己重寫getView()方法,在一定程度上也可以算作自定義Adapter。另外對於綁定的數據可以為格式單一的泛型的數組或集合,上面涉及到的為String數組和User數組,也可以為List集合。
關於ArrayAdapter先學到這,接下來學習SimpleAdapter、SimpleCursorAdapter以及自定義BaseAdapter…
在Android開發中;Activity之間傳遞參數是常見的事;如果我們要在Activity之間傳遞圖片;1。MainActivity中包括一個ImageView;當我們
android Notification實例詳解1.使用Builder模式來創建2.必須要設置一個smallIcon,還可以設置setTicker3.可以設置 setCo
什麼是ServiceService是Android 的四大組件之一,主要處理一些耗時的後台操作邏輯,或者輪詢操作等需要長期在後台運行的任務。甚至在程序退出之後,可以讓Se
上篇文章介紹了Android開發的設計理念的一部分,並沒有得到博友們的多大認可,只看到了一位博友在下面留言期待下一篇文章的發表,為了這小小的唯一支持,我決定繼續把後面的8