ListView的優化使用
一.ListView樣式
我們平時看到的評論類的消息類的一條一條的數據,一般來說都是ListView的樣式(雖然可能大部分都是RecycleView),但他們實現的樣式基本類似。本文以實現獲取所有系統應用的名稱和圖標爲例。
二.ListView的優化使用方法
(普通方法就不寫了)
2.1在佈局文件中:
直接寫入一個ListView,定義它的id.
<?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=".ApplistActivity">
<ListView
android:id="@+id/viewlist"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
這裏我們就有了這樣的一個樣式:
然後我們寫一個ListView中每一個Item的佈局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:id="@+id/appImage"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/appName"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center_vertical"
android:paddingLeft="6dp"
android:textSize="20dp"
android:text="@string/app_name"/>
</LinearLayout>
我們爲每一個Item設置了一張圖片和一段文字,樣式是這樣的:
這個就作爲了Item的樣式。
然後我們開始給ListView寫一個適配器,用來把你的資源和ListView的Item的佈局綁定起來。
public class AppListAdapter extends BaseAdapter
{
List<ResolveInfo> myAppInfos;
public AppListAdapter(List<ResolveInfo> appNames) {
this.myAppInfos =appNames;
}
@Override
public int getCount() {
//獲取數據總數
return myAppInfos.size();
}
@Override
public Object getItem(int position) {
//獲取當前position這條item
return myAppInfos.get(position);
}
@Override
public long getItemId(int position) {
//返回當前item的id
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
//填充數據的過程
ViewHolder viewHolder = new ViewHolder();
/*如果Item不存在*/
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.item_app_list_view, null);
viewHolder.mappImage= convertView.findViewById(R.id.appImage);
viewHolder.mappNames = convertView.findViewById(R.id.appName);
convertView.setTag(viewHolder);//保存ViewHolder
}
else
{
viewHolder= (ViewHolder) convertView.getTag();
}
viewHolder.mappNames.setText(myAppInfos.get(position).activityInfo.loadLabel(getPackageManager()));
viewHolder.mappImage.setImageDrawable(myAppInfos.get(position).activityInfo.loadIcon(getPackageManager()));
/*Item的點擊事件*/
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String packageName = myAppInfos.get(position).activityInfo.packageName;
String className = myAppInfos.get(position).activityInfo.name;
ComponentName componentName = new ComponentName(packageName, className);
final Intent intent = new Intent();
intent.setComponent(componentName);
startActivity(intent);
}
});
return convertView;
}
public class ViewHolder
{
public ImageView mappImage;
public TextView mappNames;
}
}
}
然後再Activity文件中,去加載ListView.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_applist);
ListView appListView = findViewById(R.id.viewlist);
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
//設置頂部圖片
View headView = inflater.inflate(R.layout.headview,null);
appListView.addHeaderView(headView);
appListView.setAdapter(new AppListAdapter(getAppInfos()));
}
// 獲取所有的用戶信息
private List<ResolveInfo> getAppInfos()
{
Intent intent = new Intent(Intent.ACTION_MAIN,null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
return getPackageManager().queryIntentActivities(intent,0);
}
如果要實現在ListView的最上邊,加載一張圖片,我們可以設置ListView的HeadView
<?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="60dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@drawable/digleet"/>
</LinearLayout>
最後實現的效果如下:
三.RecycleBin的原理
我們知道,ListView是繼承自AbsListView的。在AbsListView中,有一個內部類就是RecycleBin,在這個類中,有幾個變量值得我們注意
- private View[] mActiveView:這個數組記錄的當前處於屏幕上的view,可以被直接複用
- private ArrayList[] mScrapView:所有廢棄的view(已經被劃過)
- private ArrayList[] mCurrentScrap:當前被廢棄的view
同樣的,還有幾個重要的方法:
- setViewTypeCount():爲listview中的每種item設置RecycleBin機制
- fillActiveViews():將正在屏幕上顯示的item存儲到mActivityView這個數組中,及初始化或者更新這個數組
- getActiveView():獲取正在屏幕上顯示的item.值得注意的一點是,當我們獲取了這個view之後,存儲這個view的數組會將對應下標的位置的元素置爲空,即在此調用這個方法獲取想用下標的原色的時候會返回null。
- addScrapView():將已經廢棄的view存入到mScrapView數組中