Skip to content

Commit e3be95d

Browse files
Piotr Zawadzkizawadz88
authored andcommitted
Added RTL support for StepperLayout's inner ViewPager
1 parent fccdae0 commit e3be95d

File tree

14 files changed

+334
-15
lines changed

14 files changed

+334
-15
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ before_script:
3232
- printf 'bintray.user=dummy_user\nbintray.apikey=dummy_api_key' > local.properties
3333

3434
script:
35-
- ./gradlew check
35+
- ./gradlew check install
3636

3737
after_success:
3838
- bash <(curl -s https://codecov.io/bash)

material-stepper/build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,6 @@ tasks.matching {it instanceof Test}.all {
8484
check.dependsOn 'checkstyle', 'findbugs', 'pmd', 'jacocoTestReport'
8585

8686
apply from: '../installv1.gradle'
87-
apply from: '../bintrayv1.gradle'
87+
apply from: '../bintrayv1.gradle'
88+
89+
install.mustRunAfter check

material-stepper/src/main/java/com/stepstone/stepper/StepperLayout.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,13 @@ public void setAdapter(@NonNull StepAdapter stepAdapter, @IntRange(from = 0) int
331331
}
332332

333333
/**
334-
* Overrides the default page transformer used in the underlying {@link ViewPager}
334+
* Overrides the default page transformer used in the underlying {@link com.stepstone.stepper.internal.widget.StepViewPager}.
335+
* If you're supporting RTL make sure your {@link android.support.v4.view.ViewPager.PageTransformer} accounts for it.
335336
*
336337
* @param pageTransformer new page transformer
338+
*
339+
* @see com.stepstone.stepper.internal.widget.StepViewPager
340+
* @see com.stepstone.stepper.internal.widget.pagetransformer.StepPageTransformerFactory
337341
*/
338342
public void setPageTransformer(@Nullable ViewPager.PageTransformer pageTransformer) {
339343
mPager.setPageTransformer(false, pageTransformer);
Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,24 @@
2222
import android.util.AttributeSet;
2323
import android.view.MotionEvent;
2424

25+
import com.stepstone.stepper.internal.widget.pagetransformer.StepPageTransformerFactory;
26+
2527
import static android.support.annotation.RestrictTo.Scope.LIBRARY;
2628

2729
/**
28-
* A non-swipeable viewpager.<br>
30+
* A non-swipeable viewpager with RTL support.<br>
2931
* <a href="http://stackoverflow.com/questions/9650265/how-do-disable-paging-by-swiping-with-finger-in-viewpager-but-still-be-able-to-s">Source</a>
3032
*/
3133
@RestrictTo(LIBRARY)
32-
public class NonSwipeableViewPager extends ViewPager {
34+
public class StepViewPager extends ViewPager {
3335

34-
public NonSwipeableViewPager(Context context) {
35-
super(context);
36+
public StepViewPager(Context context) {
37+
this(context, null);
3638
}
3739

38-
public NonSwipeableViewPager(Context context, AttributeSet attrs) {
40+
public StepViewPager(Context context, AttributeSet attrs) {
3941
super(context, attrs);
42+
setPageTransformer(false, StepPageTransformerFactory.createPageTransformer(context));
4043
}
4144

4245
@Override
@@ -50,4 +53,5 @@ public boolean onTouchEvent(MotionEvent event) {
5053
// Never allow swiping to switch between pages
5154
return false;
5255
}
56+
5357
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.stepstone.stepper.internal.widget.pagetransformer;
2+
3+
import android.content.Context;
4+
import android.support.annotation.NonNull;
5+
import android.support.annotation.Nullable;
6+
import android.support.annotation.RestrictTo;
7+
import android.support.v4.view.ViewPager;
8+
9+
import com.stepstone.stepper.R;
10+
11+
import static android.support.annotation.RestrictTo.Scope.LIBRARY;
12+
13+
/**
14+
* Creates a page transformer to be used by {@link com.stepstone.stepper.internal.widget.StepViewPager}.
15+
*
16+
* @author Piotr Zawadzki
17+
*/
18+
@RestrictTo(LIBRARY)
19+
public final class StepPageTransformerFactory {
20+
21+
private StepPageTransformerFactory() {
22+
}
23+
24+
/**
25+
* Creates a {@link android.support.v4.view.ViewPager.PageTransformer}.
26+
* If layout direction is in RTL it returns {@link StepperRtlPageTransformer}, <i>null</i> otherwise.
27+
* @param context context
28+
* @return page transformer
29+
*/
30+
@Nullable
31+
public static ViewPager.PageTransformer createPageTransformer(@NonNull Context context) {
32+
boolean rtlEnabled = context.getResources().getBoolean(R.bool.ms_rtlEnabled);
33+
return rtlEnabled ? new StepperRtlPageTransformer() : null;
34+
}
35+
36+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.stepstone.stepper.internal.widget.pagetransformer;
2+
3+
import android.support.annotation.RestrictTo;
4+
import android.support.v4.view.ViewPager;
5+
import android.view.View;
6+
7+
import static android.support.annotation.RestrictTo.Scope.LIBRARY;
8+
9+
/**
10+
* A {@link android.support.v4.view.ViewPager.PageTransformer} which reverses
11+
* the direction in which the pages slide in.
12+
*
13+
* @author Piotr Zawadzki
14+
*/
15+
@RestrictTo(LIBRARY)
16+
public class StepperRtlPageTransformer implements ViewPager.PageTransformer {
17+
18+
@Override
19+
public void transformPage(View view, float position) {
20+
/* This moves the View to the other side.
21+
*
22+
* Lets assume that ViewPager has a width of 300dp.
23+
* This means that Views also have a width of 300dp.
24+
* The view that's in front and center has a position on screen equal to 0dp.
25+
* By view position we mean the position of view's left edge.
26+
*
27+
* Now, assuming we have a View on the right which is visible in 33% (its left 33% are visible)
28+
* we know that its actual position on the screen would be 200dp = 300dp * (100% - 33%).
29+
*
30+
* In this state from transformPage(..) method would be called with position = 0.67
31+
*
32+
* The line below would move the view by 400dp = -2 * 0.67 * 300dp to the left.
33+
* So effectively the view would be at -200dp and it's right 100dp would be visible.
34+
*
35+
* Thus, the view would be actually sliding to the other side which we expect when in RTL layout direction.
36+
*/
37+
view.setTranslationX(-2 * position * view.getWidth());
38+
39+
}
40+
}

material-stepper/src/main/res/layout/ms_stepper_layout.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
android:layout_height="0dp"
1919
android:layout_weight="1">
2020

21-
<com.stepstone.stepper.internal.widget.NonSwipeableViewPager
21+
<com.stepstone.stepper.internal.widget.StepViewPager
2222
android:id="@+id/ms_stepPager"
2323
android:layout_width="match_parent"
2424
android:layout_height="match_parent" />
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
4+
<bool name="ms_rtlEnabled">true</bool>
5+
6+
</resources>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
4+
<bool name="ms_rtlEnabled">false</bool>
5+
6+
</resources>

material-stepper/src/test/java/com/stepstone/stepper/StepperLayoutSanityTest.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.stepstone.stepper;
22

33
import android.content.Context;
4-
import android.os.Build;
54
import android.support.annotation.IntRange;
65
import android.support.annotation.NonNull;
76
import android.support.v4.app.Fragment;
@@ -10,14 +9,13 @@
109
import android.util.AttributeSet;
1110

1211
import com.stepstone.stepper.adapter.AbstractFragmentStepAdapter;
12+
import com.stepstone.stepper.test.runner.StepperRobolectricTestRunner;
1313
import com.stepstone.stepper.viewmodel.StepViewModel;
1414

1515
import org.junit.Before;
1616
import org.junit.Test;
1717
import org.junit.runner.RunWith;
1818
import org.robolectric.Robolectric;
19-
import org.robolectric.RobolectricTestRunner;
20-
import org.robolectric.annotation.Config;
2119

2220
import static com.stepstone.stepper.test.assertion.StepperLayoutAssert.assertThat;
2321
import static org.mockito.Mockito.mock;
@@ -26,15 +24,14 @@
2624
/**
2725
* @author Piotr Zawadzki
2826
*/
29-
@RunWith(RobolectricTestRunner.class)
30-
@Config(sdk = Build.VERSION_CODES.LOLLIPOP, constants = BuildConfig.class)
27+
@RunWith(StepperRobolectricTestRunner.class)
3128
public class StepperLayoutSanityTest {
3229

3330
private static final String TYPE_PROGRESS_BAR = "progress_bar";
3431
private static final String TYPE_DOTS = "dots";
3532
private static final String TYPE_TABS = "tabs";
3633

37-
private FragmentActivity activity;
34+
FragmentActivity activity;
3835

3936
@Before
4037
public void setUp() throws Exception {

0 commit comments

Comments
 (0)