Fork me on GitHub

BottomNavigationView+ViewPager+Fragment---实现双导航栏

效果图

原理

  1. 底部导航栏使用BottomNavigationView + 自定义的ViewPager
  2. 底部导航栏使用BottomNavigationView + ViewPager

底部导航栏实现

简单的BottomNavigationView使用

  1. 布局文件

    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
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.example.bibingwei.view.view.NoScrollViewPager
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"/>

    <android.support.design.widget.BottomNavigationView
    android:id="@+id/navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?android:attr/windowBackground"
    app:menu="@menu/navigation" />

    </LinearLayout>
  2. 菜单文件

    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
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
    android:id="@+id/navigation_reading"
    android:icon="@drawable/reading"
    android:orderInCategory="0"
    android:title="@string/title_reading"/>

    <item
    android:id="@+id/navigation_luck"
    android:icon="@drawable/luck"
    android:orderInCategory="1"
    android:title="@string/title_luck"/>

    <item
    android:id="@+id/navigation_music"
    android:icon="@drawable/music"
    android:orderInCategory="2"
    android:title="@string/title_music"/>

    <item
    android:id="@+id/navigation_video"
    android:icon="@drawable/video"
    android:orderInCategory="3"
    android:title="@string/title_video"/>
    </menu>

自定义ViewPager

注意拦截事件和事件处理事件返回false,这样就避免冲突(事件分发机制)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class NoScrollViewPager extends ViewPager{


public NoScrollViewPager(@NonNull Context context) {
super(context);
}

public NoScrollViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
return false;
}
}

Activity实现

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
public class MainActivity extends AppCompatActivity {

private ViewPager mViewPager;
private Fragment readingFragment,luckFragment,musicFragment,videoFragment;
private BottomNavigationView navigation;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mViewPager = findViewById(R.id.fragment_container);
mViewPager.addOnPageChangeListener(mOnPageChangeListener);
navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
readingFragment = reading_fragment.newInstance();
luckFragment = luck_fragment.newInstance();
musicFragment = music_fragment.newInstance();
videoFragment = video_fragment.newInstance();
}

@Override
protected void onResume() {
super.onResume();
mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
return readingFragment;
case 1:
return luckFragment;
case 2:
return musicFragment;
case 3:
return videoFragment;
default:
}
return null;
}

@Override
public int getCount() {
return 4;
}


});
//防止频繁的销毁视图
mViewPager.setOffscreenPageLimit(4);
}

private ViewPager.OnPageChangeListener mOnPageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {
navigation.getMenu().getItem(position).setChecked(true);
}

@Override
public void onPageScrollStateChanged(int state) {

}

};

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
mViewPager.setCurrentItem(item.getOrder());
return true;
}
};
}

顶部导航栏实现

布局文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".fragments.reading_fragment">

<android.support.design.widget.BottomNavigationView
android:id="@+id/reading_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:menu="@menu/reading_navigation" />

<android.support.v4.view.ViewPager
android:id="@+id/reading_viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />

</LinearLayout>

菜单文件

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
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item
android:id="@+id/navigation_zhihu"
android:textSize="16sp"
android:textColor="#fff"
android:orderInCategory="0"
android:icon="@drawable/point1"
android:title="@string/zhihu"/>

<item
android:id="@+id/navigation_android"
android:textSize="16sp"
android:textColor="#fff"
android:icon="@drawable/point2"
android:orderInCategory="1"
android:title="@string/android"/>

<item
android:id="@+id/navigation_IOS"
android:textSize="16sp"
android:textColor="#fff"
android:orderInCategory="2"
android:icon="@drawable/point3"
android:title="@string/ios"/>

<item
android:id="@+id/navigation_front"
android:textSize="16sp"
android:textColor="#fff"
android:orderInCategory="3"
android:icon="@drawable/point4"
android:title="@string/front"/>

<item
android:id="@+id/navigation_joker"
android:textSize="16sp"
android:textColor="#fff"
android:orderInCategory="4"
android:icon="@drawable/point5"
android:title="@string/joker"/>
</menu>

Fragment实现

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
public class reading_fragment extends Fragment {

private ViewPager readingViewPager;
private Fragment zhihuFragment,androidFragment,iosFragment,frontFragment,jokerFragment;
private BottomNavigationView mBottomNavigationView;

public static reading_fragment newInstance() {

Bundle args = new Bundle();

reading_fragment fragment = new reading_fragment();
fragment.setArguments(args);
return fragment;
}

public reading_fragment() {
// Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_reading, container, false);
readingViewPager = view.findViewById(R.id.reading_viewPager);
readingViewPager.addOnPageChangeListener(mOnPageChangeListener);
mBottomNavigationView = view.findViewById(R.id.reading_container);
mBottomNavigationView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
zhihuFragment = zhihu_fragment.newInstance();
androidFragment = android_fragment.newInstance();
iosFragment = ios_fragment.newInstance();
frontFragment = front_fragment.newInstance();
jokerFragment = joker_fragment.newInstance();
return view;
}

@Override
public void onStart() {
super.onStart();
readingViewPager.setAdapter(new FragmentStatePagerAdapter(getChildFragmentManager()) {
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
return zhihuFragment;
case 1:
return androidFragment;
case 2:
return iosFragment;
case 3:
return frontFragment;
case 4:
return jokerFragment;
default:
}
return null;
}

@Override
public int getCount() {
return 5;
}
});
readingViewPager.setOffscreenPageLimit(5);
}

private ViewPager.OnPageChangeListener mOnPageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {
mBottomNavigationView.getMenu().getItem(position).setChecked(true);
}

@Override
public void onPageScrollStateChanged(int state) {

}

};

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
readingViewPager.setCurrentItem(item.getOrder());
return true;
}
};
}

参考

https://tomoya92.github.io/2017/04/05/android-bottomnavigationview-viewpager-fragment/
https://www.jianshu.com/p/2c51ac813eee