Merge changes I6e3f4da2,I8acfbd1a into nyc-dev
* changes: Fully detach unused scrap views Remove detached headers
This commit is contained in:
@@ -2322,7 +2322,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
*
|
*
|
||||||
* @param position The position to display
|
* @param position The position to display
|
||||||
* @param isScrap Array of at least 1 boolean, the first entry will become true if
|
* @param isScrap Array of at least 1 boolean, the first entry will become true if
|
||||||
* the returned view was taken from the scrap heap, false if otherwise.
|
* the returned view was taken from the "temporary detached" scrap heap, false if
|
||||||
|
* otherwise.
|
||||||
*
|
*
|
||||||
* @return A view displaying the data associated with the specified position
|
* @return A view displaying the data associated with the specified position
|
||||||
*/
|
*/
|
||||||
@@ -2362,10 +2363,18 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
// Failed to re-bind the data, return scrap to the heap.
|
// Failed to re-bind the data, return scrap to the heap.
|
||||||
mRecycler.addScrapView(scrapView, position);
|
mRecycler.addScrapView(scrapView, position);
|
||||||
} else {
|
} else {
|
||||||
|
if (child.isTemporarilyDetached()) {
|
||||||
isScrap[0] = true;
|
isScrap[0] = true;
|
||||||
|
|
||||||
// Finish the temporary detach started in addScrapView().
|
// Finish the temporary detach started in addScrapView().
|
||||||
child.dispatchFinishTemporaryDetach();
|
child.dispatchFinishTemporaryDetach();
|
||||||
|
} else {
|
||||||
|
// we set isScrap to "true" only if the view is temporarily detached.
|
||||||
|
// if the view is fully detached, it is as good as a view created by the
|
||||||
|
// adapter
|
||||||
|
isScrap[0] = false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5152,6 +5161,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
fillGap(down);
|
fillGap(down);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mRecycler.fullyDetachScrapViews();
|
||||||
if (!inTouchMode && mSelectedPosition != INVALID_POSITION) {
|
if (!inTouchMode && mSelectedPosition != INVALID_POSITION) {
|
||||||
final int childIndex = mSelectedPosition - mFirstPosition;
|
final int childIndex = mSelectedPosition - mFirstPosition;
|
||||||
if (childIndex >= 0 && childIndex < getChildCount()) {
|
if (childIndex >= 0 && childIndex < getChildCount()) {
|
||||||
@@ -6861,8 +6871,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
scrapViews = mScrapViews[whichScrap];
|
scrapViews = mScrapViews[whichScrap];
|
||||||
}
|
}
|
||||||
|
|
||||||
victim.dispatchStartTemporaryDetach();
|
|
||||||
lp.scrappedFromPosition = mFirstActivePosition + i;
|
lp.scrappedFromPosition = mFirstActivePosition + i;
|
||||||
|
removeDetachedView(victim, false);
|
||||||
scrapViews.add(victim);
|
scrapViews.add(victim);
|
||||||
|
|
||||||
if (hasListener) {
|
if (hasListener) {
|
||||||
@@ -6871,10 +6881,28 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pruneScrapViews();
|
pruneScrapViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* At the end of a layout pass, all temp detached views should either be re-attached or
|
||||||
|
* completely detached. This method ensures that any remaining view in the scrap list is
|
||||||
|
* fully detached.
|
||||||
|
*/
|
||||||
|
void fullyDetachScrapViews() {
|
||||||
|
final int viewTypeCount = mViewTypeCount;
|
||||||
|
final ArrayList<View>[] scrapViews = mScrapViews;
|
||||||
|
for (int i = 0; i < viewTypeCount; ++i) {
|
||||||
|
final ArrayList<View> scrapPile = scrapViews[i];
|
||||||
|
for (int j = scrapPile.size() - 1; j >= 0; j--) {
|
||||||
|
final View view = scrapPile.get(j);
|
||||||
|
if (view.isTemporarilyDetached()) {
|
||||||
|
removeDetachedView(view, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes sure that the size of mScrapViews does not exceed the size of
|
* Makes sure that the size of mScrapViews does not exceed the size of
|
||||||
* mActiveViews, which can happen if an adapter does not recycle its
|
* mActiveViews, which can happen if an adapter does not recycle its
|
||||||
@@ -6888,10 +6916,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
for (int i = 0; i < viewTypeCount; ++i) {
|
for (int i = 0; i < viewTypeCount; ++i) {
|
||||||
final ArrayList<View> scrapPile = scrapViews[i];
|
final ArrayList<View> scrapPile = scrapViews[i];
|
||||||
int size = scrapPile.size();
|
int size = scrapPile.size();
|
||||||
final int extras = size - maxViews;
|
while (size > maxViews) {
|
||||||
size--;
|
scrapPile.remove(--size);
|
||||||
for (int j = 0; j < extras; j++) {
|
|
||||||
removeDetachedView(scrapPile.remove(size--), false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import android.view.accessibility.AccessibilityNodeProvider;
|
|||||||
import android.widget.RemoteViews.RemoteView;
|
import android.widget.RemoteViews.RemoteView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Implementation Notes:
|
* Implementation Notes:
|
||||||
@@ -1763,6 +1764,10 @@ public class ListView extends AbsListView {
|
|||||||
// Flush any cached views that did not get reused above
|
// Flush any cached views that did not get reused above
|
||||||
recycleBin.scrapActiveViews();
|
recycleBin.scrapActiveViews();
|
||||||
|
|
||||||
|
// remove any header/footer that has been temp detached and not re-attached
|
||||||
|
removeUnusedFixedViews(mHeaderViewInfos);
|
||||||
|
removeUnusedFixedViews(mFooterViewInfos);
|
||||||
|
|
||||||
if (sel != null) {
|
if (sel != null) {
|
||||||
// The current selected item should get focus if items are
|
// The current selected item should get focus if items are
|
||||||
// focusable.
|
// focusable.
|
||||||
@@ -1879,6 +1884,36 @@ public class ListView extends AbsListView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean trackMotionScroll(int deltaY, int incrementalDeltaY) {
|
||||||
|
final boolean result = super.trackMotionScroll(deltaY, incrementalDeltaY);
|
||||||
|
removeUnusedFixedViews(mHeaderViewInfos);
|
||||||
|
removeUnusedFixedViews(mFooterViewInfos);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header and Footer views are not scrapped / recycled like other views but they are still
|
||||||
|
* detached from the ViewGroup. After a layout operation, call this method to remove such views.
|
||||||
|
*
|
||||||
|
* @param infoList The info list to be traversed
|
||||||
|
*/
|
||||||
|
private void removeUnusedFixedViews(@Nullable List<FixedViewInfo> infoList) {
|
||||||
|
if (infoList == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = infoList.size() - 1; i >= 0; i--) {
|
||||||
|
final FixedViewInfo fixedViewInfo = infoList.get(i);
|
||||||
|
final View view = fixedViewInfo.view;
|
||||||
|
final LayoutParams lp = (LayoutParams) view.getLayoutParams();
|
||||||
|
if (view.getParent() == null && lp != null && lp.recycledHeaderFooter) {
|
||||||
|
removeDetachedView(view, false);
|
||||||
|
lp.recycledHeaderFooter = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param child a direct child of this list.
|
* @param child a direct child of this list.
|
||||||
* @return Whether child is a header or footer view.
|
* @return Whether child is a header or footer view.
|
||||||
@@ -3179,6 +3214,9 @@ public class ListView extends AbsListView {
|
|||||||
last = getChildAt(--lastIndex);
|
last = getChildAt(--lastIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
recycleBin.fullyDetachScrapViews();
|
||||||
|
removeUnusedFixedViews(mHeaderViewInfos);
|
||||||
|
removeUnusedFixedViews(mFooterViewInfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
private View addViewAbove(View theView, int position) {
|
private View addViewAbove(View theView, int position) {
|
||||||
|
|||||||
Reference in New Issue
Block a user