一.ListView簡介
在Android開發中,ListView是一個比較常用的控制元件,它以串列的形式 展示具體資料內容,并且能夠根據資料的長度自適應螢屏顯示,
二.ListView簡單用法
代碼部分
1.布局界面 activity_main.xml 代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
2.類檔案 MainActivity.java 代碼:
package com.example.listview1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
//1、定義物件
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//2、系結控制元件
listView=(ListView) findViewById(R.id.list_view);
//3、準備資料
String[] data={"菠蘿","芒果","石榴","葡萄", "蘋果", "橙子", "西瓜","菠蘿","芒果","石榴","葡萄", "蘋果", "橙子", "西瓜","菠蘿","芒果","石榴","葡萄", "蘋果", "橙子", "西瓜"};
//4、創建配接器 連接資料源和控制元件的橋梁
//引數 1:當前的背景關系環境
//引數 2:當前串列項所加載的布局檔案
//(android.R.layout.simple_list_item_1)這里的布局檔案是Android內置的,里面只有一個textview控制元件用來顯示簡單的文本內容
//引數 3:資料源
ArrayAdapter<String> adapter=new ArrayAdapter<>(MainActivity.this,android.R.layout.simple_list_item_1,data);
//5、將配接器加載到控制元件中
listView.setAdapter(adapter);
//6、為串列中選中的項添加單擊回應事件
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int i, long l) {
String result=((TextView)view).getText().toString();
Toast.makeText(MainActivity.this,"您選擇的水果是:"+result,Toast.LENGTH_LONG).show();
}
});
}
}
代碼決議
1.ArrayAdapter配接器
1、ArrayAdapter適用亍陣列或資料ArrayList(動態陣列),
2、ArrayAdapter可以通過泛型來指定要適配的資料型別,然后在構造凼數中把要適配的資料傳入,
3、ArrayAdapter有多個建構式的多載,可以根據實際情況選擇最合適的一種,
2.點擊事件回應
Parent: 指定哪個AdapterView(可能會有多個ListView,區分多個ListView)
View: 為你點擊的Listview的某一項的內容,來源于adapter,如用((TextView)view).getText().toString(),可以取出點擊的這一項的內容,轉為string 型別,
Position: 指的是adapter的某一項的位置,如點擊了listview第2項,而第2項對應 的是adapter的第2個數值,那此時position的值就為1了,注:這些數值都是從0開 始的,
Id:id的值為點擊了Listview的哪一項對應的數值,點擊了listview第2項,那id就等于1,一般和position相同,

