[英]Viewpager inside Viewpager Scroll Issue
在我的主要活動中,我有一個水平 viewpager。 在viewpager 的一個片段中,我有另一個垂直viewpager。 兩者都工作正常。 但是對於水平 viewpager,我需要從屏幕邊緣滾動。 但我希望它可以從屏幕的任何地方滾動。
我的水平 viewpager 設置:
viewPager = (ViewPager) findViewById(R.id.viewpager);
adapterViewPager = new HorizontalViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapterViewPager);
viewPager.setCurrentItem(1);
水平 viewpager 適配器:
public class HorizontalViewPagerAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 3;
public HorizontalViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return MoreFragment.newInstance("Fragment MoreFragment", "HA HA HA");
case 1:
return NewsFragment.newInstance("Fragment 1", "HA HA HA");
case 2:
return WebViewFragment.newInstance("Fragment Webview", "HA HA HA");
default:
return null;
}
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public CharSequence getPageTitle(int position) {
return "Tab " + position;
}
}
在我的新聞片段中,我有另一個 viewpager。
viewPager = view.findViewById(R.id.shortpager);
adapterViewPager = new VerticalPagerAdapter(getActivity().getSupportFragmentManager(), newsList);
viewPager.setAdapter(adapterViewPager);
我的垂直 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() {
// 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);
}
/**
* 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));
}
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/top page
view.setAlpha(1);
ViewCompat.setElevation(view, 1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
view.setTranslationY(0);
//set Y position to swipe in from top
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else if (position <= 1) { // [0,1]
view.setAlpha(1);
ViewCompat.setElevation(view, 2);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
view.setTranslationY(position * view.getHeight());
// Scale the page down (between MIN_SCALE and 1)
view.setScaleX(1);
view.setScaleY(1);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
}
垂直取景器適配器:
public class VerticalPagerAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 3;
private final ArrayList<News> newsList;
public VerticalPagerAdapter(FragmentManager fm, ArrayList<News> newsList) {
super(fm);
this.newsList = newsList;
}
@Override
public Fragment getItem(int position) {
return ShortFragment.newInstance("Fragment 1", "HA HA HA", newsList.get(position));
}
@Override
public int getCount() {
return this.newsList.size();
}
@Override
public CharSequence getPageTitle(int position) {
return "Tab " + position;
}
}
垂直 viewpager 平滑滾動。 目前對於水平 viewpager,我必須從屏幕邊緣滾動。 但我需要讓它像垂直滾動一樣從屏幕的任何地方滾動。
您的代碼問題是您的VerticalViewPager
如果你注意到代碼,
@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;
}
第 1 步,用交換的手勢調用 super。
第 2 步,使用當前手勢在垂直視圖尋呼機上執行操作。
如果您特別看到評論, // return touch coordinates to original reference frame for any child views
這清楚地表明手勢首先被子// return touch coordinates to original reference frame for any child views
使用。
因此,在您的垂直視圖尋呼機中,由於您正在交換手勢,因此即使在將其傳遞給父級之前,它也會消耗 Horizontal Gesture。 這就是為什么您的水平視圖尋呼機沒有得到手勢的原因。
如果您正在使用具有任何沖突手勢實現(如 ScrollView、Lists、RecyclerView、ViewPager 等)的 Vertical View Pager,請使用以下鏈接中的那個。 它已被棄用,但適用於所有手勢沖突視圖。
我遇到了這個問題,我通過將 viewpager 包裝在 Scrollview 中解決了它
<ScrollView
android:id="@+id/nested_scroll"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:nestedScrollingEnabled="false"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.