android 中怎么关掉viewpage的滑动效果

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 中怎么关掉viewpage的滑动效果相关的知识,希望对你有一定的参考价值。

参考技术A 首先,要使用该控件就需要添加designlibrary,在androidstudio(还没有使用Androidstudio的小伙伴们要赶紧更换啦)中添加依赖compile‘com.android.support:design:22.2.0’然后再布局文件中使用TabLayout12345紧接着在下面添加ViewPager12345布局文件完成了,接下来去定义ViewPager中的适配器,这里我使用的是Fragment,所以继承自FragmentPagerAdapter,代码如下:publicclassMyPageAdapterextendsFragmentPagerAdapterArrayListdatas;ArrayListtitles;publicCommunityPageAdapter(FragmentManagerfm)super(fm);publicvoidsetData(ArrayListdatas)this.datas=datas;publicvoidsetTitles(ArrayListtitles)this.titles=titles;@OverridepublicFragmentgetItem(intposition)returndatas==null?null:datas.get(position);@OverridepublicintgetCount()returndatas==null?0:datas.size();@OverridepublicCharSequencegetPageTitle(intposition)returntitles==null?null:titles.get(position);12345678910111213141516171819202122232425262728293031适配器中需要两个数据集合,分配填充Fragment和显示的标题。然后在需要使用的页面添加如下代码:MyPageAdaptermyPageAdapter=newMyPageAdapter(getFragmentManager());ArrayListdatas=newArrayList();datas.add(newAFragment());datas.add(newBFragment());datas.add(newCFragment());myPageAdapter.setData(datas);ArrayListtitles=newArrayList();titles.add("A");titles.add("B");titles.add("C");myPageAdapter.setTitles(titles);12345678910111213现在适配器和数据已经准备好了,那么接下来就是要把数据放入ViewPager中,并使ViewPager和TabLayout相关联:TabLayouttabLayout=(TabLayout)findViewById(R.id.tablayout);ViewPagerviewPager=(ViewPager)findViewById(R.id.view_pager);//将适配器设置进ViewPagerviewPager.setAdapter(myPageAdapter);//将ViewPager与TabLayout相关联tabLayout.setupWithViewPager(viewPager);123456关联之后运行发现,其实ViewPager由于预加载机制,导致每次都会提前加载下一个页面,如果页面的数据量大,那么这将会占用大量的内存,有什么法可以只加载当前显示的页面呢看通过查找相关资料发现,有一个方法setOffscreenPageLimit(int),该方法的作用是设置提前加载页面的数量,尝试使用viewPager.setOffscreenPageLimit(0);后发现无效。继续查阅资料后发现,原来这是由于ViewPager的机制导致的,最少需要预加载一个页面,Requestedoffscreenpagelimit0toosmall;defaultingto1,相关问题链接:发现了可以完美解决该问题的方法:在Fragment中有一个方法,setUserVisibleHint,该方法可以获取当前页面的展示情况@OverridepublicvoidsetUserVisibleHint(booleanisVisibleToUser)super.setUserVisibleHint(isVisibleToUser);if(isVisibleToUser)//页面正在展示,在这里加载你的数据else//页面没有展示12345678910基本到这一步功能已经实现了,但是,还有一些细节需要注意,到底ViewPager滑动的时候为什么会造成TabLayout的标题也随之更换呢看原来setupWithViewPager被调用的时候,执行了下面的代码viewPager.addOnPageChangeListener(newTabLayout.TabLayoutOnPageChangeListener(this));this.setOnTabSelectedListener(newTabLayout.ViewPagerOnTabSelectedListener(viewPager));到最后,还有一个问题,那么就是如果我们的标题有多条,导致超出了TabLayout的显示范围,这该如何解决呢看很简单,查阅官方API发现,TabLayout有一个方法是setTabMode,它是用来设置TabLayout的展示模式,而这个方法接受两个常量,MODE_SCROLLABLE以及MODE_FIXED,显而易见,当我们设置为MODE_SCROLLABLE它就能自动根据标题的数量,滑动展示啦,功能到这里就完美实现了!本回答被提问者采纳

Android 中 DrawerLayout + ViewPager 怎么解决滑动冲突?

DrawerLayout 是 Android 官方的侧滑菜单控件,而 ViewPager 相信大家都很熟悉了。今天这里就讲一下当在 DrawerLayout 中嵌套 ViewPager 时,要如何解决滑动冲突的问题,效果如下:

首先,让我们先来解决 DrawerLayout 和 ViewPager 的侧滑事件冲突。当 DrawerLayout 中嵌套 ViewPager 时,侧滑默认是执行 DrawerLayout 的侧滑事件,因为 Android 的事件分发是从 外层 ViewGroup 向里逐级传递到 View 的。

