2017-11-24 5 views
1

사진 및 비디오 탭에 동일한 조각을 사용해야하지만 탭이 3 개 있습니다. 뷰 파인더에 두 개의 조각이 있고 tablayout에 세 개의 탭이 있습니다. 나는 인스 타 그램처럼 뷰 파인더 변경 효과를 얻고 싶다. 내가 무슨 짓을했는지 : 나는 아래의 사용자 정의 viewpager를 만들어 :Android 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(); 
    } 

다 좋아,하지만 당신은 갤러리 탭에있을 때 당신은 비디오 탭으로 이동하려는 경우, 당신은 비디오 탭을 클릭하여 수행 할 수 없습니다. 비디오 탭을 클릭하면 활성 사진 탭이 생기고 그 다음에 비디오 탭을 클릭하면 활성 비디오 탭이 나타납니다. 또한 사진 탭과 비디오 탭에서 일하는 것을 못 생기게 변경합니다. 비디오 탭을 클릭 할 때 비디오 탭으로 가야 할 때가 있습니다. 지금처럼 사진 탭이 아닙니다.

enter image description here

도 참조 비디오 : https://youtu.be/tbT7mzkmydQ

  1. 왜이 두 조각뿐 아니라 세 개의 탭? 카메라 객체는 하나의 액티비티에 하나만 만들 수 있으므로 사진 및 비디오 탭에 하나의 조각을 사용해야하는 이유는 무엇입니까?
  2. 왜 드래그를 해제해야합니까? 사용자가 세 번째 탭으로 이동하면 viewpager의 기본 스 와이프 효과를 비활성화해야합니다 (그렇게하지 않으면 thrid 탭에서 두 번째 viewpager로 스 와이프하여 첫 번째 탭으로 이동할 때)
  3. 나는 무한하고 싶지 않습니다. 뷰 페이지.
  4. 오른쪽 (세 번째) 단편부터 왼쪽 (첫 번째) 단편에 이르기를 원하지 않습니다.

해결 비디오 참조하십시오 Video of my activity in action

+1

나는 당신의 문제에 대해 희미한 생각을하고 있습니다. "첫 번째", "두 번째"및 "세 번째"만 사용하여 ** 전체 질문 **을 편집하면 도움이됩니다. 나는 아직도 이해하지 못한다. 하나의 카메라 조각에서 다른 카메라 조각으로 갈 때 어떤 일이 일어나기를 원합니 까? 물론 탭이 바뀌어야하지만 호출기에 슬라이딩 애니메이션이 있어야합니까? 무엇 사이? 아니면 아무 일도 일어나지 않으시겠습니까? 또한, 당신은 왜 훔쳐서 엉망이됩니까? 오히려 어댑터를 다뤄야하지 않습니까? 구현을 보여 주시겠습니까? 또한 단 두 조각 만 가지고 있다면 처음에는 세 개의 탭을 어떻게 얻습니까? – kalabalik

+0

비디오 탭을 클릭하면 사진 탭으로 이동합니다. 두 번째 클릭 후 비디오 탭으로 이동합니다. 인스 타 그램을 사용하신 적이 있습니까? –

+0

달성하고자하는 것을 비디오로 게시 할 수 있습니까? – abhiank

답변

3

당신이 달성하고자하는 것을 철저하고 명확입니다. 왜 두 개의 단편 만 있고 세 개의 단편은 있습니까? 왜 스 와이퍼를 구현 하는가 (스 와이프 또는 페이징은 기본적으로 뷰 페이지에 내장된다). 왜 드래그를 해제해야합니까? 이것이 뷰어 페이지의 기능일까요? 아니면 당신 조각 중 하나의 특징일까요? (후자에서는 그 조각으로 남겨 두어야합니다.)

무한 뷰 페이지를 원하고있는 것 같습니다 (맨 오른쪽 부분의 왼쪽 (!)으로 스 와이프). 이 올바른지? 또는 오른쪽 (세 번째) 단편에서 왼쪽 단편 (첫 번째 단편)으로 이동하기를 원하십니까? ViewPagerTabLayout의 간단한 구현으로 이렇게 할 수 있습니다. 페이지 (조각)를 스 와이프/페이징 할 수 있으며 (세 번째 조각부터 첫 번째 조각으로 전환하기 위해 두 번 스 와이프) 탭을 클릭 할 수 있습니다 (동일한 스위치를 수행 할 때 한 번 클릭하십시오.).

