我需要在“照片和视频”标签中使用相同的片段,并且仍然有三个标签。 我在viewpager中有两个片段,在tablayout中有3个制表符。我希望实现viewpager改变效果,如instagram。我做了什么: 我在下面创建了自定义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();
}
}
当当前项目是适配器中的最后一项时,它将通知向右滑动(这需要您在照片选项卡中并且想要通过滑动进入视频选项卡)。 在活动中,我设置了这样的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();
}
一切都还可以,但是当您在图库标签中并且想要转到视频标签时,您无法通过点击视频标签来完成。当您单击视频选项卡时,它会生成活动的照片选项卡,然后如果您再单击视频选项卡,它将激活视频选项卡。也可以通过滑动工作来改变照片选项卡和视频选项卡。 我需要在点击视频标签时实现它必须转到视频标签而不是像现在这样的照片标签。
另见视频: https://youtu.be/tbT7mzkmydQ
答案 0 :(得分:4)
据我了解,您需要在“照片和视频”标签中使用相同的片段,并且仍然有三个标签。
从照片滑动到视频标签 - 在第三个标签中添加空白片段,在寻呼机适配器中将其宽度保持为零。从照片滑动到视频选项卡时,照片片段将继续显示。
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));
...
}
将空白标签的宽度设置为0
public class SectionsPagerAdapter extends FragmentPagerAdapter {
...
@Override
public float getPageWidth(int position) {
if (position == 2) {
return 0;
}
return super.getPageWidth(position);
}
}
从视频向照片选项卡滑动 - 增加“视频”标签的投射距离,以便在照片标签处停止滑动。将fling距离重置为其他选项卡的默认值。您需要Java Reflection API才能使fling距离字段可访问,因为它是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) {}
});
视频链接:https://imgur.com/a/wA3e0
这是一个快速而又肮脏的解决方案。您可能需要对其进行微调。