日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android笔记(二十五) ListView的缓存机制与BaseAdapter

發布時間:2025/3/20 Android 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android笔记(二十五) ListView的缓存机制与BaseAdapter 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ?之前接觸了ListView和Adapter,Adapter將數據源和View連接起來,實際應用中,我們要顯示的數據往往有很多,而屏幕只有那么大,系統只能屏幕所能顯示的內容,當我們滑動屏幕,會將舊的內容放入到緩沖池中,再從緩存池中拿出新的內容顯示出來,這就是ListView的緩存機制,這一機制可以極大的節省系統資源。

BaseAdapter

?????? BaseAdapter通常用于被擴展,擴展BaseAdapter可以對各項列表進行最大限度的定制。

?????? 我們可以用自己的類去繼承BaseAdapter,然后實現getCount()、getItem()、getItemId()、getView()這四個方法,來完成對Adapter的定制。

?????? getCount()??? 該方法返回ListView需要顯示的數據量

?????? getItem()????? 該方法返回指定索引(position)所對應的數據項

?????? getItemId()? 該方法返回對應的索引

?????? getView()????? 該方法返回每一項所顯示的內容

簡單示例:

package cn.lixyz.baseadaptertest;import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.Toast;import java.util.ArrayList; import java.util.List;public class MainActivity extends AppCompatActivity {List<ItemBean> itemBeanList;ListView listView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);itemBeanList = new ArrayList<ItemBean>();for (int i = 0; i < 20; i++) {ItemBean ib = new ItemBean(R.drawable.icon, "標題" + i, "內容" + i);itemBeanList.add(ib);}listView = (ListView) findViewById(R.id.listView);listView.setAdapter(new MyAdapter(this, itemBeanList));listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {Toast.makeText(MainActivity.this, "你選擇的是:" + position, Toast.LENGTH_SHORT).show();}});} } MainActivity.java <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><ListViewandroid:id="@+id/listView"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout> layout_main.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_icon"android:layout_width="60dp"android:layout_height="60dp"android:layout_marginLeft="10dp"android:layout_marginTop="10dp"android:src="@drawable/icon" /><TextViewandroid:id="@+id/tv_name"android:layout_width="match_parent"android:layout_height="35dp"android:layout_marginTop="10dp"android:layout_toEndOf="@+id/iv_icon"android:gravity="center"android:text="標題"android:textSize="25dp" /><TextViewandroid:id="@+id/tv_desc"android:layout_width="match_parent"android:layout_height="25dp"android:layout_below="@+id/tv_name"android:layout_marginLeft="10dp"android:layout_toEndOf="@+id/iv_icon"android:gravity="center"android:text="內容內容內容內容" /></RelativeLayout> layout_item.xml package cn.lixyz.baseadaptertest;/*** Created by LGB on 2015/9/9.*/ public class ItemBean {public int ItemImageResid;public String ItemName;public String Itemdesc;public ItemBean(int ItemImageResid, String ItemName, String Itemdesc) {this.ItemImageResid = ItemImageResid;this.ItemName = ItemName;this.Itemdesc = Itemdesc;} } ItemBean.java package cn.lixyz.baseadaptertest;import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView;import java.util.List;/*** Created by LGB on 2015/9/9.*/ public class MyAdapter extends BaseAdapter {private List<ItemBean> list;private LayoutInflater inflater;public MyAdapter(Context context, List<ItemBean> list) {this.list = list;inflater = LayoutInflater.from(context);}//該方法返回ListView需要顯示的數據量 @Overridepublic int getCount() {return list.size();}//該方法返回指定索引(position)所對應的數據項 @Overridepublic Object getItem(int position) {return list.get(position);}//該方法返回對應的索引 @Overridepublic long getItemId(int position) {return 0;}// @Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view = inflater.inflate(R.layout.laytou_item, null);ImageView imageView = (ImageView) view.findViewById(R.id.iv_icon);TextView name = (TextView) view.findViewById(R.id.tv_name);TextView desc = (TextView) view.findViewById(R.id.tv_desc);imageView.setImageResource(list.get(position).ItemImageResid);name.setText(list.get(position).ItemName);desc.setText(list.get(position).Itemdesc);return view;} } MyAdapter.java

運行結果:

?

? ? ? ?上面的代碼中,我們可以看到一個ListView中的每一項都是我們直接使用Inflater新建并返回的,完全沒有使用到ListView提供的緩存機制

View view = inflater.inflate(R.layout.laytou_item, null); ...... return view;

? ? ? ?有關inflater的內容,可以看這里:<轉> Android LayoutInflater詳解? ? ??Android 中LayoutInflater的使用

?

? ? ? ?我們稍對代碼做一下修改:

package cn.lixyz.baseadaptertest;import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView;import java.util.List;/*** Created by LGB on 2015/9/9.*/ public class MyAdapter extends BaseAdapter {private List<ItemBean> list;private LayoutInflater inflater;public MyAdapter(Context context, List<ItemBean> list) {this.list = list;inflater = LayoutInflater.from(context);}//該方法返回ListView需要顯示的數據量 @Overridepublic int getCount() {return list.size();}//該方法返回指定索引(position)所對應的數據項 @Overridepublic Object getItem(int position) {return list.get(position);}//該方法返回對應的索引 @Overridepublic long getItemId(int position) {return 0;}//該方法返回每一項所顯示的內容 @Overridepublic View getView(int position, View convertView, ViewGroup parent) {if (convertView == null) {convertView = inflater.inflate(R.layout.laytou_item, null);}ImageView imageView = (ImageView) convertView.findViewById(R.id.iv_icon);TextView name = (TextView) convertView.findViewById(R.id.tv_name);TextView desc = (TextView) convertView.findViewById(R.id.tv_desc);imageView.setImageResource(list.get(position).ItemImageResid);name.setText(list.get(position).ItemName);desc.setText(list.get(position).Itemdesc);return convertView;} }

? ? ? ?我們先判斷要顯示的view是否已經存在,如果不存在,才創建,如果存在,就直接返回,這樣也就避免了多次重復創建。

? ? ? ? ?現在避免了多次創建View對象了,但是每次調用getView的時候,仍然會多次使用findViewById來創建組件,那么有沒有辦法可以避免在這個問題上面浪費資源呢,這里就使用到了view的getTag和setTag,通常我們會創建一個ViewHolder類然后實例化,然后通過setTag的方法將這個ViewHolder對象和View連接起來

???????? 看代碼:

package cn.lixyz.baseadaptertest;import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.Toast;import java.util.ArrayList; import java.util.List;public class MainActivity extends AppCompatActivity {List<ItemBean> itemBeanList;ListView listView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);itemBeanList = new ArrayList<ItemBean>();for (int i = 0; i < 20; i++) {ItemBean ib = new ItemBean(R.drawable.icon, "標題" + i, "內容" + i);itemBeanList.add(ib);}listView = (ListView) findViewById(R.id.listView);listView.setAdapter(new MyAdapter(this, itemBeanList));listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {Toast.makeText(MainActivity.this, "你選擇的是:" + position, Toast.LENGTH_SHORT).show();}});} } MainActivity.java <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><ListViewandroid:id="@+id/listView"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout> activity_main.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_icon"android:layout_width="60dp"android:layout_height="60dp"android:layout_marginLeft="10dp"android:layout_marginTop="10dp" /><TextViewandroid:id="@+id/tv_name"android:layout_width="match_parent"android:layout_height="35dp"android:layout_marginTop="10dp"android:layout_toEndOf="@+id/iv_icon"android:gravity="center"android:text="標題"android:textSize="25dp" /><TextViewandroid:id="@+id/tv_desc"android:layout_width="match_parent"android:layout_height="25dp"android:layout_below="@+id/tv_name"android:layout_marginLeft="10dp"android:layout_toEndOf="@+id/iv_icon"android:gravity="center"android:text="內容內容內容內容" /></RelativeLayout> layout_item.xml package cn.lixyz.baseadaptertest;/*** Created by LGB on 2015/9/9.*/ public class ItemBean {public int ItemImageResid;public String ItemName;public String Itemdesc;public ItemBean(int ItemImageResid, String ItemName, String Itemdesc) {this.ItemImageResid = ItemImageResid;this.ItemName = ItemName;this.Itemdesc = Itemdesc;} } ItemBean.java package cn.lixyz.baseadaptertest;import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView;import java.util.List;/*** Created by LGB on 2015/9/9.*/ public class MyAdapter extends BaseAdapter {private List<ItemBean> list;private LayoutInflater inflater;public MyAdapter(Context context, List<ItemBean> list) {this.list = list;inflater = LayoutInflater.from(context);}//該方法返回ListView需要顯示的數據量 @Overridepublic int getCount() {return list.size();}//該方法返回指定索引(position)所對應的數據項 @Overridepublic Object getItem(int position) {return list.get(position);}//該方法返回對應的索引 @Overridepublic long getItemId(int position) {return position;}//該方法返回每一項所顯示的內容 @Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder vh = null;if (convertView == null) {vh = new ViewHolder();convertView = inflater.inflate(R.layout.laytou_item, null);vh.imageView = (ImageView) convertView.findViewById(R.id.iv_icon);vh.name = (TextView) convertView.findViewById(R.id.tv_name);vh.desc = (TextView) convertView.findViewById(R.id.tv_desc);convertView.setTag(vh);} else {vh = (ViewHolder) convertView.getTag();}vh.imageView.setImageResource(list.get(position).ItemImageResid);vh.name.setText(list.get(position).ItemName);vh.desc.setText(list.get(position).Itemdesc);return convertView;}//創建ViewHolder,避免重復的findViewById操作浪費資源class ViewHolder {public ImageView imageView;public TextView name;public TextView desc;} } MyAdapter.java

? ? ? ? ?運行結果是一樣的

? ? ? ? ?在上面的代碼中,我們創建了一個ViewHolder對象,用來保存一個Item的內容,然后使用setTag()將View和ViewHolder對象連接起來,假如convertView不為空的話,直接使用getTag來獲取View對象,然后再給這個對象的屬性賦值(也就是給Item的組件賦值),這樣就充分利用了ListView的緩存機制,避免重復findViewById造成資源的浪費

? ? ? ? ?總結一下使用ListView緩存機制的思路

???????? 1)創建Bean對象,用戶封裝數據ItemBean

???????? 2)在構造方法中初始化用戶映射的數據List

???????? 3)創建ViewHolder類,創建布局映射關系

???????? 4)判斷convertView是否為空,如果為空,則創建,并設置tag,如果不為空,則通過getTag來去除ViewHolder

???????? 5)給ViewHolder中的控件設置數據

轉載于:https://www.cnblogs.com/xs104/p/4796423.html

總結

以上是生活随笔為你收集整理的Android笔记(二十五) ListView的缓存机制与BaseAdapter的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。