Czy istnieje sposób, aby ViewPager
przewijać nie w poziomie, ale w pionie ?!
Czy istnieje sposób, aby ViewPager
przewijać nie w poziomie, ale w pionie ?!
Odpowiedzi:
Możesz użyć ViewPager.PageTransformer, aby stworzyć iluzję pionu ViewPager
. Aby uzyskać przewijanie w pionie zamiast w poziomie, będziesz musiał zastąpić ViewPager
domyślne zdarzenia dotyku i zamienić współrzędne MotionEvent
s przed ich obsługą, np .:
/**
* Uses a combination of a PageTransformer and swapping X & Y coordinates
* of touch events to create the illusion of a vertically scrolling ViewPager.
*
* Requires API 11+
*
*/
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens here
setPageTransformer(true, new VerticalPageTransformer());
// The easiest way to get rid of the overscroll drawing that happens on the left and right
setOverScrollMode(OVER_SCROLL_NEVER);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
@Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
Oczywiście możesz dostosować te ustawienia według własnego uznania. Kończy się tak:
Wszystkie inne odpowiedzi wydawały się mieć z nimi pewne problemy. Nawet zalecane projekty open source nie łączyły ostatnich żądań ściągnięcia z poprawkami błędów. Potem znalazłem VerticalViewPager
od Google, że używali jakiejś aplikacji DeskClock. Ufam implementacji Google znacznie bardziej niż innym odpowiedziom krążącym tutaj. (Wersja Google jest podobna do aktualnie najczęściej głosowanej odpowiedzi, ale jest dokładniejsza).
Ten przykład jest prawie dokładnie taki sam, jak mój przykład Basic ViewPager , z kilkoma drobnymi zmianami w celu wykorzystania tej VerticalViewPager
klasy.
Dodaj układy xml dla głównego działania i dla każdej strony (fragmentu). Zwróć uwagę, że używamy VerticalViewPager
zamiast standardu ViewPager
. Dołączę do tego kod poniżej.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.verticalviewpager.MainActivity">
<com.example.myapp.VerticalViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
fragment_one.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textview"
android:textSize="30sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
Kod VerticalViewPager
nie jest mój. To tylko okrojona wersja (bez komentarzy) z kodu źródłowego Google. Sprawdź ten, aby uzyskać najbardziej aktualną wersję. Komentarze są również pomocne w zrozumieniu tego, co się dzieje.
import android.support.v4.view.ViewPager;
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
this(context, null);
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
@Override
public boolean canScrollHorizontally(int direction) {
return false;
}
@Override
public boolean canScrollVertically(int direction) {
return super.canScrollHorizontally(direction);
}
private void init() {
setPageTransformer(true, new VerticalPageTransformer());
setOverScrollMode(View.OVER_SCROLL_NEVER);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final boolean toIntercept = super.onInterceptTouchEvent(flipXY(ev));
flipXY(ev);
return toIntercept;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
final boolean toHandle = super.onTouchEvent(flipXY(ev));
flipXY(ev);
return toHandle;
}
private MotionEvent flipXY(MotionEvent ev) {
final float width = getWidth();
final float height = getHeight();
final float x = (ev.getY() / height) * width;
final float y = (ev.getX() / width) * height;
ev.setLocation(x, y);
return ev;
}
private static final class VerticalPageTransformer implements ViewPager.PageTransformer {
@Override
public void transformPage(View view, float position) {
final int pageWidth = view.getWidth();
final int pageHeight = view.getHeight();
if (position < -1) {
view.setAlpha(0);
} else if (position <= 1) {
view.setAlpha(1);
view.setTranslationX(pageWidth * -position);
float yPosition = position * pageHeight;
view.setTranslationY(yPosition);
} else {
view.setAlpha(0);
}
}
}
}
MainActivity.java
Zamieniłem się tylko VerticalViewPager
na ViewPager
.
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
public class MainActivity extends AppCompatActivity {
static final int NUMBER_OF_PAGES = 2;
MyAdapter mAdapter;
VerticalViewPager mPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = findViewById(R.id.viewpager);
mPager.setAdapter(mAdapter);
}
public static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return NUMBER_OF_PAGES;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FragmentOne.newInstance(0, Color.WHITE);
case 1:
// return a different Fragment class here
// if you want want a completely different layout
return FragmentOne.newInstance(1, Color.CYAN);
default:
return null;
}
}
}
public static class FragmentOne extends Fragment {
private static final String MY_NUM_KEY = "num";
private static final String MY_COLOR_KEY = "color";
private int mNum;
private int mColor;
// You can modify the parameters to pass in whatever you want
static FragmentOne newInstance(int num, int color) {
FragmentOne f = new FragmentOne();
Bundle args = new Bundle();
args.putInt(MY_NUM_KEY, num);
args.putInt(MY_COLOR_KEY, color);
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt(MY_NUM_KEY) : 0;
mColor = getArguments() != null ? getArguments().getInt(MY_COLOR_KEY) : Color.BLACK;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_one, container, false);
v.setBackgroundColor(mColor);
TextView textView = v.findViewById(R.id.textview);
textView.setText("Page " + mNum);
return v;
}
}
}
Powinieneś móc uruchomić aplikację i zobaczyć wynik na powyższej animacji.
Mam rozwiązanie, które działa dla mnie w dwóch krokach.
onInstantiateItem()
z PagerAdapter
, utwórz widok i obróć go o -90:
view.setRotation(-90f)
Jeśli używasz FragmentPagerAdapter
, to:
objFragment.getView().setRotation(-90)
Obróć ViewPager
widok o 90 stopni:
objViewPager.setRotation(90)
Działa jak urok, przynajmniej na moje wymagania.
Dla kogoś, kto boryka się z tym, jak sprawić, by ViewPager działał w pionie w poziomie, wykonaj następujące czynności:
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setPageTransformer(true, new VerticalPageTransformer());
setOverScrollMode(OVER_SCROLL_NEVER);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
@Override
public void transformPage(View view, float position) {
if (position < -1) {
view.setAlpha(0);
} else if (position <= 1) {
view.setAlpha(1);
view.setTranslationX(view.getWidth() * -position);
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else {
view.setAlpha(0);
}
}
}
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev);
return intercepted;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
public class HorizontalViewPager extends ViewPager {
private GestureDetector xScrollDetector;
public HorizontalViewPager(Context context) {
super(context);
}
public HorizontalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
xScrollDetector = new GestureDetector(getContext(), new XScrollDetector());
}
class XScrollDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return Math.abs(distanceX) > Math.abs(distanceY);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (xScrollDetector.onTouchEvent(ev)) {
super.onInterceptTouchEvent(ev);
return true;
}
return super.onInterceptTouchEvent(ev);
}
}
Niewielkie rozszerzenie tej odpowiedzi pomogło mi spełnić moje wymagania (Pager z widokiem pionowym do animacji podobnej jak w Inshorts - Wiadomości w 60 słowach )
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens here
setPageTransformer(true, new VerticalPageTransformer());
// The easiest way to get rid of the overscroll drawing that happens on the left and right
setOverScrollMode(OVER_SCROLL_NEVER);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
@Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // [0,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
Mam nadzieję, że to może być pomocne dla kogoś innego.
Istnieje kilka projektów open source, które twierdzą, że to robią. Tutaj są:
Zostały one oznaczone przez ich autorów jako przestarzałe:
I jeszcze jedno:
deskclock
aplikacji, ale nie wydaje się, aby była oficjalnie obsługiwana, ponieważ nie mogę znaleźć dokumentacji.Sprawdź to: https://github.com/JakeWharton/Android-DirectionalViewPager
Lub poniższe pytanie może Ci pomóc: Pionowy „Widok siatki ze stronami” lub „Viewpager”
DirectionalViewPager
nie był on aktualizowany od dłuższego czasu i dlatego brakuje w nim niektórych nowszych funkcji ViewPager
w bibliotece wsparcia; tj setPageMargin(int)
. Generalnie jednak powinien wystarczyć. A jeśli nie, pobranie kodu źródłowego ViewPager
i zamiana całej logiki x / y i szerokości / wysokości nie jest zbyt trudne .
DirectionalViewPager
ale, jak powiedział MH, nie jest aktualizowany (jego twórca uważa to za DEPRECATED) !! To niesamowite, że programiści Androida nie zapewnili społeczności pionu ViewPager
, a jedynie poziom. Jestem nowicjuszem na Androidzie, rozwijanie mojej pionowej ViewPager
zamiany x / y nie jest dla mnie takie łatwe .. wolałbym już zbudowane rozwiązanie .. w każdym razie, dziękuję
To tylko ulepszenie odpowiedzi z @Brett i @ Salman666, aby poprawnie przekształcić współrzędne (X, Y) na (Y, X), ponieważ wyświetlacze urządzeń są prostokątne:
...
/**
* Swaps the X and Y coordinates of your touch event
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(swapXY(ev));
}
private MotionEvent swapXY(MotionEvent ev) {
//Get display dimensions
float displayWidth=this.getWidth();
float displayHeight=this.getHeight();
//Get current touch position
float posX=ev.getX();
float posY=ev.getY();
//Transform (X,Y) into (Y,X) taking display dimensions into account
float newPosX=(posY/displayHeight)*displayWidth;
float newPosY=(1-posX/displayWidth)*displayHeight;
//swap the x and y coords of the touch event
ev.setLocation(newPosX, newPosY);
return ev;
}
...
Jednak nadal trzeba coś zrobić, aby poprawić reakcję ekranu dotykowego. Problem może być związany z tym, co @msdark skomentował odpowiedź @ Salman666.
true
w onInterceptTouchEvent
, a ja również zmodyfikowała klawiszy, dzięki czemu za pomocą D-pada wywołuje przewijania z górę / w dół zamiast w lewo / w prawo: gist.github.com/zevektor/fbacf4f4f6c39fd6e409
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setPageTransformer(true, new VerticalPageTransformer());
setOverScrollMode(OVER_SCROLL_NEVER);
}
private class VerticalPageTransformer implements PageTransformer {
@Override
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) {
view.setAlpha(0);
} else if (position <= 1) {
view.setAlpha(1);
view.setTranslationX(pageWidth * -position);
float yPosition = position * pageHeight;
view.setTranslationY(yPosition);
} else {
view.setAlpha(0);
}
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
ev.setLocation(ev.getY(), ev.getX());
return super.onTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
ev.setLocation(ev.getY(), ev.getX());
return super.onInterceptTouchEvent(ev);
}
}
Skończyło się na utworzeniu nowego DirectionalViewPager, który może przewijać w pionie lub w poziomie, ponieważ wszystkie rozwiązania, które tu widziałem, mają wady:
Istniejące implementacje VerticalViewPager (autorstwa Castorflex i LambergaR)
Sztuczka transformacji z zamianą współrzędnych
VelocityTracker.computeCurrentVelocity
nadal oblicza prędkość z osią X, prawdopodobnie dlatego, że wewnętrznie używa się wywołania natywnego, które ignoruje zamianę współrzędnych.Zobacz obrót
Właściwie jest już jeden w źródle Androida . Zmodyfikowałem go, aby działał lepiej:
package com.crnlgcs.sdk.widgets;
import android.content.Context;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewParent;
public class VerticalViewPager extends ViewPager {
private static final String TAG = "VerticalViewPager";
private static final boolean DEBUG = true;
private float mLastMotionX;
private float mLastMotionY;
private float mTouchSlop;
private boolean mVerticalDrag;
private boolean mHorizontalDrag;
// Vertical transit page transformer
private final ViewPager.PageTransformer mPageTransformer = new ViewPager.PageTransformer() {
@Override
public void transformPage(View view, float position) {
final int pageWidth = view.getWidth();
final int pageHeight = view.getHeight();
if (position < -1) {
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) {
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// set Y position to swipe in from top
float yPosition = position * pageHeight;
view.setTranslationY(yPosition);
} else {
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
};
public VerticalViewPager(Context context) {
super(context, null);
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
init();
}
private void init() {
// Make page transit vertical
setPageTransformer(true, mPageTransformer);
// Get rid of the overscroll drawing that happens on the left and right (the ripple)
setOverScrollMode(View.OVER_SCROLL_NEVER);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
final float x = ev.getX();
final float y = ev.getY();
if (DEBUG) Log.v(TAG, "onTouchEvent " + x + ", " + y);
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
mLastMotionX = x;
mLastMotionY = y;
if (!super.onTouchEvent(ev))
return false;
return verticalDrag(ev);
}
case MotionEvent.ACTION_MOVE: {
final float xDiff = Math.abs(x - mLastMotionX);
final float yDiff = Math.abs(y - mLastMotionY);
if (!mHorizontalDrag && !mVerticalDrag) {
if (xDiff > mTouchSlop && xDiff > yDiff) { // Swiping left and right
mHorizontalDrag = true;
} else if (yDiff > mTouchSlop && yDiff > xDiff) { //Swiping up and down
mVerticalDrag = true;
}
}
if (mHorizontalDrag) {
return super.onTouchEvent(ev);
} else if (mVerticalDrag) {
return verticalDrag(ev);
}
}
case MotionEvent.ACTION_UP: {
if (mHorizontalDrag) {
mHorizontalDrag = false;
return super.onTouchEvent(ev);
}
if (mVerticalDrag) {
mVerticalDrag = false;
return verticalDrag(ev);
}
}
}
// Set both flags to false in case user lifted finger in the parent view pager
mHorizontalDrag = false;
mVerticalDrag = false;
return false;
}
private boolean verticalDrag(MotionEvent ev) {
final float x = ev.getX();
final float y = ev.getY();
ev.setLocation(y, x);
return super.onTouchEvent(ev);
}
}
Obecnie bardziej aktywnym repozytorium jest lsjwzh / RecyclerViewPager .
RecyclerView
Jest to pionowa, przewijalna implementacja ViewPagera, która dobrze współpracuje z RecyclerView i ListView. guochong / VerticalViewPager .
użyj ViewPager.PageTransformer, aby ViewPager przewijał się w pionie, a także zapewnij View.OnTouchListener, aby poradzić sobie z konfliktem przewijania.
/**
* 1.dispatch ACTION_DOWN,ACTION_UP,ACTION_CANCEL to child<br>
* 2.hack ACTION_MOVE
*
* @param v
* @param e
* @return
*/
@Override
public boolean onTouch(View v, MotionEvent e) {
Log.i(TAG, "onTouchEvent " + ", action " + e.getAction() + ", e.rawY " + e.getRawY() + ",lastMotionY " + lastMotionY + ",downY " + downY);
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = e.getRawY();
break;
case MotionEvent.ACTION_MOVE:
if (downY == Float.MIN_VALUE && lastMotionY == Float.MIN_VALUE) {
//not start from MOTION_DOWN, the child dispatch this first motion
downY = e.getRawY();
break;
}
float diff = e.getRawY() - (lastMotionY == Float.MIN_VALUE ? downY : lastMotionY);
lastMotionY = e.getRawY();
diff = diff / 2; //slow down viewpager scroll
Log.e(TAG, "scrollX " + dummyViewPager.getScrollX() + ",basescrollX " + dummyViewPager.getBaseScrollX());
if (dummyViewPager.getScrollX() != dummyViewPager.getBaseScrollX()) {
if (fakeDragVp(v, e, diff)) return true;
} else {
if (ViewCompat.canScrollVertically(v, (-diff) > 0 ? 1 : -1)) {
Log.e(TAG, "scroll vertically " + diff + ", move.lastMotionY " + e.getY());
break;
} else {
dummyViewPager.beginFakeDrag();
fakeDragVp(v, e, diff);
adjustDownMotion(v, e);
return true;
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (dummyViewPager.isFakeDragging()) {
try {
dummyViewPager.endFakeDrag();
} catch (Exception e1) {
Log.e(TAG, "", e1);
}
}
reset();
break;
}
return false;
}
Nawet ja miałem ten sam problem z ustawieniem ViewPagera w pionie przez zamianę X i Y. Nie było to wcale gładkie.
Dzieje się tak, ponieważ kiedyś działało tylko wtedy, gdy kąt przesuwania był mniejszy niż 7,125 stopnia = arctan (1/8) podczas przecięcia i 14 stopni = arctan (1/4) podczas dotyku; tak jak oryginalny ViewPager poziomy działa, gdy kąt przesuwania jest mniejszy niż 26,565 stopni = arctan (1/2) podczas przecięcia i 45 stopni = arctan (1) podczas dotykania.
Dlatego skopiowałem kod Android support-core-ui i przeniosłem wartości do zmiennych, które pomnożyłem za pomocą odbicia.
Kod i plik README można znaleźć pod adresem https://github.com/deepakmishra/verticalviewpager i VerticalViewPager pod adresem https://github.com/deepakmishra/verticalviewpager/blob/master/app/src/main/java/com/viewpager/VerticalViewPager .Jawa