Skip to content

Commit b85a0a8

Browse files
author
Alexander Mikhalevich
committed
Added looping feature.
1 parent dd5a984 commit b85a0a8

File tree

4 files changed

+24
-12
lines changed

4 files changed

+24
-12
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ Currently SwipeStack implements the following callbacks:
125125

126126
`disable_hw_acceleration` set to `true` disables hardware acceleration. *Default: false*
127127

128+
`looped` set to `true` enables looping. *Default: false*
129+
128130
## Copyright Notice ##
129131
```
130132
Copyright (C) 2016 Frederik Schweiger

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ buildscript {
55
jcenter()
66
}
77
dependencies {
8-
classpath 'com.android.tools.build:gradle:2.0.0-beta5'
8+
classpath 'com.android.tools.build:gradle:2.1.0'
99
classpath 'com.novoda:bintray-release:0.3.4'
1010
}
1111
}

library/src/main/java/link/fls/swipestack/SwipeStack.java

+20-11
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public class SwipeStack extends ViewGroup {
4444
public static final float DEFAULT_SWIPE_OPACITY = 1f;
4545
public static final float DEFAULT_SCALE_FACTOR = 1f;
4646
public static final boolean DEFAULT_DISABLE_HW_ACCELERATION = true;
47+
public static final boolean DEFAULT_IS_LOOPED = false;
4748

4849
private static final String KEY_SUPER_STATE = "superState";
4950
private static final String KEY_CURRENT_INDEX = "currentIndex";
@@ -53,7 +54,7 @@ public class SwipeStack extends ViewGroup {
5354

5455
private int mAllowedSwipeDirections;
5556
private int mAnimationDuration;
56-
private int mCurrentViewIndex;
57+
private int mCurrentIndex;
5758
private int mNumberOfStackedViews;
5859
private int mViewSpacing;
5960
private int mViewRotation;
@@ -62,6 +63,7 @@ public class SwipeStack extends ViewGroup {
6263
private float mScaleFactor;
6364
private boolean mDisableHwAcceleration;
6465
private boolean mIsFirstLayout = true;
66+
private boolean mIsLooped;
6567

6668
private View mTopView;
6769
private SwipeHelper mSwipeHelper;
@@ -109,6 +111,9 @@ private void readAttributes(AttributeSet attributeSet) {
109111
mDisableHwAcceleration =
110112
attrs.getBoolean(R.styleable.SwipeStack_disable_hw_acceleration,
111113
DEFAULT_DISABLE_HW_ACCELERATION);
114+
mIsLooped =
115+
attrs.getBoolean(R.styleable.SwipeStack_looped,
116+
DEFAULT_IS_LOOPED);
112117
} finally {
113118
attrs.recycle();
114119
}
@@ -139,32 +144,36 @@ public void onChanged() {
139144
public Parcelable onSaveInstanceState() {
140145
Bundle bundle = new Bundle();
141146
bundle.putParcelable(KEY_SUPER_STATE, super.onSaveInstanceState());
142-
bundle.putInt(KEY_CURRENT_INDEX, mCurrentViewIndex - getChildCount());
147+
bundle.putInt(KEY_CURRENT_INDEX, mCurrentIndex - getChildCount());
143148
return bundle;
144149
}
145150

146151
@Override
147152
public void onRestoreInstanceState(Parcelable state) {
148153
if (state instanceof Bundle) {
149154
Bundle bundle = (Bundle) state;
150-
mCurrentViewIndex = bundle.getInt(KEY_CURRENT_INDEX);
155+
mCurrentIndex = bundle.getInt(KEY_CURRENT_INDEX);
151156
state = bundle.getParcelable(KEY_SUPER_STATE);
152157
}
153158

154159
super.onRestoreInstanceState(state);
155160
}
156161

162+
private int getCurrentViewIndex() {
163+
return mCurrentIndex % mAdapter.getCount();
164+
}
165+
157166
@Override
158167
protected void onLayout(boolean changed, int l, int t, int r, int b) {
159168

160169
if (mAdapter == null || mAdapter.isEmpty()) {
161-
mCurrentViewIndex = 0;
170+
mCurrentIndex = 0;
162171
removeAllViewsInLayout();
163172
return;
164173
}
165174

166175
for (int x = getChildCount();
167-
x < mNumberOfStackedViews && mCurrentViewIndex < mAdapter.getCount();
176+
x < mNumberOfStackedViews && (mIsLooped || mCurrentIndex < mAdapter.getCount());
168177
x++) {
169178
addNextView();
170179
}
@@ -175,8 +184,8 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) {
175184
}
176185

177186
private void addNextView() {
178-
if (mCurrentViewIndex < mAdapter.getCount()) {
179-
View bottomView = mAdapter.getView(mCurrentViewIndex, null, this);
187+
if (getCurrentViewIndex() < mAdapter.getCount()) {
188+
View bottomView = mAdapter.getView(getCurrentViewIndex(), null, this);
180189
bottomView.setTag(R.id.new_view, true);
181190

182191
if (!mDisableHwAcceleration) {
@@ -211,7 +220,7 @@ private void addNextView() {
211220
bottomView.measure(measureSpecWidth | width, measureSpecHeight | height);
212221
addViewInLayout(bottomView, 0, params, true);
213222

214-
mCurrentViewIndex++;
223+
mCurrentIndex++;
215224
}
216225
}
217226

@@ -301,7 +310,7 @@ public void onSwipeEnd() {
301310
}
302311

303312
public void onViewSwipedToLeft() {
304-
if (mListener != null) mListener.onViewSwipedToLeft(getCurrentPosition());
313+
if (mListener != null) mListener.onViewSwipedToRight(getCurrentPosition());
305314
removeTopView();
306315
}
307316

@@ -316,7 +325,7 @@ public void onViewSwipedToRight() {
316325
* @return The current position.
317326
*/
318327
public int getCurrentPosition() {
319-
return mCurrentViewIndex - getChildCount();
328+
return (mCurrentIndex - getChildCount()) % mAdapter.getCount();
320329
}
321330

322331
/**
@@ -410,7 +419,7 @@ public void swipeTopViewToLeft() {
410419
* Resets the current adapter position and repopulates the stack.
411420
*/
412421
public void resetStack() {
413-
mCurrentViewIndex = 0;
422+
mCurrentIndex = 0;
414423
removeAllViewsInLayout();
415424
requestLayout();
416425
}

library/src/main/res/values/attrs.xml

+1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@
1414
<attr name="swipe_opacity" format="float"/>
1515
<attr name="scale_factor" format="float"/>
1616
<attr name="disable_hw_acceleration" format="boolean"/>
17+
<attr name="looped" format="boolean"/>
1718
</declare-styleable>
1819
</resources>

0 commit comments

Comments
 (0)