所以会先执行 DrawerLayout 的 onTouchEvent 方法:

    @Override
    public boolean onTouchEvent(MotionEvent ev) 
        mLeftDragger.processTouchEvent(ev); 
        mRightDragger.processTouchEvent(ev); 
        final int action = ev.getAction(); boolean wantTouchEvents = true; 
        switch (action & MotionEventCompat.ACTION_MASK)  
            case MotionEvent.ACTION_DOWN:  
                final float x = ev.getX(); 
                final float y = ev.getY(); 
                mInitialMotionX = x; 
                mInitialMotionY = y; 
                mDisallowInterceptRequested = false; 
                mChildrenCanceledTouch = false; 
                break; 
             
            case MotionEvent.ACTION_UP:  
                final float x = ev.getX(); 
                final float y = ev.getY(); 
                boolean peekingOnly = true;
                final View touchedView = mLeftDragger.findTopChildUnder((int) x, (int) y); 
                if (touchedView != null && isContentView(touchedView))  
                    final float dx = x - mInitialMotionX; 
                    final float dy = y - mInitialMotionY; 
                    final int slop = mLeftDragger.getTouchSlop(); 
                    if (dx * dx + dy * dy < slop * slop)  
                        // Taps close a dimmed open drawer but only if it isn't locked open. 
                        final View openDrawer = findOpenDrawer(); 
                        if (openDrawer != null)  
                            peekingOnly = getDrawerLockMode(openDrawer) == LOCK_MODE_LOCKED_OPEN; 
                         
                     
                  
                closeDrawers(peekingOnly); 
                mDisallowInterceptRequested = false; 
                break; 
             
            case MotionEvent.ACTION_CANCEL:  
                closeDrawers(true); 
                mDisallowInterceptRequested = false;
                mChildrenCanceledTouch = false; break; 
             
         
        return wantTouchEvents;
    

可以看到在最后始终返回 wantTouchEvents,也就是返回 true,意味着点击事件在 DrawerLayout 就被消费掉了,无法传到 ViewPager。

所以,我们像下面这样,监听当 Drawer 打开时,将 DrawerLayout 设置为 LOCK_MODE_LOCKED_OPEN,这样在 Drawer 被打开时,就能够触发 ViewPager 的滑动事件了。

mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener()  
  @Override 
  public void onDrawerSlide(View drawerView, float slideOffset)  

   

  @Override 
  public void onDrawerOpened(View drawerView) 
    mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
   

  @Override public void onDrawerClosed(View drawerView) 
    mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); 
   

  @Override public void onDrawerStateChanged(int newState)  

  
);

但是,当侧边栏的 ViewPager 滑动到最后一页,再向左滑动时,我们会希望能够自然的关闭 Drawer。这就需要我们监听 ViewPager 的 PageChange 事件,当滑动到最后一页时,将 DrawerLayout 的 LockMode 设置回 LOCK_MODE_UNLOCKED。

这里,选择在 DrawerFragment(也就是定义侧边栏的 Fragment) 中定义一个接口:

/** 
* 监听侧边栏的页面选择。 
*/
public interface OnDrawerPageChangeListener  
  void onPageSelected(boolean isLast);

然后让 MainActivity 实现这个接口:

@Override
public void onPageSelected(boolean isLast)  
  if (isLast)  
    mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
   else if (mDrawerLayout.getDrawerLockMode(GravityCompat.START) == DrawerLayout.LOCK_MODE_UNLOCKED) 
    mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN); 
  

再在 DrawerFragment 中 ViewPager 的 PageChange 事件中使用:

final OnDrawerPageChangeListener drawerPageChangeListener = (OnDrawerPageChangeListener) getActivity();
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()  
  @Override 
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) 

   
  @Override 
  public void onPageSelected(int position)  
    if (position == fragmentList.size() - 1)  
      drawerPageChangeListener.onPageSelected(true); 
     else  
      drawerPageChangeListener.onPageSelected(false); 
     
   
  @Override 
  public void onPageScrollStateChanged(int state)  

  
);

这样我们就解决了 DrawerLayout 和 ViewPager 的侧滑事件冲突问题,剩下最后一个要处理的小问题就是在点击空白区域时,也想要关闭侧边栏,这个就只需要:

// 点击除开侧边栏的区域会收起侧边栏。
mDrawerLayout.setOnTouchListener(new View.OnTouchListener()  
  @Override 
  public boolean onTouch(View v, MotionEvent event)  
    switch (event.getAction())  
      case MotionEvent.ACTION_DOWN: 
        mDrawerLayout.closeDrawers();
        break;
     
    return false; 
  
);

到这里就大功告成啦!

作者:Hevin - 极光开发者

原文:Android 中 DrawerLayout + ViewPager 怎么解决滑动冲突?

知乎专栏:极光日报

以上是关于android 中怎么关掉viewpage的滑动效果的主要内容,如果未能解决你的问题,请参考以下文章

android viewpager滑动与slidingpanelayout冲突怎么解决

Android 联合ViewPager 与 Fragment

Android 中 DrawerLayout + ViewPager 怎么解决滑动冲突?

tablayout+viewpager怎么设置取消滑动

Android ViewPager 控制滑动速度

android怎么实现页面的左右滑动