Có cách nào để làm cho một ViewPager
cái không cuộn theo chiều ngang, nhưng theo chiều dọc?!
Có cách nào để làm cho một ViewPager
cái không cuộn theo chiều ngang, nhưng theo chiều dọc?!
Câu trả lời:
Bạn có thể sử dụng ViewPager.PageTransformer để tạo ảo giác về chiều dọc ViewPager
. Để đạt được cuộn bằng dọc thay vì kéo ngang, bạn sẽ phải ghi đè ViewPager
các sự kiện chạm mặc định của nó và hoán đổi tọa độ của MotionEvent
s trước khi xử lý chúng, ví dụ:
/**
* 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));
}
}
Tất nhiên bạn có thể điều chỉnh các cài đặt này khi bạn thấy phù hợp. Kết thúc như thế này:
Các câu trả lời khác ở đây dường như có một số vấn đề với họ. Ngay cả các dự án nguồn mở được đề xuất cũng không hợp nhất các yêu cầu kéo gần đây với sửa lỗi. Sau đó, tôi tìm thấy VerticalViewPager
từ Google rằng họ đã sử dụng một số ứng dụng DeskClock. Tôi tin tưởng sử dụng triển khai của Google nhiều hơn các câu trả lời khác trôi nổi quanh đây. (Phiên bản của Google tương tự như câu trả lời được bình chọn hàng đầu hiện tại, nhưng kỹ lưỡng hơn.)
Ví dụ này gần giống hệt như Ví dụ ViewPager cơ bản của tôi , với một vài thay đổi nhỏ để sử dụng VerticalViewPager
lớp.
Thêm bố cục xml cho hoạt động chính và cho mỗi trang (đoạn). Lưu ý rằng chúng tôi sử dụng VerticalViewPager
chứ không phải là tiêu chuẩn ViewPager
. Tôi sẽ bao gồm mã cho bên dưới.
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>
Mã cho VerticalViewPager
không phải là của tôi. Nó chỉ là một phiên bản rút gọn (không có bình luận) từ mã nguồn Google. Kiểm tra cái đó cho phiên bản cập nhật nhất. Các ý kiến cũng có ích để hiểu những gì đang xảy ra.
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
Tôi chỉ đổi chỗ VerticalViewPager
cho 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;
}
}
}
Bạn sẽ có thể chạy ứng dụng và xem kết quả trong hình động ở trên.
Tôi có một giải pháp phù hợp với tôi theo hai bước.
onInstantiateItem()
của PagerAdapter
, tạo chế độ xem và xoay nó theo -90:
view.setRotation(-90f)
Nếu bạn đang sử dụng FragmentPagerAdapter
, thì:
objFragment.getView().setRotation(-90)
Xoay ViewPager
góc nhìn 90 độ:
objViewPager.setRotation(90)
Hoạt động như một sự quyến rũ ít nhất cho yêu cầu của tôi.
Đối với ai đó đang vật lộn với cách làm cho ViewPager dọc hoạt động theo chiều ngang, chỉ cần thực hiện các công cụ sau:
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);
}
}
Một phần mở rộng nhỏ câu trả lời này đã giúp tôi đạt được yêu cầu của mình (Máy nhắn tin dạng xem dọc để hoạt hình tương tự như trong Inshorts - Tin tức trong 60 từ )
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));
}
}
Tôi hy vọng điều này có thể hữu ích cho người khác.
Có một vài dự án nguồn mở tuyên bố sẽ làm điều này. Họ đây rồi:
Những điều này đã được đánh dấu phản đối bởi các tác giả của họ:
Và một điều nữa:
deskclock
ứng dụng, nhưng dường như nó không được hỗ trợ chính thức vì tôi không thể tìm thấy tài liệu cho nó.Hãy xem điều này: https://github.com/JakeWharton/Android-DirectionalViewPager
Hoặc câu hỏi sau đây có thể giúp bạn: Dọc 'Gridview with page' hoặc 'Viewpager'
DirectionalViewPager
đã không được cập nhật trong một thời gian dài và do đó thiếu một số tính năng mới hơn của ViewPager
thư viện hỗ trợ; tức setPageMargin(int)
. Nói chung nó nên làm công việc mặc dù. Và nếu không, sẽ không quá khó để lấy mã nguồn ViewPager
và trao đổi tất cả logic x / y và chiều rộng / chiều cao.
DirectionalViewPager
nhưng, như MH đã nói, nó không được cập nhật (nhà phát triển của nó coi nó là ĐỔI) !! Thật đáng kinh ngạc khi các nhà phát triển Android đã không cung cấp cho cộng đồng theo chiều dọc ViewPager
mà chỉ có tầm nhìn. Tôi mới hơn với Android, phát triển ViewPager
việc thay đổi theo chiều dọc x / y không dễ dàng đối với tôi .. tôi muốn một giải pháp đã được xây dựng .. dù sao, cảm ơn bạn
Chỉ cần cải thiện câu trả lời từ @Brett và @ Salman666 để chuyển đổi chính xác tọa độ (X, Y) thành (Y, X) vì màn hình thiết bị có hình chữ nhật:
...
/**
* 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;
}
...
Tuy nhiên, vẫn cần phải làm gì đó để đáp ứng màn hình cảm ứng tốt hơn. Vấn đề có thể liên quan đến những gì @msdark nhận xét về câu trả lời của @ Salman666.
true
trong onInterceptTouchEvent
và Tôi cũng sửa đổi các ràng buộc chính, do đó sử dụng một DPAD nó gây nên cuộn với UP / DOWN thay vì trái / phải: 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);
}
}
Thực sự đã có một trong nguồn Android . Tôi đã sửa đổi nó để hoạt động tốt hơn mặc dù:
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);
}
}
Một kho lưu trữ hiện đang hoạt động nhiều hơn là lsjwzh / RecyclerViewPager .
RecyclerView
Đây là một triển khai ViewPager có thể cuộn dọc. Làm việc tốt với RecyclerView và ListView. guochong / dọcViewPager .
sử dụng ViewPager.PageTransformer để tạo ViewPager cuộn theo chiều dọc và cũng cung cấp View.OnTouchListener để xử lý xung đột cuộn.
/**
* 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;
}
Ngay cả tôi cũng gặp phải vấn đề tương tự với việc tạo ViewPager theo chiều dọc bằng cách hoán đổi X và Y. Nó không hoàn toàn suôn sẻ.
Đó là bởi vì nó chỉ hoạt động khi góc vuốt nhỏ hơn 7.125 độ = arctan (1/8) trong khi chặn và 14 độ = arctan (1/4) khi chạm; như ViewPager ban đầu nằm ngang một tác phẩm khi góc vuốt nhỏ hơn 26,565 độ = arctan (1/2) trong khi chặn và 45 độ = arctan (1) trong khi chạm.
Đó là lý do tại sao tôi đã sao chép mã hỗ trợ Android-core-ui và chuyển các giá trị thành các biến, mà tôi đã nhân lên bằng cách sử dụng sự phản chiếu.
Vui lòng tìm mã và README tại https://github.com/deepakmishra/verticalviewpager và verticalViewPager tại https://github.com/deepakmishra/verticalviewpager/blob/master/app/src/main/java/com/viewpager/V vertical .java
Cuối cùng tôi đã tạo ra một DirectionalViewPager mới có thể cuộn theo chiều dọc hoặc chiều ngang bởi vì tất cả các giải pháp tôi thấy ở đây đều có sai sót:
Các triển khai dọcViewPager hiện có (của castorflex và LambergaR)
Thủ thuật chuyển đổi với sự phối hợp hoán đổi
VelocityTracker.computeCurrentVelocity
vẫn tính toán vận tốc với trục X, có thể vì nội bộ này sử dụng lệnh gọi gốc mà bỏ qua hoán đổi tọa độ.Xem xoay