Android最常用的控件ListView(详解)
一.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"><ListViewandroid: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;@Overrideprotected 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() {@Overridepublic 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"><ListViewandroid: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;@Overrideprotected 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@Overridepublic 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"><ImageViewandroid:id="@+id/fruit_image"android:src="@drawable/apple"android:layout_width="100dp"android:layout_height="80dp"/><TextViewandroid: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"/><TextViewandroid: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@Overridepublic 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() {@Overridepublic 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();}});六.總結
七.參考資料
? ? ? 點擊免費下載
總結
以上是生活随笔為你收集整理的Android最常用的控件ListView(详解)的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: linux的cpu信息怎么理解,理解Li
- 下一篇: java学习(42):巩固练习
