简体   繁体   English

嵌套在 ViewPager 中的 ViewPager

[英]ViewPager nested in ViewPager

I'm really newbie in android and I would appreciate any help for my course work.我真的是 android 的新手,如果我的课程工作有任何帮助,我将不胜感激。

I need to do:我需要去做:

1) two ViewPagers (not nested) in one Activity 1) 一个 Activity 中有两个 ViewPagers(非嵌套)

2) two ViewPagers (one ViewPager is nested in another ViewPager) 2)两个ViewPager(一个ViewPager嵌套在另一个ViewPager中)

I found similar question, but I could not use it.我发现了类似的问题,但我无法使用它。 ViewPager inside ViewPager ViewPager 里面的 ViewPager

I add first ViewPager and do not know what to do next我添加了第一个 ViewPager,不知道接下来要做什么

LayoutInflater inflater = LayoutInflater.from(this); //this - context of my activity
List<View> pages = new ArrayList<View>();
View page = inflater.inflate(R.layout.activity_main, null);
//next I adding some buttons on page
pages.add(page);

page = inflater.inflate(R.layout.activity_main2, null);  //my second page
//some buttons
pages.add(page);

page = inflater.inflate(R.layout.activity_main3, null);  //my third page
//some buttons
pages.add(page);

SamplePagerAdapter pagerAdapter = new SamplePagerAdapter(pages);
ViewPager viewPager = new ViewPager(this);
viewPager.setAdapter(pagerAdapter);
viewPager.setCurrentItem(0);          
setContentView(viewPager);

If I add ViewPager2 and say setContentView(viewPager2), I lost my viewPager1.如果我添加 ViewPager2 并说 setContentView(viewPager2),我就丢失了 viewPager1。 I spent a lot of time for this two questions, please, some help...这两个问题我花了很多时间,请帮助...

//This is my sketch what I need to do. //这是我需要做的草图。 Sorry, I can't attach my scetches...对不起,我不能附上我的 scetches...

I added an OnTouchListener to the interior ViewPager :我添加了一个OnTouchListener到内部ViewPager

private OnTouchListener mSuppressInterceptListener = new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(
                event.getAction() == MotionEvent.ACTION_DOWN &&
                v instanceof ViewGroup
        ) {
                ((ViewGroup) v).requestDisallowInterceptTouchEvent(true);
        }
        return false;
    }
};

This just detects ACTION_DOWN touch events on the inner ViewPager and prevents the outer one from intercepting it.这只是检测内部ViewPager上的 ACTION_DOWN 触摸事件并防止外部拦截它。 Because it returns false, only the ACTION_DOWN event should be hit;因为它返回 false,所以应该只命中 ACTION_DOWN 事件; all the other events will be ignored.所有其他事件将被忽略。 You can add this listener to every element you want to "protect" from the outer ViewPager 's scrolling, though obviously if you want to pick up any other touch behaviour on those elements you'll need to deal with them inside the touch listener and possibly implement a better listener.您可以将此侦听器添加到要“保护”外部ViewPager滚动的每个元素,但显然,如果您想在这些元素上获取任何其他触摸行为,则需要在触摸侦听器中处理它们,并且可能实现更好的侦听器。

I think you should reconsider having a viewpager inside another viewpager.我认为您应该重新考虑在另一个 viewpager 中放置一个 viewpager。 You will have a lot of problems with the touch events plus the user experience might be confusing/tricky, I suggest you to rethink that one.您会遇到很多触摸事件的问题,而且用户体验可能会令人困惑/棘手,我建议您重新考虑这一点。

Now for question 1:现在是问题 1:

Declare both viewpagers in the xml file of the activity (/layout/activity.xml), for example:在活动的xml文件(/layout/activity.xml)中声明两个viewpagers,例如:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <android.support.v4.view.ViewPager
            android:id="@+id/viewpager1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    <android.support.v4.view.ViewPager
            android:id="@+id/viewpager2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

</LinearLayout>

Then inflate the xml on the onCreate method of your activity and wire both of the viewpagers:然后在您的活动的 onCreate 方法上膨胀 xml 并连接两个 viewpagers:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);

    mViewpager1 = (ViewPager) findViewById(R.id.viewpager1);
    mViewpager2 = (ViewPager) findViewById(R.id.viewpager2);
}

Don't forget to declare those two variables private ViewPager mViewpager1, mViewpager2;不要忘记将这两个变量声明为private ViewPager mViewpager1, mViewpager2;

Then you can do whatever you want with mViewpager1 and mViewpager2.然后你可以用 mViewpager1 和 mViewpager2 做任何你想做的事情。 One more tip, i suggest you to use adapters to set the pages instead of adding them manually one by one to each viewpager, it will be much cleaner and better to operate with.还有一个提示,我建议您使用适配器来设置页面,而不是手动将它们一个一个地添加到每个 viewpager 中,这样操作起来会更清晰、更好。

A solution about having a nested Viewpager and disabling the nested Viewpager swiping (if you want to set the selected pages with buttons in the nested)关于嵌套 Viewpager 和禁用嵌套 Viewpager 滑动的解决方案(如果您想在嵌套中设置带有按钮的选定页面)

For the nested You SubClass ViewPager and you add these:对于嵌套的 You SubClass ViewPager 并添加以下内容:

 public boolean onInterceptTouchEvent(MotionEvent event) {
        //if you want to send the Touches to this Viewpager (the nested) //change true to false
      return true;    
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages on this inner 

        //send swipe to father instead of child
        if (this.getParent()!=null &&  this.getParent() instanceof ViewPager) {
            ((ViewPager) this.getParent()).onTouchEvent(event);
        }
        return false;
    }

In the Layouts you put this:在布局中你把这个:

<com.mypackage.mycustomapp.myviews.MyViewPager
            android:id="@+id/myNestedviewpager"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
  1. Use single viewPager with a ConcatAdapter使用单viewPager与ConcatAdapter
//sample usage
val strings = listOf("a", "b", "cde", "f", "g", "h")
viewPager.adapter = ConcatAdapter(
   strings.partition({ string -> string.length > 1 }, { string -> string.split("") })
     //{{a, b}, {c, d, e}, {f, g, h}}
      .map { StringAdapter(it) }.toList() 
)

/**
 * custom partition function as kotlin List extension
 */

fun <E> List<E>.partition(shouldFlatten: (e: E)->Boolean, flatten: (e: E)->List<E>) : List<List<E>>{
   val partitions = mutableListOf<List<E>>()
   var currentPartition = mutableListOf<E>()
   val listIterator = this.listIterator()
   while (listIterator.hasNext()) {
      val next = listIterator.next()
      if (shouldFlatten(next)) {
         if (currentPartition.isNotEmpty()) {
            partitions.add(currentPartition)
            currentPartition = mutableListOf()
         }
         partitions.add(flatten(next))
      } else {
         currentPartition.add(next)
      }
   }
   if (currentPartition.isNotEmpty()) {
      partitions.add(currentPartition)
   }
   return partitions
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM