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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

安卓APP_ 控件(10)—— ListView可上下滑动的列表(重要)与ViewHolder优化

發布時間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 安卓APP_ 控件(10)—— ListView可上下滑动的列表(重要)与ViewHolder优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

摘自:安卓APP_ 控件(10)—— ListView可上下滑動的列表(重要)與ViewHolder優化
作者:丶PURSUING
發布時間: 2021-04-12 23:28:27
網址:https://blog.csdn.net/weixin_44742824/article/details/115618378

目錄

  • 項目運行效果
  • (1)創建ListView
  • (2)創建新的item布局
  • (3)創建 javaBean
  • (4)創建數據中間橋梁:Adapter
  • (5)listView的點擊效果
  • 更多細節在代碼中體現
  • 重點:優化getView中需要多次調用的 `findViewById`
  • 知識掃盲
    • (1)什么是ViewHolder
    • (2)什么是setTag
    • (3)什么是javaBean

項目運行效果

ListView實現效果一睹為快

可以進行上下的滑動,也可以對每一個條目進行點擊,每個條目稱為ListView的item。

(1)創建ListView

在activity_main.xml下創建ListView,默認顯示效果如下:
當然,還要對每一個item填充數據,并且每一個item實際上就是一種布局,所以要給item進行布局。

(2)創建新的item布局

根據項目需求進行設置,這里僅用TestView做簡單的演示。

(3)創建 javaBean

設置完以上兩個布局后,就要設置數據。ListView數據都是從網上獲取的,在item下可能會有好幾個數據,所以一般會去創建一個java的Bean類。

使用代碼生成器,生成name的設置方法與獲取方法
(快捷鍵為alt+Insert)

(4)創建數據中間橋梁:Adapter

用for循環模擬從網上獲取的數據,數據如何填充listview這個對象呢?有個輔助類:Adapter

Adapter(適配器)
Adapter是用來幫助填出數據的中間橋梁,簡單點說就是將各種數據以合適的形式顯示在View中給用戶看。

在MainActivity.java中調用了Adapter,如下:

而Adapter的實現細節還要看下文的“更多細節在代碼中體現”。

(5)listView的點擊效果

實際上listView給我們提供有監聽事件:

效果如下圖

更多細節在代碼中體現

Mainactivity.java

public class MainActivity extends AppCompatActivity {private List<Bean> data = new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);for(int i = 0;i< 100;i++){Bean bean = new Bean();bean.setName("zhua"+i);data.add(bean);}//拿到listview的對象ListView listview = findViewById(R.id.lv);//數據如何填充這個對象呢?把數據放到Adapter里面去listview.setAdapter(new myAdapter(data,this));//listview的監聽事件listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Override//方法重寫,點擊后打印positionpublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {Log.e("zhua", "onItemClick: "+position );}});} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><ListViewandroid:id="@+id/lv"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

myAdapter.java

//繼承BaseAdapter后實現其方法 public class myAdapter extends BaseAdapter {private List<Bean> data;private Context context;//存放數據,以及把context放進去的構造方法public myAdapter(List<Bean> data, Context context){this.data = data;this.context = context;}@Override//返回listview能夠顯示多少數據:data有多少顯示多少public int getCount() {return data.size();}@Override//獲取itempublic Object getItem(int position) {return null;}@Override//獲取itemidpublic long getItemId(int position) {return position;}@Override//返回每一個item條目并給它進行一個設值后返回到界面上。//每次在顯示的時候,都會調用getview給每一個item進行賦值public View getView(int position, View convertView, ViewGroup parent) {//因為item是可以復用的,上下滑動界面時會不斷地進行判斷,為了防止convertView不斷創建,要進行判斷if(convertView == null){//先拿到item條目的布局 渲染layout.list_item,渲染后給到convertViewconvertView = LayoutInflater.from(context).inflate(R.layout.list_item,parent,false);}//需要把data創建的那些值,傳到textView每一個item上面(這個值在項目中是從網上獲取的)TextView textView = convertView.findViewById(R.id.tv);//getView并不是只會調用一次,而是界面每顯示一個item的時候都會創建一次textView.setText(data.get(position).getName());//這樣就把name設置到了textview上面Log.e("zhua", "getView: "+position);return convertView;}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

