Android

횡스크롤 안되는 FragmentViewPager + 하단 네비게이션

그란. 2017. 11. 9. 13:49




하단에 있는 네비게이션뷰와 FragmentViewPager 결합 및 생성방법


개념 : 

1. MainActivity 에서 ViewPager 공간을 만든 후 ViewPager의 한 페이지 마다  Fragment 를 보여지게 함


   MainActivity -> FragmentHome [0]

 FragmentTruck  [1]

 FragmentOther  [2]




2. 기본 ViewPager 는 Swipe 가 가능하다 -> Swipe 안되는 ViewPager로 Custom

3. FragmentPagerAdapter 사용




1.  ViewPager 상속받은 CustomViewPager 생성


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class NonSwipeableViewPager extends ViewPager{
    public NonSwipeableViewPager(Context context) {
        super(context);
        setMyScroller();
    }
 
    public NonSwipeableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        setMyScroller();
    }
 
    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return false;
    }
 
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return false;
    }
 
    private void setMyScroller() {
        try {
            Class<?> viewpager = ViewPager.class;
            Field scroller = viewpager.getDeclaredField("mScroller");
            scroller.setAccessible(true);
            scroller.set(thisnew MyScroller(getContext()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public class MyScroller extends Scroller {
        public MyScroller(Context context) {
            super(context, new DecelerateInterpolator());
        }
 
        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);
        }
    }
}
cs




2.  FragmentPagerAdapter 상속받은 ViewPagerAdapter 생성


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
 
    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }
    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }
 
    @Override
    public int getCount() {
        return mFragmentList.size();
    }
 
    public void addFragment(Fragment fragment) {
        mFragmentList.add(fragment);
    }
 
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        //super.destroyItem(container, position, object);
    }
}
cs

destroyItem 을 주석처리 : 한번 생성된 뷰를 프레그먼트 이동할때 마다 지우지 않고 계속 보여지게 한다


3. MainActivity 의 레이아웃 설정 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">
 
 
    <com.example.a0b.move2dinerforuser.NonSwipeableViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_above="@+id/bottomNavi"
        android:layout_alignParentTop="true"
        />
 
    <android.support.design.widget.BottomNavigationView
        android:id="@+id/bottomNavi"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="?android:attr/windowBackground"
        app:menu="@menu/bottom_nav"
        />
 
</RelativeLayout>
cs

NonSwipeableViewPager 라고 입력하고 자동으로 View 이름이 나타남 (위에서 ViewPager 를 Custom 했기 때문)




4. res -> menu 폴더에 bottom_nav.xml 작성


1
2
3
4
5
6
7
8
9
10
11
12
13
14
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/btm_home"
        android:icon="@drawable/icon_home"
        android:title="새 소식"/>
    <item
        android:id="@+id/btm_search"
        android:icon="@drawable/icon_truck"
        android:title="트럭 찾기!"/>
    <item
        android:id="@+id/btm_others"
        android:icon="@drawable/icon_others"
        android:title="더 보기"/>
</menu>
cs



5. MainActivity 인터페이스 상속 및 선언 


1
2
3
4
5
6
7
public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener, BottomNavigationView.OnNavigationItemSelectedListener
 
 
private NonSwipeableViewPager viewPager;
private BottomNavigationView bottomNavigationView;
private MenuItem prevMenuItem;
cs




1
NavigationView.OnNavigationItemSelectedListener, BottomNavigationView.OnNavigationItemSelectedListener
cs

* Tip *  MainActivity 의 필수 메소드 오버라이딩 방법

=> Alt + 엔터








자동 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.btm_home) {
        viewPager.setCurrentItem(0);
    } else if (id == R.id.btm_search) {
        viewPager.setCurrentItem(1);
    } else if (id == R.id.btm_others) {
        viewPager.setCurrentItem(2);
    } else {
 
    }
    return false;
}
cs




6. MainActivity 바인딩 , 이벤트 연결


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
viewPager = (NonSwipeableViewPager) findViewById(R.id.viewPager);
bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottomNavi);
bottomNavigationView.setOnNavigationItemSelectedListener(this);
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
 
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(FragmentHome.newInstance());
adapter.addFragment(FragmentSearchTruck.newInstance());
adapter.addFragment(FragmentOthers.newInstance());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }
 
    @Override
    public void onPageSelected(int position) {
        if (prevMenuItem != null) {
            prevMenuItem.setChecked(false);
        } else {
            bottomNavigationView.getMenu().getItem(0).setChecked(false);
        }
        bottomNavigationView.getMenu().getItem(position).setChecked(true);
        prevMenuItem = bottomNavigationView.getMenu().getItem(position);
    }
 
    @Override
    public void onPageScrollStateChanged(int state) {
 
    }
});
cs





7. 각 Fragment마다 newInstance() 메소드를 static 으로 생성


1
2
3
4
5
6
7
8
9
10
public static FragmentHome newInstance() {
    return new FragmentHome();
}
 
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
 
public static FragmentOthers newInstance()
{
    return new FragmentOthers();
}
cs