由于手機屏幕空間有限,能夠一次性展現(xiàn)在屏幕上的內(nèi)容并不多后雷,當我們需要展現(xiàn)大量數(shù)據(jù)時邻眷,就可以通過ListView
來實現(xiàn)仗考。
ListView
允許用戶通過手指上下滑動的方式將屏幕外的數(shù)據(jù)滾動到屏幕內(nèi)鹅巍,同時屏幕上原有的數(shù)據(jù)則會滾動出屏幕千扶。
應用場景:QQ聊天記錄 料祠、 微博消息
ListView的簡單用法
簡單實現(xiàn)ListView
創(chuàng)建一個Activity,在其視圖中添加ListView
控件澎羞,并為其指定id
髓绽,長寬match_parent
。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/main_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
然后修改Activity中的代碼:
public class MainActivity extends AppCompatActivity {
private ListView mListview;
private String[] data = {"item1","item2","item3","item4","item5","item6","item7","item8",
"item9,","item10","item11","item12","item13","item14","item15"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 綁定視圖
mListview = (ListView) findViewById(R.id.main_2a'z'zlistview);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, data);
mListview.setAdapter(adapter);
}
}
效果如圖所示:
自定義ListView
在上一節(jié)中妆绞,我們每一行填充的View是系統(tǒng)自帶的資源android.R.layout.simple_list_item_1
顺呕,我們可以按住ctrl
加鼠標左鍵進入查看,內(nèi)容如下:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:minHeight="?android:attr/listPreferredItemHeightSmall" />
我們使用了系統(tǒng)提供的ArrayAdaper
作為ListView
的適配器摆碉,每行填充的視圖就是上面的TextView
。然后把名為data的String類型數(shù)組依此填充進去脓豪。
關于Adapter
ListView控件是為了交互和展示數(shù)據(jù)用的巷帝,ListView也只承擔交互和展示作用,而數(shù)據(jù)來自哪里和ListView無關扫夜。所以我們要使ListView起作用楞泼,我們需要一個ListView和一個數(shù)據(jù)源。
關鍵在于數(shù)據(jù)源笤闯,我們無法知道數(shù)據(jù)源是什么類型堕阔。它可能是數(shù)組,可能是對象集合颗味,還可能是數(shù)據(jù)庫表中查詢出來的游標超陆,如果ListView要為每一種數(shù)據(jù)源都進行適配操作的話,擴展性就會比較差浦马。
Adapter適配器时呀,它在ListView和數(shù)據(jù)源之間起到了一個橋梁的作用。ListView不直接和數(shù)據(jù)源打交道晶默,而是借助Adapter作為橋梁來訪問真正的數(shù)據(jù)源谨娜,
實際上我們可以自定義填充的View,我們也可以填充一個ViewGroup磺陡,例如:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/item_roadid"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="30sp"
android:gravity="center"/>
<TextView
android:id="@+id/item_redtime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="30sp"
android:gravity="center"/>
<TextView
android:id="@+id/item_greentime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="30sp"
android:gravity="center"/>
<TextView
android:id="@+id/item_yellowtime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="30sp"
android:gravity="center"/>
</LinearLayout>
這個ViewGroup由四個TextView組成趴梢。
在上節(jié)中我們直接使用了ArrayAdapter來作為適配器,ArrayAdapter繼承自BaseAdapter币他,默認情況下坞靶,我們可以使用它的構造方法引用單個TextView的布局作為item。但如果布局較復雜蝴悉,我們就需要加入TextView外層的布局的layout資源 滩愁,即下圖第四種用法。當TextView被引用之后辫封,將會被填充傳進來的數(shù)組對象的toString()
的值硝枉。
而我們需要更復雜的item廉丽,不僅僅是一個TextView,比如一個ImageView妻味,或者一個Checkbox正压,亦或是一個Button。ArrayAdapter通過getView()方法獲得每個item的View责球,所以我們需要重寫ArrayAdapter的getView()方法來返回我們自己需要的View焦履。我們通過繼承來完成重寫。
重寫ArrayAdapter
因為我們不再使用String數(shù)組作為數(shù)據(jù)源雏逾,而是以對象list的形式作為數(shù)據(jù)源嘉裤,所以我們先構建一個所需的對象。
我以交通燈為例栖博,這個對象包含roadId
,redTime
,greenTime
,yellowTime
四個屬性屑宠,然后創(chuàng)建了它的構造函數(shù)和一些getter/setter。
public class LightInfo {
private int roadId;
private int redTime;
private int greenTime;
private int yellowTime;
public LightInfo(int roadId, int redTime, int greenTime, int yellowTime) {
this.roadId = roadId;
this.redTime = redTime;
this.greenTime = greenTime;
this.yellowTime = yellowTime;
}
public int getRoadId() {
return roadId;
}
public void setRoadId(int roadId) {
this.roadId = roadId;
}
public int getRedTime() {
return redTime;
}
public void setRedTime(int redTime) {
this.redTime = redTime;
}
public int getGreenTime() {
return greenTime;
}
public void setGreenTime(int greenTime) {
this.greenTime = greenTime;
}
public int getYellowTime() {
return yellowTime;
}
public void setYellowTime(int yellowTime) {
this.yellowTime = yellowTime;
}
}
然后重寫適配器:
public class LightInfoAdapter extends ArrayAdapter<LightInfo> {
private ArrayList list = new ArrayList();;
public LightInfoAdapter(@NonNull Context context, int resource, @NonNull List<LightInfo> objects) {
super(context, resource, objects);
}
@NonNull
@Override
public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.item_light_info, parent, false);
LightInfo lightInfo = getItem(position);
TextView roadId = (TextView) view.findViewById(R.id.item_roadid);
TextView redTime = (TextView) view.findViewById(R.id.item_redtime);
TextView greenTime = (TextView) view.findViewById(R.id.item_greentime);
TextView yellowTime = (TextView) view.findViewById(R.id.item_yellowtime);
roadId.setText(lightInfo.getRoadId()+"");
redTime.setText(lightInfo.getRedTime()+"");
greenTime.setText(lightInfo.getGreenTime()+"");
yellowTime.setText(lightInfo.getYellowTime()+"");
return view;
}
修改Activity中的代碼
public class MainActivity extends AppCompatActivity {
private ListView mListview;
// 刪除
//private String[] data = {"item1","item2","item3","item4","item5","item6","item7","item8","item9,","item10","item11","item12","item13","item14","item15"};
// 添加
private List<LightInfo> lightInfos = new ArrayList<>();;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 綁定視圖
mListview = (ListView) findViewById(R.id.main_2a'z'zlistview);
// 刪除
//ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, data);
// 添加
initData();
LightInfoAdapter adapter = new LightInfoAdapter(this,R.layout.item_light_info,lightInfos);
mListview.setAdapter(adapter);
}
// 添加死數(shù)據(jù)
private void initData() {
for (int i=0;i<4;i++) {
lightInfos.add(new LightInfo(i,i,i,i));
}
}
}
效果如圖: