Skip to content
This repository was archived by the owner on Jul 14, 2021. It is now read-only.

Commit 1d94f2b

Browse files
committed
Merge branch 'develop'
# Conflicts: # examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java # vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java
2 parents 7e08f2e + 8216478 commit 1d94f2b

File tree

6 files changed

+231
-22
lines changed

6 files changed

+231
-22
lines changed

examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.alibaba.android.vlayout.VirtualLayoutManager;
3131
import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutParams;
3232
import com.alibaba.android.vlayout.extend.PerformanceMonitor;
33+
import com.alibaba.android.vlayout.extend.ViewLifeCycleListener;
3334
import com.alibaba.android.vlayout.layout.ColumnLayoutHelper;
3435
import com.alibaba.android.vlayout.layout.FixLayoutHelper;
3536
import com.alibaba.android.vlayout.layout.FloatLayoutHelper;
@@ -110,8 +111,8 @@ protected void onCreate(Bundle savedInstanceState) {
110111
super.onCreate(savedInstanceState);
111112
setContentView(R.layout.main_activity);
112113

113-
mSwipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swipe_container);
114-
;
114+
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
115+
;
115116
mFirstText = (TextView) findViewById(R.id.first);
116117
mLastText = (TextView) findViewById(R.id.last);
117118
mCountText = (TextView) findViewById(R.id.count);
@@ -151,8 +152,6 @@ public void onScrolled(RecyclerView recyclerView, int i, int i2) {
151152
}
152153
});
153154

154-
layoutManager.setRecycleOffset(300);
155-
156155
recyclerView.setLayoutManager(layoutManager);
157156

158157
// layoutManager.setReverseLayout(true);
@@ -173,6 +172,31 @@ public void getItemOffsets(Rect outRect, View view, RecyclerView parent, Recycle
173172

174173
viewPool.setMaxRecycledViews(0, 20);
175174

175+
layoutManager.setRecycleOffset(300);
176+
177+
// viewLifeCycleListener should be used with setRecycleOffset()
178+
layoutManager.setViewLifeCycleListener(new ViewLifeCycleListener() {
179+
@Override
180+
public void onAppearing(View view) {
181+
// Log.e("ViewLifeCycleTest", "onAppearing: " + view);
182+
}
183+
184+
@Override
185+
public void onDisappearing(View view) {
186+
// Log.e("ViewLifeCycleTest", "onDisappearing: " + view);
187+
}
188+
189+
@Override
190+
public void onAppeared(View view) {
191+
// Log.e("ViewLifeCycleTest", "onAppeared: " + view);
192+
}
193+
194+
@Override
195+
public void onDisappeared(View view) {
196+
// Log.e("ViewLifeCycleTest", "onDisappeared: " + view);
197+
}
198+
});
199+
176200
final DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager, true);
177201

178202
recyclerView.setAdapter(delegateAdapter);
@@ -280,7 +304,7 @@ public void onBindViewHolder(MainViewHolder holder, int position) {
280304
});
281305
}
282306

