ListView:ListView是一個能夠?qū)?shù)據(jù)集合以動態(tài)滾動的方式展示到用戶界面上的View梦染。
1. ListView的適配器模式
說明:ListView的適配器模式將
數(shù)據(jù)
資源和視圖
分離,通過適配器
來連接兩者灯谣,屬于MVC
模式。
2. ListView的垃圾回收機制RecycleBin
說明:適配器的getCount()方法用來計算數(shù)據(jù)資源的長度卷胯,有n條數(shù)據(jù)就會調(diào)用n次getView()方法來繪制Item摊趾,當(dāng)數(shù)據(jù)長度很多時,ListView的recycleBin機制(內(nèi)存回收機制)保證滑動時不會發(fā)生OOM(內(nèi)存泄漏)藤肢。
如:一旦Item0劃出屏幕,則Item0就會被放到RecycleBin機制里糯景,在Item6要顯示的時候再從緩存中獲取到緩存的Item0治拿,達到復(fù)用的目的暇榴。
recycleBin機制保證了僅界面內(nèi)顯示的數(shù)據(jù)會存儲在內(nèi)存止吐,故列表滑動時不會造成內(nèi)存泄漏
超凳。
3. ListView的優(yōu)化
(1) convertView復(fù)用和viewHolder
//繪制ListView的每個Item
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null){
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(ListViewTestActivity.this).inflate(R.layout.item_listview,null);
viewHolder.title = convertView.findViewById(R.id.title);
viewHolder.content= convertView.findViewById(R.id.content);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder)convertView.getTag();
}
viewHolder.title.setText("標題");
viewHolder.info.setText("內(nèi)容");
return convertView;
}
class ViewHolder{
private TextView title;
private TextView content;
}
convertView是ListView優(yōu)化最重要的一點
:convertView其實是緩存的作用。利用緩存convertView來做判斷怠惶,當(dāng)緩存中convertView為空時才創(chuàng)建相應(yīng)的View涨缚,存在則調(diào)用已有的View,從而提升了性能策治。
自定義viewHolder
:View是一個二叉樹的結(jié)構(gòu)脓魏,每次遍歷都很耗時,利用viewHolder可以減少每次findViewById()的調(diào)用次數(shù)通惫,從而在時間上進行優(yōu)化茂翔。
(2) 三級緩存和監(jiān)聽滑動事件
三級緩存
:圖片加載時需要用到緩存機制來進行。
監(jiān)聽滑動事件
:盡量不要在getView()中做耗時操作履腋,保證ListView滑動的流暢性珊燎,避免滑動時卡頓。如果一定要在ListView滑動時加載,可以設(shè)置ListView的監(jiān)聽事件俐末,當(dāng)滑動停止時再去加載整個圖片。
(3) 其他
- ListView的Item布局中盡量避免半透明的元素:半透明的繪制比不透明更耗時
- 可以開啟硬件加速
4. ListView使用
(1) ListViewTestActivity.java
package comi.example.liy.mytestdemo;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Created by liy on 2019-11-08 15:38
*/
public class ListViewTestActivity extends AppCompatActivity {
private ListView listView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listview);
listView = findViewById(R.id.listview);
listView.setAdapter(new MyAdapter(this));
}
class MyAdapter extends BaseAdapter{
private Context context;
private ArrayList<NewsInfo> newsInfos = new ArrayList<>();
public MyAdapter(Context context) {
this.context = context;
newsInfos = new NewsInfo().getNewsInfos();
}
//計算數(shù)據(jù)資源的長度:有n條數(shù)據(jù)就會調(diào)用n次getView()方法來繪制Item奄侠,當(dāng)數(shù)據(jù)長度很多時卓箫,ListView的recycleBin機制(內(nèi)存回收機制)保證滑動時不會發(fā)生OOM(內(nèi)存泄漏)
@Override
public int getCount() {
if (newsInfos == null){
return 0;
}
return newsInfos.size();
}
@Override
public Object getItem(int position) {
return newsInfos.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
//繪制ListView的每個Item
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null){
convertView = LayoutInflater.from(ListViewTestActivity.this).inflate(R.layout.item_listview,null);
viewHolder = new ViewHolder();
viewHolder.title = convertView.findViewById(R.id.title);
viewHolder.content = convertView.findViewById(R.id.content);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder)convertView.getTag();
}
viewHolder.title.setText(newsInfos.get(position).getTitle());
viewHolder.content.setText(newsInfos.get(position).getContent());
return convertView;
}
class ViewHolder{
private TextView title;
private TextView content;
}
}
}
(2) NewsInfo.java
package comi.example.liy.mytestdemo;
import java.util.ArrayList;
/**
* Created by liy on 2019-11-08 15:54
*/
public class NewsInfo {
private String title;
private String content;
public NewsInfo() {
}
public NewsInfo(String title, String content) {
this.title = title;
this.content= content;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
//創(chuàng)建測試數(shù)據(jù)
public ArrayList<NewsInfo> getNewsInfos(){
ArrayList<NewsInfo> newsInfos = new ArrayList<>();
newsInfos.add(new NewsInfo("標題1","信息內(nèi)容1"));
newsInfos.add(new NewsInfo("標題2","信息內(nèi)容2"));
newsInfos.add(new NewsInfo("標題3","信息內(nèi)容3"));
newsInfos.add(new NewsInfo("標題4","信息內(nèi)容4"));
newsInfos.add(new NewsInfo("標題5","信息內(nèi)容5"));
newsInfos.add(new NewsInfo("標題6","信息內(nèi)容6"));
newsInfos.add(new NewsInfo("標題7","信息內(nèi)容7"));
newsInfos.add(new NewsInfo("標題8","信息內(nèi)容8"));
newsInfos.add(new NewsInfo("標題9","信息內(nèi)容9"));
newsInfos.add(new NewsInfo("標題10","信息內(nèi)容10"));
return newsInfos;
}
}
(3) activity_listview.xml
<?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/listview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
(4) item_listview.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="match_parent">
<android.support.v7.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/title"
android:textSize="20sp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/content"
android:textSize="16sp"/>
</android.support.v7.widget.LinearLayoutCompat>
</LinearLayout>
(5) 運行效果