มีวิธีทำให้ a ViewPager
ที่ไม่เลื่อนในแนวนอน แต่แนวตั้งหรือไม่!
มีวิธีทำให้ a ViewPager
ที่ไม่เลื่อนในแนวนอน แต่แนวตั้งหรือไม่!
คำตอบ:
คุณสามารถใช้ViewPager.PageTransformerViewPager
เพื่อให้ภาพลวงตาของแนวตั้ง เพื่อให้การเลื่อนด้วยแนวตั้งแทนที่จะเป็นการลากแนวนอนคุณจะต้องแทนที่ViewPager
เหตุการณ์การสัมผัสเริ่มต้นและสลับพิกัดของMotionEvent
s ก่อนการจัดการเช่น
/**
* 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));
}
}
แน่นอนคุณสามารถปรับแต่งการตั้งค่าเหล่านี้ตามที่เห็นสมควร จบลงด้วยการมีลักษณะเช่นนี้:
ฉันมีวิธีแก้ปัญหาที่เหมาะกับฉันในสองขั้นตอน
onInstantiateItem()
จากPagerAdapter
สร้างมุมมองและหมุนโดย -90:
view.setRotation(-90f)
หากคุณกำลังใช้FragmentPagerAdapter
งานอยู่:
objFragment.getView().setRotation(-90)
หมุนViewPager
มุมมอง 90 องศา:
objViewPager.setRotation(90)
ทำงานอย่างมีเสน่ห์อย่างน้อยก็สำหรับความต้องการของฉัน
คำตอบอื่น ๆ ที่นี่ทั้งหมดดูเหมือนจะมีปัญหาบางอย่างกับพวกเขา แม้แต่โครงการโอเพ่นซอร์สที่แนะนำก็ไม่ได้รวมคำขอดึงล่าสุดกับการแก้ไขข้อบกพร่อง จากนั้นฉันพบ a VerticalViewPager
จาก Google ว่าพวกเขาใช้แอป DeskClock ฉันเชื่อมั่นในการใช้งานของ Google มากกว่าคำตอบอื่น ๆ (เวอร์ชันของ Google คล้ายกับคำตอบที่ได้รับคะแนนสูงสุดในปัจจุบัน แต่ละเอียดยิ่งขึ้นกว่านี้)
ตัวอย่างนี้เกือบเหมือนกับตัวอย่างพื้นฐานของViewPagerของฉันโดยมีการเปลี่ยนแปลงเล็กน้อยเพื่อใช้VerticalViewPager
คลาส
เพิ่มเลย์เอาต์ xml สำหรับกิจกรรมหลักและสำหรับแต่ละหน้า (แฟรกเมนต์) หมายเหตุที่เราใช้มากกว่ามาตรฐานVerticalViewPager
ViewPager
ฉันจะรวมรหัสสำหรับด้านล่าง
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>
รหัสสำหรับVerticalViewPager
ไม่ใช่ของฉัน มันเป็นเพียงเวอร์ชันที่ถูกตัดทอน (ไม่มีความคิดเห็น) จากซอร์สโค้ดของ Google ลองดูเวอร์ชั่นล่าสุดสำหรับเวอร์ชั่นล่าสุด ความคิดเห็นที่มีประโยชน์สำหรับการทำความเข้าใจสิ่งที่เกิดขึ้น
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
ผมสลับเดียวที่ออกมาสำหรับVerticalViewPager
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;
}
}
}
คุณควรจะสามารถเรียกใช้แอพและดูผลลัพธ์ในภาพเคลื่อนไหวด้านบน
สำหรับคนที่ดิ้นรนกับวิธีทำให้ ViewPager ในแนวตั้งทำงานในแนวนอนให้ทำสิ่งต่อไปนี้:
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);
}
}
ส่วนขยายเล็กน้อยคำตอบนี้ช่วยให้ฉันสามารถทำตามความต้องการของฉันได้ (มุมมองแนวตั้งเพจเจอร์ทำให้มีลักษณะคล้ายกันในInshorts - ข่าว 60 คำ )
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));
}
}
ฉันหวังว่านี่จะเป็นประโยชน์กับคนอื่น
มีโครงการโอเพนซอร์ซสองสามตัวที่อ้างว่าทำสิ่งนี้ ที่นี่พวกเขาคือ:
สิ่งเหล่านี้ได้ถูกคัดค้านโดยผู้เขียน:
และอีกสิ่งหนึ่ง:
deskclock
แอป แต่ดูเหมือนจะไม่ได้รับการสนับสนุนอย่างเป็นทางการเนื่องจากฉันไม่สามารถหาเอกสารของมันได้ลองใช้งานได้เลย: https://github.com/JakeWharton/Android-DirectionalViewPager
หรือคำถามต่อไปนี้อาจช่วยคุณได้: แนวตั้ง 'Gridview with pages' หรือ 'Viewpager'
DirectionalViewPager
ไม่ได้รับการปรับปรุงมาระยะหนึ่งแล้วจึงขาดคุณสมบัติใหม่บางอย่างViewPager
ในไลบรารีการสนับสนุน setPageMargin(int)
กล่าวคือ โดยทั่วไปควรจะทำงานแม้ว่า และหากไม่เป็นเช่นนั้นก็ไม่ยุ่งยากเกินกว่าที่จะคว้าซอร์สโค้ดมาViewPager
และสลับออกทั้งหมด x / y และตรรกะความกว้าง / ความสูง
DirectionalViewPager
แต่อย่างที่ MH บอกไว้ว่ามันไม่ได้รับการปรับปรุง (นักพัฒนาของมันพิจารณาว่าเป็นไม่ถูกต้อง) !! ไม่น่าเชื่อว่านักพัฒนา Android ไม่ได้ให้แนวตั้งแก่ชุมชนViewPager
แต่มีเพียงขอบเขตอันไกลโพ้น ฉันใหม่สำหรับ Android พัฒนาการViewPager
เปลี่ยนแนวตั้งx / y ไม่ใช่เรื่องง่ายสำหรับฉัน .. ฉันต้องการโซลูชันที่มีอยู่แล้ว .. ขอบคุณขอบคุณ
เพียงแค่ปรับปรุงคำตอบจาก@Brettและ@ Salman666เพื่อแปลงพิกัด (X, Y) เป็น (Y, X) อย่างถูกต้องเนื่องจากการแสดงอุปกรณ์เป็นรูปสี่เหลี่ยมผืนผ้า:
...
/**
* 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;
}
...
อย่างไรก็ตามบางสิ่งยังคงต้องทำเพื่อให้ตอบสนองหน้าจอสัมผัสได้ดีขึ้น ปัญหาอาจเกี่ยวข้องกับสิ่งที่ @msdark แสดงความคิดเห็นในคำตอบของ @ Salman666
true
ในonInterceptTouchEvent
และฉันได้เปลี่ยนไปด้วยปุ่มลัดเพื่อให้ใช้ DPAD มันเป็นต้นเหตุเลื่อนขึ้น / ลงแทนซ้าย / ขวา: 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);
}
}
มีจริงแล้วหนึ่งในแหล่งที่มาของ Android ฉันได้ปรับเปลี่ยนให้ทำงานได้ดีขึ้นแม้ว่า:
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);
}
}
พื้นที่เก็บข้อมูลขณะใช้งานมากขึ้นเป็นlsjwzh / RecyclerViewPager
RecyclerView
นี่คือการปรับใช้ ViewPager ที่เลื่อนได้ในแนวตั้งทำงานได้ดีกับ RecyclerView และ ListView guochong / VerticalViewPager
ใช้ ViewPager.PageTransformer เพื่อทำให้ ViewPager เลื่อนในแนวตั้งและให้ ViewOnTouchListener เพื่อจัดการกับความขัดแย้งในการเลื่อน
/**
* 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;
}
แม้ฉันกำลังเผชิญปัญหาเดียวกันกับการทำให้ ViewPager เป็นแนวตั้งโดยการสลับ X และ Y มันไม่ราบรื่นเลย
นั่นเป็นเพราะมันใช้งานได้เฉพาะเมื่อมุมการปัดน้อยกว่า 7.125 องศา = arctan (1/8) ในขณะที่การสกัดกั้นและ 14 องศา = arctan (1/4) ในขณะที่สัมผัส ตามต้นฉบับ ViewPager แนวนอนหนึ่งทำงานเมื่อมุมของการปัดน้อยกว่า 26.565 องศา = arctan (1/2) ในขณะที่ตัดและ 45 องศา = arctan (1) ในขณะที่สัมผัส
นั่นเป็นเหตุผลที่ฉันคัดลอกรหัสของ Android support-core-ui และย้ายค่าไปยังตัวแปรซึ่งฉันคูณด้วยการสะท้อนกลับ
โปรดค้นหารหัสและ README ได้ที่https://github.com/deepakmishra/verticalviewpager และ VerticalViewPager ที่https://github.com/deepakmishra/verticalviewpager/blob/master/app/src/main/java/com/viewpager/VerticalViewPager .java
วิธีที่ดีกว่าคือการหมุนตัวรับชมเพจ 90 องศาและใช้ข้อ จำกัด เค้าโครงเพื่อปรับตำแหน่ง
ฉันลงเอยด้วยการสร้างDirectionalViewPagerใหม่ที่สามารถเลื่อนได้ทั้งแนวตั้งหรือแนวนอนเพราะโซลูชันทั้งหมดที่ฉันเห็นที่นี่มีข้อบกพร่อง:
การใช้งาน VerticalViewPager ที่มีอยู่ (โดย castorflex และ LambergaR)
เคล็ดลับการแปลงกับการแลกเปลี่ยนประสานงาน
VelocityTracker.computeCurrentVelocity
ก็ยังคำนวณความเร็วด้วยแกน X ซึ่งอาจเป็นเพราะการใช้การโทรภายในนั้นไม่สนใจการแลกเปลี่ยนพิกัดดูการหมุน