조각의 순서는 어디에도 정의되어 있지 않으므로 "비디오"또는 "갤러리"는 말하지 말고 첫 번째와 두 번째 (가능하면 세 번째) 조각을 말하십시오.

설명을 명확히하기 위해 표준보기 페이지 - 탭 레이아웃 - 툴바 설정으로 활동을 게시합니다. 스 와이프 감지가 필요하지 않습니다.

public class MainActivity extends AppCompatActivity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     final ArrayList<Fragment> fragments = new ArrayList<>(); 
     // make sure to instantiate and add all your fragments 
     // your fragments will probably be of different types 
     fragments.add(YourFragment.newInstance("Gallery")); 
     fragments.add(YourFragment.newInstance("Video")); 
     fragments.add(YourFragment.newInstance("Photo")); 

     final Toolbar toolbar = findViewById(R.id.toolbar); 

     final ViewPager viewPager = findViewById(R.id.viewpager); 
     FragmentPagerAdapter adapter = new FragmentPagerAdapter(getSupportFragmentManager()) { 
      @Override 
      public int getCount() { 
       return fragments.size(); 
      } 

      @Override 
      public Fragment getItem(int position) { 
       return fragments.get(position); 
      } 

      public CharSequence getPageTitle(int position) { 
       return ((YourFragment) fragments.get(position)).getTitle(); 
      } 

     }; 
     viewPager.setAdapter(adapter); 

     TabLayout tabLayout = findViewById(R.id.sliding_tabs); 
     tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 
      @Override 
      public void onTabSelected(TabLayout.Tab tab) { 
       // tab.getPosition() returns index for viewPager.setCurrentItem() 
       viewPager.setCurrentItem(tab.getPosition()); 
       toolbar.setTitle(((YourFragment) fragments.get(tab.getPosition())).getTitle()); 
      } 

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

      @Override 
      public void onTabReselected(TabLayout.Tab tab) { 
      } 
     }); 
     tabLayout.setupWithViewPager(viewPager); 
    } 

    // make your fragments implement this interface 
    interface FragmentTitle { 
     CharSequence getTitle(); 
    } 
} 
+0

내 질문을 업데이트했습니다. 봐봐. –

4

필자는 사진 및 비디오 탭에 대해 동일한 조각을 사용해야하지만 여전히 세 개의 탭이 있어야 함을 알고 있습니다.

사진에서 비디오 탭으로 스 와이프 - 페이저 어댑터에서 너비를 0으로 유지하면서 빈 조각을 세 번째 탭에 추가하십시오. 사진 조각을 비디오 탭으로 스 와이프하면 사진 조각이 계속 표시됩니다. 그 슬쩍이 사진 탭에서 정지 있도록 비디오 탭에 대한 증가 날뛰는 거리 - 사진 탭 비디오 와이프 0

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

에 빈 탭의

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)); 
     ... 
    } 

설정 폭입니다. 다른 탭의 fling 거리를 기본값으로 재설정하십시오. https://imgur.com/a/wA3e0

이 방향으로 빠른 - 및 - 더러운 솔루션입니다 : 그것은 비디오 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) {} 
}); 

링크에서 개인 필드가 같이 날뛰는 거리 필드에 액세스 할 수 있도록하기 위해 자바 리플렉션 API가 필요합니다. 그것을 미세 조정해야 할 수도 있습니다.

+0

예, 당신이 옳았음을 이해했습니다! 나는 당신의 솔루션이 잘 보이는지 테스트하고있다. –

+0

내가 고칠 수없는 한 가지는 : 비디오에서 사진으로 탭을 변경하려고 할 때 매우 빠르게 변경됩니다. 이 문제를 어떻게 해결할 수 있습니까? flingDistance를 2000 * 밀도로 변경하려고 시도했지만 작동하지 않습니다 ... –

+0

fling을 다음과 같이 올바르게 설정했는지 테스트했습니다. int flingDist = (int) mFlingDistance.get (viewPager); Log.v ("fling", ""+ flingDist); 동영상 탭으로 전환 할 때 출력 : fling : 6000 및 다른 탭 : fling : 75 –