Bean.java

public class Bean {String name;public String getName() {return name;}public void setName(String name) {this.name = name;} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

list_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:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:id="@+id/tv"android:textSize="30sp"android:layout_width="wrap_content"android:layout_height="wrap_content"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

重點:優化getView中需要多次調用的 findViewById

但是上面的使用方法,并不是ListView的最優解,因為在myAdapter.java中,每次調用getView都會間接調用方法findViewByld,這非常耗時,效率不高。

優化后的myAdapter.java:每次在getView調用的時候就節省了findViewByld的調用時間。

//繼承BaseAdapter后實現其方法 public class myAdapter extends BaseAdapter {private List<Bean> data;private Context context;//存放數據,以及把context放進去的構造方法public myAdapter(List<Bean> data, Context context){this.data = data;this.context = context;}@Override//返回listview能夠顯示多少數據:data有多少顯示多少public int getCount() {return data.size();}@Override//獲取itempublic Object getItem(int position) {return null;}@Override//獲取itemidpublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {//(2)創建viewHolder對象ViewHolder viewHolder;//當convertView為null的時候(首次進入)進行如下設置if(convertView == null){//(3)實例化這個對象viewHolder = new ViewHolder();convertView = LayoutInflater.from(context).inflate(R.layout.list_item,parent,false);//(4)讓它去獲取findViewById:把TextView放到ViewHolder里面viewHolder.textView = convertView.findViewById(R.id.tv);//(5)再通過setTag把viewHolder放到convertView里面去convertView.setTag(viewHolder);}else{//(6)不是第一次進來不需要進行上面的設置,直接:viewHolder = (ViewHolder) convertView.getTag();//使viewHolder.textView與R.id.tv進行了“綁定”}//(7)再使用textView的時候呢就要通過viewHolderviewHolder.textView.setText(data.get(position).getName());//這樣就把name設置到了textview上面Log.e("zhua", "getView: "+position);return convertView;}//(1)創建ViewHolder類private final class ViewHolder{TextView textView;//在item布局中有幾個子控件就填充幾個} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

其他補充:

知識掃盲

(1)什么是ViewHolder

ViewHolder通常出現在適配器里,為的是listview滾動的時候快速設置值,而不必每次都重新創建很多對象,從而提升性能。

在android開發中Listview是一個很重要的組件,它以列表的形式根據數據的長自適應展示具體內容,用戶可以自由的定義listview每一列的布局,但當listview有大量的數據需要加載的時候,會占據大量內存,影響性能,這時候就需要按需填充并重新使用view來減少對象的創建。

ListView加載數據都是在public View getView(int position, View convertView, ViewGroup parent) {}方法中進行的(要自定義listview都需要重寫listadapter:如BaseAdapter,SimpleAdapter,CursorAdapter的等的getvView方法)。

優化listview的加載速度就要讓convertView匹配列表類型,并最大程度上的重新使用convertView。 getview的最慢的加載方式是每一次都重新定義一個View載入布局,再加載數據。而最快的方式是定義一個ViewHolder,將convetView的tag設置為ViewHolder,不為null時重新使用即可。

(2)什么是setTag

我們使用View,大多數情況就是為了向用戶展示一定的數據,因此,view的使用又總是離不開數據的。基本很多人的做法都會把數據以及view分開,但是其實在Android開發的view中已經有api接口可以完成一定量數據的存儲了,這就是——View.setTag()以及View.getTag()

功力不夠,應用場景暫時看不懂,先掛著:Android View中setTag的二三事

(3)什么是javaBean

Java語言欠缺屬性、事件、多重繼承功能。所以,如果要在Java程序中實現一些面向對象編程的常見需求,只能手寫大量膠水代碼。Java Bean正是編寫這套膠水代碼的慣用模式或約定。

舉例詳解

總結

以上是生活随笔為你收集整理的安卓APP_ 控件(10)—— ListView可上下滑动的列表(重要)与ViewHolder优化的全部內容,希望文章能夠幫你解決所遇到的問題。

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