283-
{
307+
{
284308
RangeGridLayoutHelper layoutHelper = new RangeGridLayoutHelper(4);
285309
layoutHelper.setBgColor(Color.GREEN);
286310
layoutHelper.setWeights(new float[]{20f, 26.665f});
@@ -355,7 +379,7 @@ public void onBindViewHolder(MainViewHolder holder, int position) {
355379

356380
adapters.add(new SubAdapter(this, layoutHelper, 23));
357381
}
358-
382+
359383
{
360384
SingleLayoutHelper layoutHelper = new SingleLayoutHelper();
361385
layoutHelper.setBgColor(Color.BLUE);
@@ -632,7 +656,7 @@ public void onBindViewHolder(MainViewHolder holder, int position) {
632656
}
633657

634658
adapters.add(
635-
new FooterAdapter(recyclerView, VLayoutActivity.this, new GridLayoutHelper(1), 1));
659+
new FooterAdapter(recyclerView, VLayoutActivity.this, new GridLayoutHelper(1), 1));
636660

637661
delegateAdapter.setAdapters(adapters);
638662

@@ -642,8 +666,8 @@ public void onBindViewHolder(MainViewHolder holder, int position) {
642666
trigger = new Runnable() {
643667
@Override
644668
public void run() {
645-
//recyclerView.scrollToPosition(22);
646-
//recyclerView.getAdapter().notifyDataSetChanged();
669+
//recyclerView.scrollToPosition(22);
670+
//recyclerView.getAdapter().notifyDataSetChanged();
647671
//mainHandler.postDelayed(trigger, 1000);
648672
//List<DelegateAdapter.Adapter> newAdapters = new ArrayList<>();
649673
//newAdapters.add((new SubAdapter(VLayoutActivity.this, new ColumnLayoutHelper(), 3)));
@@ -674,7 +698,6 @@ public void onClick(View v) {
674698
});
675699

676700

677-
678701
mainHandler.postDelayed(trigger, 1000);
679702

680703
mSwipeRefreshLayout.setOnRefreshListener(new OnRefreshListener() {

vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class ExposeLinearLayoutManagerEx extends LinearLayoutManager {
129129

130130
private final Method mEnsureLayoutStateMethod;
131131

132-
private int recycleOffset;
132+
protected int recycleOffset;
133133

134134
/**
135135
* Creates a vertical LinearLayoutManager
@@ -1155,8 +1155,7 @@ protected int fill(RecyclerView.Recycler recycler, LayoutState layoutState,
11551155
}
11561156
recycleByLayoutStateExpose(recycler, layoutState);
11571157
}
1158-
int remainingSpace = layoutState.mAvailable + layoutState.mExtra + (
1159-
layoutState.mLayoutDirection == LayoutState.LAYOUT_START ? 0 : recycleOffset); //FIXME opt here to fix bg and shake
1158+
int remainingSpace = layoutState.mAvailable + layoutState.mExtra + recycleOffset;
11601159
while (remainingSpace > 0 && layoutState.hasMore(state)) {
11611160
layoutChunkResultCache.resetInternal();
11621161
layoutChunk(recycler, state, layoutState, layoutChunkResultCache);

vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,9 @@
2424

2525
package com.alibaba.android.vlayout;
2626

27-
import java.util.Collections;
28-
import java.util.Comparator;
29-
import java.util.HashMap;
30-
import java.util.Iterator;
31-
import java.util.LinkedList;
32-
import java.util.List;
33-
import java.util.Map;
34-
3527
import com.alibaba.android.vlayout.extend.PerformanceMonitor;
28+
import com.alibaba.android.vlayout.extend.ViewLifeCycleHelper;
29+
import com.alibaba.android.vlayout.extend.ViewLifeCycleListener;
3630
import com.alibaba.android.vlayout.layout.BaseLayoutHelper;
3731
import com.alibaba.android.vlayout.layout.DefaultLayoutHelper;
3832
import com.alibaba.android.vlayout.layout.FixAreaAdjuster;
@@ -53,6 +47,14 @@
5347
import android.view.ViewGroup;
5448
import android.view.ViewParent;
5549

50+
import java.util.Collections;
51+
import java.util.Comparator;
52+
import java.util.HashMap;
53+
import java.util.Iterator;
54+
import java.util.LinkedList;
55+
import java.util.List;
56+
import java.util.Map;
57+
5658

5759
/**
5860
* A {@link android.support.v7.widget.RecyclerView.LayoutManager} implementation which provides
@@ -103,6 +105,8 @@ public static void enableDebugging(boolean isDebug) {
103105

104106
private PerformanceMonitor mPerformanceMonitor;
105107

108+
private ViewLifeCycleHelper mViewLifeCycleHelper;
109+
106110
public VirtualLayoutManager(@NonNull final Context context) {
107111
this(context, VERTICAL);
108112
}
@@ -456,6 +460,10 @@ private void runPostLayout(RecyclerView.Recycler recycler, RecyclerView.State st
456460
}
457461
}
458462
}
463+
464+
if (null != mViewLifeCycleHelper) {
465+
mViewLifeCycleHelper.checkViewStatusInScreen();
466+
}
459467
}
460468
}
461469

@@ -625,6 +633,26 @@ public void offsetChildrenVertical(int dy) {
625633
LayoutHelper layoutHelper = layoutHelpers.get(i);
626634
layoutHelper.onOffsetChildrenVertical(dy, this);
627635
}
636+
637+
if (null != mViewLifeCycleHelper) {
638+
mViewLifeCycleHelper.checkViewStatusInScreen();
639+
}
640+
}
641+
642+
public void setViewLifeCycleListener(@NonNull ViewLifeCycleListener viewLifeCycleListener) {
643+
if (null == viewLifeCycleListener) {
644+
throw new IllegalArgumentException("ViewLifeCycleListener should not be null!");
645+
}
646+
647+
if (recycleOffset == 0) {
648+
throw new IllegalArgumentException("ViewLifeCycleListener should work with virtualLayoutManager.setRecycleOffset()!");
649+
}
650+
651+
mViewLifeCycleHelper = new ViewLifeCycleHelper(this, viewLifeCycleListener);
652+
}
653+
654+
public int getVirtualLayoutDirection() {
655+
return mLayoutState.mLayoutDirection;
628656
}
629657

630658
private LayoutStateWrapper mTempLayoutStateWrapper = new LayoutStateWrapper();
@@ -1438,7 +1466,7 @@ private void measureChildWithDecorationsAndMargin(View child, int widthSpec, int
14381466

14391467
if (getOrientation() == VERTICAL) {
14401468
widthSpec = updateSpecWithExtra(widthSpec, lp.leftMargin + mDecorInsets.left,
1441-
lp.rightMargin + mDecorInsets.right);
1469+
lp.rightMargin + mDecorInsets.right);
14421470
}
14431471
if (getOrientation() == HORIZONTAL) {
14441472
heightSpec = updateSpecWithExtra(heightSpec, mDecorInsets.top,
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package com.alibaba.android.vlayout.extend;
2+
3+
import android.support.annotation.NonNull;
4+
import android.support.v4.util.ArrayMap;
5+
import android.view.View;
6+
7+
import com.alibaba.android.vlayout.VirtualLayoutManager;
8+
9+
public class ViewLifeCycleHelper {
10+
public enum STATUS {
11+
APPEARING,
12+
APPEARED,
13+
DISAPPEARING,
14+
DISAPPEARED
15+
}
16+
17+
private ArrayMap<View, STATUS> mViewStatusMap = new ArrayMap<>();
18+
19+
private ViewLifeCycleListener mViewLifeCycleListener;
20+
21+
private VirtualLayoutManager mVirtualLayoutManager;
22+
23+
private int scrHeight;
24+
25+
public ViewLifeCycleHelper(VirtualLayoutManager virtualLayoutManager, @NonNull ViewLifeCycleListener mViewLifeCycleListener) {
26+
this.mViewLifeCycleListener = mViewLifeCycleListener;
27+
this.mVirtualLayoutManager = virtualLayoutManager;
28+
}
29+
30+
public void checkViewStatusInScreen() {
31+
for (int i = 0; i < mVirtualLayoutManager.getChildCount(); i++) {
32+
View view = mVirtualLayoutManager.getChildAt(i);
33+
if (scrHeight == 0) {
34+
scrHeight = view.getContext().getResources().getDisplayMetrics().heightPixels;
35+
}
36+
37+
if (mVirtualLayoutManager.getVirtualLayoutDirection() == VirtualLayoutManager.LayoutState.LAYOUT_END) {
38+
if (view.getTop() <= 0 && view.getBottom() >= 0 && isViewReadyDisAppearing(view)) {
39+
setViewDisappearing(view);
40+
} else if (view.getTop() <= scrHeight && view.getBottom() >= scrHeight && isViewReadyAppearing(view)) {
41+
setViewAppearing(view);
42+
}
43+
} else {
44+
if (view.getTop() <= 0 && view.getBottom() >= 0 && isViewReadyAppearing(view)) {
45+
setViewAppearing(view);
46+
} else if (view.getTop() <= scrHeight && view.getBottom() >= scrHeight && isViewReadyDisAppearing(view)) {
47+
setViewDisappearing(view);
48+
}
49+
}
50+
51+
if (view.getTop() >= 0 && view.getBottom() <= scrHeight) {
52+
// fully in screen
53+
54+
if (isViewReadyAppearing(view)) {
55+
setViewAppearing(view);
56+
57+
} else if (isViewReadyAppeared(view)) {
58+
setViewAppeared(view);
59+
}
60+
} else if (view.getBottom() <= 0 || view.getTop() >= scrHeight) {
61+
// not in screen
62+
if (isViewReadyDisAppearing(view)) {
63+
setViewDisappearing(view);
64+
65+
} else if (isViewReadyDisAppeared(view)) {
66+
setViewDisappeared(view);
67+
}
68+
69+
}
70+
}
71+
}
72+
73+
private STATUS getViewStatus(View view) {
74+
if (!mViewStatusMap.containsKey(view)) {
75+
mViewStatusMap.put(view, STATUS.DISAPPEARED);
76+
return STATUS.DISAPPEARED;
77+
}
78+
return mViewStatusMap.get(view);
79+
}
80+
81+
private void setViewstatus(View view, STATUS status) {
82+
mViewStatusMap.put(view, status);
83+
}
84+
85+
private boolean isViewReadyAppearing(View view) {
86+
return getViewStatus(view) == STATUS.DISAPPEARED;
87+
}
88+
89+
private void setViewAppearing(View view) {
90+
if (getViewStatus(view) == STATUS.APPEARING) {
91+
return;
92+
}
93+
94+
setViewstatus(view, STATUS.APPEARING);
95+
if (null != mViewLifeCycleListener) {
96+
mViewLifeCycleListener.onAppearing(view);
97+
}
98+
}
99+
100+
private boolean isViewReadyAppeared(View view) {
101+
return getViewStatus(view) == STATUS.APPEARING;
102+
}
103+
104+
private void setViewAppeared(View view) {
105+
if (getViewStatus(view) == STATUS.APPEARED) {
106+
return;
107+
}
108+
setViewstatus(view, STATUS.APPEARED);
109+
if (null != mViewLifeCycleListener) {
110+
mViewLifeCycleListener.onAppeared(view);
111+
}
112+
}
113+
114+
private boolean isViewReadyDisAppearing(View view) {
115+
return getViewStatus(view) == STATUS.APPEARED;
116+
}
117+
118+
private void setViewDisappearing(View view) {
119+
if (getViewStatus(view) == STATUS.DISAPPEARING) {
120+
return;
121+
}
122+
123+
setViewstatus(view, STATUS.DISAPPEARING);
124+
if (null != mViewLifeCycleListener) {
125+
mViewLifeCycleListener.onDisappearing(view);
126+
}
127+
}
128+
129+
private boolean isViewReadyDisAppeared(View view) {
130+
return getViewStatus(view) == STATUS.DISAPPEARING;
131+
}
132+
133+
private void setViewDisappeared(View view) {
134+
if (getViewStatus(view) == STATUS.DISAPPEARED) {
135+
return;
136+
}
137+
setViewstatus(view, STATUS.DISAPPEARED);
138+
if (null != mViewLifeCycleListener) {
139+
mViewLifeCycleListener.onDisappeared(view);
140+
}
141+
}
142+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.alibaba.android.vlayout.extend;
2+
3+
import android.view.View;
4+
5+
public interface ViewLifeCycleListener {
6+
void onAppearing(View view);
7+
8+
void onDisappearing(View view);
9+
10+
void onAppeared(View view);
11+
12+
void onDisappeared(View view);
13+
}

vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ public void afterLayout(RecyclerView.Recycler recycler, RecyclerView.State state
291291
} else {
292292
fixLayoutStateInCase2(orientationHelper, recycler, startPosition, endPosition, helper);
293293
}
294+
295+
if (mFixView != null){
296+
mFixView.setBackgroundColor(mBgColor);
297+
}
294298
}
295299

296300
private void fixLayoutStateFromAbnormal2Normal(OrientationHelperEx orientationHelper, RecyclerView.Recycler recycler, int startPosition, int endPosition,

0 commit comments

Comments
 (0)