ListView:
ListView继承自AbsListView, AbsListView里面有一个RecycleBin的内部类.二 .RecycleBin里面重要的几个方法:
/\*\*
\* Puts a view into the list of scrap views.
\* <p>
\* If the list data hasn't changed or the adapter has stable IDs, views
\* with transient state will be preserved for later retrieval.
\*
\* @param scrap The view to add
\* @param position The view's position within its parent
\*/
void addScrapView\(View scrap, int position\) {//scrap是刚刚滑出屏幕的view.
final AbsListView.LayoutParams lp = \(AbsListView.LayoutParams\) scrap.getLayoutParams\(\);
if \(lp == null\) {
// Can't recycle, but we don't know anything about the view.
// Ignore it completely.
return;
}
lp.scrappedFromPosition = position;
// Remove but don't scrap header or footer views, or views that
// should otherwise not be recycled.
final int viewType = lp.viewType;
if \(!shouldRecycleViewType\(viewType\)\) {
// Can't recycle. If it's not a header or footer, which have
// special handling and should be ignored, then skip the scrap
// heap and we'll fully detach the view later.
if \(viewType != ITEM\_VIEW\_TYPE\_HEADER\_OR\_FOOTER\) {
getSkippedScrap\(\).add\(scrap\);
}
return;
}
scrap.dispatchStartTemporaryDetach\(\);
// The the accessibility state of the view may change while temporary
// detached and we do not allow detached views to fire accessibility
// events. So we are announcing that the subtree changed giving a chance
// to clients holding on to a view in this subtree to refresh it.
notifyViewAccessibilityStateChangedIfNeeded\(
AccessibilityEvent.CONTENT\_CHANGE\_TYPE\_SUBTREE\);
// Don't scrap views that have transient state.
final boolean scrapHasTransientState = scrap.hasTransientState\(\);
if \(scrapHasTransientState\) {
if \(mAdapter != null && mAdapterHasStableIds\) {
// If the adapter has stable IDs, we can reuse the view for
// the same data.
if \(mTransientStateViewsById == null\) {
mTransientStateViewsById = new LongSparseArray<>\(\);
}
mTransientStateViewsById.put\(lp.itemId, scrap\);
} else if \(!mDataChanged\) {
// If the data hasn't changed, we can reuse the views at
// their old positions.
if \(mTransientStateViews == null\) {
mTransientStateViews = new SparseArray<>\(\);
}
mTransientStateViews.put\(position, scrap\);
} else {
// Otherwise, we'll have to remove the view and start over.
getSkippedScrap\(\).add\(scrap\);
}
} else {
if \(mViewTypeCount == 1\) {
mCurrentScrap.add\(scrap\);
} else {
mScrapViews\[viewType\].add\(scrap\);
}
if \(mRecyclerListener != null\) {
mRecyclerListener.onMovedToScrapHeap\(scrap\);
}
}
}
三 .RecycleBin机制
四 . ListView的优化:
- Adapter里面的 getView()方法是convertview参数的利用.
- ViewHolder的利用减少findViewById
在getView少做耗时的操作.
class ViewHolder { public ImageView img; public TextView title; public TextView info; } @Override public View getView\(int position, View convertView, ViewGroup parent\) { ViewHolder holder; if \(convertView == null\) { holder = new ViewHolder\(\); convertView = LayoutInflater.from\(MainActivity.this\).inflate\(R.layout.list\_item, null\); holder.img = \(ImageView\) convertView.findViewById\(R.id.img\); holder.title = \(TextView\) convertView.findViewById\(R.id.title\); holder.info = \(TextView\) convertView.findViewById\(R.id.info\); convertView.setTag\(holder\); } else { holder = \(ViewHolder\) convertView.getTag\(\); } holder.title.setText\("Hello"\); holder.info.setText\("World"\); return convertView; }