Android ViewPager像instagram照片活动

Axb*_*rov 2 android android-viewpager

我需要对“照片和视频”选项卡使用相同的片段,但仍然有三个选项卡。我在viewpager中有两个片段,在tablayout中有3个选项卡。我想实现像instagram这样的viewpager更改效果。我所做的:我在下面创建了自定义viewpager:

public class SwipableViewPager extends ViewPager {
    private float downX;
    private float downY;
    private float mStartDragX;
    private float upX;
    private float upY;
    private boolean dragDisabled;

    private SwipeListener mListener;

    public void setSwipeListener(SwipeListener listener) {
        mListener = listener;
    }

    public SwipableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        float x = ev.getX();
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = ev.getX();
                downY = ev.getY();
                mStartDragX = x;
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                upX = ev.getX();
                upY = ev.getY();

                float deltaX = downX - upX;
                if(deltaX>-getWidth() && deltaX< -getWidth()/4 && getCurrentItem() == getAdapter().getCount() - 1){
                    mListener.setPageAndEnableDrag();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (mStartDragX - 30 > x && getCurrentItem() == getAdapter().getCount() - 1) {
                    mListener.onSwipeOutAtEnd();
                }
                break;
        }
        if(dragDisabled) {
            return false;
        }
        else{
            return super.onInterceptTouchEvent(ev);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if(dragDisabled) return false;
        return super.onTouchEvent(ev);
    }

    public void disableDrag(boolean disabled) {
        dragDisabled = disabled;
    }



    public interface SwipeListener {
        void setPageAndEnableDrag();
        void onSwipeOutAtEnd();
    }
}
Run Code Online (Sandbox Code Playgroud)

当当前项目是适配器中的最后一个项目时,它将通知向右滑动(当您在“照片”选项卡中并且想要通过滑动进入“视频”选项卡时,需要这样做)。在活动中,我像这样设置viewpager:

private void setupViewPager() {
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(GalleryFragment.newInstance(), getResources().getString(R.string.gallery_toolbar_title));
        TakePhotoFragment fragment = new TakePhotoFragment();
        adapter.addFragment(fragment, getResources().getString(R.string.photo));
        viewPager.setAdapter(adapter);
        viewPager.setSwipeListener(this);
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {

                switch (tab.getPosition()){
                    case 1:  //selected photo tab
                        viewPager.setCurrentItem(1);
                        toolbar.setTitle(R.string.photo);
                        viewPager.disableDrag(false);    //switch on default swipe
                        break;
                    case 2: // selected video tab
                        toolbar.setTitle(R.string.video);
                        viewPager.disableDrag(true);    // switch off default swipe
                        break;
                    default: // selected gallery tab
                        viewPager.setCurrentItem(tab.getPosition());
                        toolbar.setTitle(R.string.gallery_toolbar_title);
                        viewPager.disableDrag(false);    //switch on default swipe
                        break;
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }

    @Override
    public void setPageAndEnableDrag() {
        tabLayout.getTabAt(1).select();
        viewPager.disableDrag(false);
    }
    public void setPagerEnabledDrag(boolean enabled) {
        viewPager.disableDrag(!enabled);
    }
    @Override
    public void onSwipeOutAtEnd() {
        viewPager.disableDrag(true);
        tabLayout.getTabAt(2).select();
    }
Run Code Online (Sandbox Code Playgroud)

一切正常,但是当您在“画廊”选项卡中并且想要进入“视频”选项卡时,无法通过单击“视频”选项卡来完成此操作。当您首先单击“视频”选项卡时,它将变为活动的“照片”选项卡,然后,如果您再次单击“视频”选项卡,则它将变为活动的视频选项卡。通过丑陋的工作,也可以从“照片”选项卡和“视频”选项卡更改。我需要实现,当单击“视频”选项卡时,它必须转到“视频”选项卡而不是像现在这样的“照片”选项卡。

在此处输入图片说明

另请参见视频:https : //youtu.be/tbT7mzkmydQ

  1. 为什么我只有两个片段,却有三个标签?因为只能在一个活动中创建一个Camera对象,所以我必须对照片和视频选项卡使用一个片段。
  2. 为什么我要处理拖延?当用户转到第三个选项卡时,我必须禁用viewpager的默认滑动效果(如果不这样做,则从“第三”选项卡滑动到第二个viewpager时,将转到第一个选项卡)
  3. 我不想要无限的viewpager。
  4. 我不想简单地从右(第三个)片段到左(第一个)片段。

请观看视频: 我的活动视频

ran*_*dom 5

据我了解,您需要对“照片和视频”标签使用相同的片段,但仍然需要三个标签。

从照片滑动到视频选项卡 -在第三个选项卡上添加空白片段,以使其在寻呼机适配器中的宽度保持为零。从照片滑动到视频选项卡时,照片片段将继续显示。

private void setupViewPager(){
        SectionsPagerAdapter adapter =  new SectionsPagerAdapter(getSupportFragmentManager());

        adapter.addFragment(new GalleryFragment());
        adapter.addFragment(new PhotoFragment());
        adapter.addFragment(new Fragment()); //blank fragment

        mViewPager = (ViewPager) findViewById(R.id.viewpager_container);
        mViewPager.setAdapter(adapter);

        mTabLayout = (TabLayout) findViewById(R.id.tabsBottom);
        mTabLayout.setupWithViewPager(mViewPager);

        mTabLayout.getTabAt(0).setText(getString(R.string.gallery));
        mTabLayout.getTabAt(1).setText(getString(R.string.photo));
        mTabLayout.getTabAt(2).setText(getString(R.string.video));
        ...
    }
Run Code Online (Sandbox Code Playgroud)

将空白标签的宽度设置为0

public class SectionsPagerAdapter extends FragmentPagerAdapter {
        ...
        @Override
        public float getPageWidth(int position) {
            if (position == 2) {
                return 0;
            }
            return super.getPageWidth(position);
        }
    }
Run Code Online (Sandbox Code Playgroud)

从视频滑动到“照片”选项卡 -增加“视频”选项卡的拖动距离,以便在“照片”选项卡处停止滑动。将其他标签的弹射距离重置为默认值。您将需要Java Reflection API才能使飞行距离字段可访问,因为它是ViewPager.class

final float density = getResources().getDisplayMetrics().density;
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        Field mFlingDistance;
        try {
            mFlingDistance = ViewPager.class.getDeclaredField("mFlingDistance");
            mFlingDistance.setAccessible(true);
            switch (tab.getPosition()){
                case 2: mFlingDistance.set(mViewPager, (int)(200 * density));
                        break;
                default: mFlingDistance.set(mViewPager, (int)(25 * density));
                         break;
            }
         } catch (NoSuchFieldException e) {
             e.printStackTrace();
         } catch (IllegalAccessException e) {
             e.printStackTrace();
         }
     }

     @Override
     public void onTabUnselected(TabLayout.Tab tab) {}

     @Override
     public void onTabReselected(TabLayout.Tab tab) {}
 });
Run Code Online (Sandbox Code Playgroud)

链接到视频:https : //imgur.com/a/wA3e0

这是一个方向上的快速解决方案。您可能需要对其进行微调。