三.定制 ListView 界面
只能顯示一段文本的listview太單調了,我們現在就來對listview的界面進行定制,讓其豐富內容,
代碼部分
1.布局界面 activity_main.xml 代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
2.類檔案 MainActivity.java 代碼:
package com.example.listview2;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
//第一步:定義物件
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//第二步:系結控制元件
listView = (ListView) findViewById(R.id.list_view);
//第三步:準備資料
List<Fruit> fruitlist = new ArrayList<>();
for (int i = 0; i <2 ; i++) {
Fruit pineapple=new Fruit(R.drawable.pineapple,"菠蘿","¥16.9 元/KG");
fruitlist.add(pineapple);
Fruit mango = new Fruit(R.drawable.mango, "芒果","¥29.9 元/kg");
fruitlist.add(mango);
Fruit pomegranate = new Fruit(R.drawable.pomegranate, "石榴","¥15元/kg");
fruitlist.add(pomegranate);
Fruit grape = new Fruit(R.drawable.grape, "葡萄","¥19.9 元/kg");
fruitlist.add(grape);
Fruit apple = new Fruit(R.drawable.apple, "蘋果","¥20 元/kg");
fruitlist.add(apple);
Fruit orange = new Fruit(R.drawable.orange, "橙子","¥18.8 元/kg");
fruitlist.add(orange);
Fruit watermelon = new Fruit(R.drawable.watermelon, "西瓜","¥28.8元/kg");
fruitlist.add(watermelon);
}
//第四步:設計每一個串列項的子布局
//第五步:定義配接器 控制元件 -橋梁-資料
FruitAdapter adapter=new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitlist);
listView.setAdapter(adapter);
}
}
3.類檔案 Fruit.java 代碼:
package com.example.listview2;
public class Fruit {
private int imageID;
private String name;
private String price;
public int getImageID() {
return imageID;
}
public String getName() {
return name;
}
public String getPrice() {
return price;
}
public Fruit(int imageID, String name, String price) {
this.imageID = imageID;
this.name = name;
this.price = price;
}
}
4.類檔案 FruitAdapter.java 代碼:
package com.example.listview2;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
//用于將背景關系、listview 子項布局的 id 和資料都傳遞過來
public class FruitAdapter extends ArrayAdapter<Fruit> {
public FruitAdapter(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {
super(context, resource, objects);
}
//每個子項被滾動到螢屏內的時候會被呼叫
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Fruit fruit=getItem(position);//得到當前項的 Fruit 實體
//為每一個子項加載設定的布局
View view=LayoutInflater.from(getContext()).inflate(R.layout.fruit_item,parent,false);
//分別獲取 image view 和 textview 的實體
ImageView fruitimage =view.findViewById(R.id.fruit_image);
TextView fruitname =view.findViewById(R.id.fruit_name);
TextView fruitprice=view.findViewById(R.id.fruit_price);
// 設定要顯示的圖片和文字
fruitimage.setImageResource(fruit.getImageID());
fruitname.setText(fruit.getName());
fruitprice.setText(fruit.getPrice());
return view;
}
}
5.布局界面 fruit_item.xml 代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/fruit_image"
android:src="@drawable/apple"
android:layout_width="100dp"
android:layout_height="80dp"/>
<TextView
android:id="@+id/fruit_name"
android:layout_gravity="center_vertical"
android:textSize="30sp"
android:textColor="#000000"
android:text="name"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/fruit_price"
android:layout_gravity="center_vertical"
android:textColor="#ff0000"
android:text="price"
android:textSize="30sp"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
代碼決議
1.引入動態陣列ArrayList
陣列的缺點
(1)陣列長度固定
(2)定義陣列只能指定一種資料型別
ArrayList:可以動態增加和縮減的索引序列,它是基于陣列實作的list類
List<Fruit> fruitlist = new ArrayList<>();
List泛型里面既包括圖片又包含文本,因此我們要定義一個Fruit類
2.Fruit類
public class Fruit {
private int imageID;
private String name;
private String price;
}
在里面添加圖片的id,名稱和價格
然后按下Alt+Insert鍵添加構造方法(Constructor)和Get方法(Getter)
3.自定義配接器 控制元件 -橋梁-資料
為什么要自定義配接器?
原因在于,當我們想用一些其他的展現方式,或者是本案例我們需要的圖文混排的呈現方式,這就需要DIY了,
1.我們定義一個自定義配接器 FruitAdapter繼承ArrayAdapter,
2.自定義配接器中常用的方法:getCount、getView、getItem、getItemId,
(1)創建好后需要添加泛型(也就是我們創建的Fruit類)
(2)按下鍵盤上的Alt+Enter鍵創建構造方法(倒數第二個list<T>)
(3)重寫getView方法
4.inflate()方法
inflate()方法的三個引數
inflate(R.layout.fruit_item,parent,false)
1、第一個引數是布局;(自己寫的)
2、第二個引數是父容器控制元件;
3、第三個布林值引數表明是否連接該布局和其父容器控制元件,在這里的情況設定 為false,因為系統已經插入了這個布局到父控制元件,設定為true將會產生多余的一 個View Group,
四.提升ListView的運行效率
目前我們ListView的運行效率是很低的,因為在FruitAdapter的 getView()方法中,每次都將布局重 新加載了一遍,將快速滾動的時候, 這將會成為性能的瓶頸,

getView()方法中的convertView引數,用于將之前加載好的布局進行快取,以便之 后可以進行重用,
優化方法一:

優化方法二:

代碼:
package com.example.listview3;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
//用于將背景關系、listview 子項布局的 id 和資料都傳遞過來
public class FruitAdapter extends ArrayAdapter<Fruit> {
public FruitAdapter(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {
super(context, resource, objects);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Fruit fruit=getItem(position);//獲取當前項的 Fruit 實體
View view;
//新增一個內部類 ViewHolder,用于對控制元件的實體進行快取
ViewHolder viewHolder;
if (convertView==null){
//為每一個子項加載設定的布局
view= LayoutInflater.from(getContext()).inflate(R.layout.fruit_item,parent,false);
viewHolder=new ViewHolder();
//分別獲取 imageview 和 textview 的實體
viewHolder.fruitimage =view.findViewById(R.id.fruit_image);
viewHolder.fruitname =view.findViewById(R.id.fruit_name);
viewHolder.fruitprice=view.findViewById(R.id.fruit_price);
view.setTag(viewHolder);//將 viewHolder 存盤在 view 中
}else {
view=convertView;
viewHolder= (ViewHolder) view.getTag();//重新獲取 viewHolder
}
// 設定要顯示的圖片和文字
viewHolder.fruitimage.setImageResource(fruit.getImageID());
viewHolder.fruitname.setText(fruit.getName());
viewHolder.fruitprice.setText(fruit.getPrice());
return view;
}
private class ViewHolder {
ImageView fruitimage;
TextView fruitname;
TextView fruitprice;
}
}
五.ListView的點擊事件
ListView的滾動畢竟只是滿足 了我們視覺上的效果,下面我們來學習ListView如何才能響 應用戶的點擊事件,
代碼:
//第六步:listview 的點擊事件
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Fruit fruit= fruitlist.get(position) ;
Toast.makeText(MainActivity.this,"您選擇的水果是:"+fruit.getName(),Toast.LENGTH_LONG).show();
}
});
六.總結

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/292981.html
標籤:其他

