底部導(dǎo)航欄我選擇用FragmentTabHost+Fragment來實現(xiàn),這個方法比較好用,代碼量也不多
首先是開始的activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
< RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android" xmlns:tools = "http://schemas.android.com/tools" android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = "${relativePackage}.${activityClass}" > < FrameLayout android:id = "@+id/main_view" android:layout_width = "match_parent" android:layout_height = "match_parent" android:layout_above = "@+id/main_tab" android:layout_alignParentLeft = "true" android:layout_alignParentTop = "true" > </ FrameLayout > < view android:id = "@+id/main_tab" android:layout_width = "match_parent" android:layout_height = "50dp" android:layout_alignParentBottom = "true" android:layout_alignParentLeft = "true" class = "android.support.v4.app.FragmentTabHost" /> </ RelativeLayout > |
也可以直接在xml文件里面寫
1
2
|
< android.support.v4.view.FragmentTabHost > </ android.support.v4.view.FragmentTabHost > |
這xml文件就一個view加一個tab view用來顯示碎片,tab用來放置底部按鈕的數(shù)量
再來是tab_foot.xml
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" android:layout_width = "match_parent" android:layout_height = "match_parent" android:background = "#F6F6F6" android:gravity = "center" android:orientation = "vertical" > < ImageView android:id = "@+id/foot_iv" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:src = "@drawable/home1" /> < TextView android:id = "@+id/foot_tv" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_marginTop = "3dp" android:text = "首頁" android:textColor = "@color/tab_color" /> </ LinearLayout > |
這是每個底部按鈕的布局設(shè)置的xml文件
再來是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
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
|
package com.gjn.mynavigation; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTabHost; import android.view.LayoutInflater; import android.view.View; import android.view.Window; import android.widget.ImageView; import android.widget.TabWidget; import android.widget.TextView; import android.widget.TabHost.OnTabChangeListener; import android.widget.TabHost.TabSpec; public class MainActivity extends FragmentActivity implements OnTabChangeListener { private FragmentTabHost mTabHost; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); //初始化FragmentTabHost initHost(); //初始化底部導(dǎo)航欄 initTab(); //默認(rèn)選中 mTabHost.onTabChanged(TabDb.getTabsTxt()[ 0 ]); } private void initTab() { String[] tabs = TabDb.getTabsTxt(); for ( int i = 0 ; i < tabs.length; i++) { //新建TabSpec TabSpec tabSpec = mTabHost.newTabSpec(TabDb.getTabsTxt()[i]); //設(shè)置view View view = LayoutInflater.from( this ).inflate(R.layout.tabs_foot, null ); ((TextView) view.findViewById(R.id.foot_tv)).setText(TabDb.getTabsTxt()[i]); ((ImageView) view.findViewById(R.id.foot_iv)).setImageResource(TabDb.getTabsImg()[i]); tabSpec.setIndicator(view); //加入TabSpec mTabHost.addTab(tabSpec,TabDb.getFramgent()[i], null ); } } /*** * 初始化Host */ private void initHost() { mTabHost = (FragmentTabHost) findViewById(R.id.main_tab); //調(diào)用setup方法 設(shè)置view mTabHost.setup( this , getSupportFragmentManager(),R.id.main_view); //去除分割線 mTabHost.getTabWidget().setDividerDrawable( null ); //監(jiān)聽事件 mTabHost.setOnTabChangedListener( this ); } @Override public void onTabChanged(String arg0) { //從分割線中獲得多少個切換界面 TabWidget tabw = mTabHost.getTabWidget(); for ( int i = 0 ; i < tabw.getChildCount(); i++) { View v = tabw.getChildAt(i); TextView tv = (TextView) v.findViewById(R.id.foot_tv); ImageView iv = (ImageView) v.findViewById(R.id.foot_iv); //修改當(dāng)前的界面按鈕顏色圖片 if (i == mTabHost.getCurrentTab()) { tv.setTextColor(getResources().getColor(R.color.tab_light_color)); iv.setImageResource(TabDb.getTabsImgLight()[i]); } else { tv.setTextColor(getResources().getColor(R.color.tab_color)); iv.setImageResource(TabDb.getTabsImg()[i]); } } } } |
其中TabDb類是用來設(shè)置導(dǎo)航欄的數(shù)據(jù)和圖片切換時候的資源
以下是TabDb類
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
|
package com.gjn.mynavigation; public class TabDb { /*** * 獲得底部所有項 */ public static String[] getTabsTxt() { String[] tabs = { "首頁" , "交易" , "地點" , "我的" }; return tabs; } /*** * 獲得所有碎片 */ public static Class[] getFramgent(){ Class[] cls = {OneFm. class ,TwoFm. class ,ThreeFm. class ,FourFm. class }; return cls ; } /*** * 獲得所有點擊前的圖片 */ public static int [] getTabsImg(){ int [] img = {R.drawable.home1,R.drawable.glod1,R.drawable.xc1,R.drawable.user1}; return img ; } /*** * 獲得所有點擊后的圖片 */ public static int [] getTabsImgLight(){ int [] img = {R.drawable.home2,R.drawable.glod2,R.drawable.xc2,R.drawable.user2}; return img ; } } |
到此,底部導(dǎo)航欄就算是完全實現(xiàn)了。
現(xiàn)在來實現(xiàn)頂部導(dǎo)航欄,看了許多最后使用了RadioGroup+ViewPager來實現(xiàn)
首先是為第一個碎片設(shè)計一個xml布局:fm_one.xml
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
|
<? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" > < HorizontalScrollView android:id = "@+id/one_hv" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:scrollbars = "none" > < RadioGroup android:id = "@+id/one_rg" android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "horizontal" > </ RadioGroup > </ HorizontalScrollView > < view android:id = "@+id/one_view" android:layout_width = "match_parent" android:layout_height = "0dp" android:layout_weight = "1" class = "android.support.v4.view.ViewPager" /> </ LinearLayout > |
設(shè)置頂部導(dǎo)航欄和顯示view
之后是導(dǎo)航欄的每個項的布局
tab_rb.xml
1
2
3
4
5
6
7
8
9
10
11
12
|
<? xml version = "1.0" encoding = "utf-8" ?> < RadioButton xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:background = "@drawable/tab_rb_selector" android:button = "@null" android:paddingBottom = "10dp" android:paddingLeft = "15dp" android:paddingRight = "15dp" android:paddingTop = "10dp" android:text = "今日" > </ RadioButton > |
其中設(shè)置selector文件來控制點擊和未點擊的狀態(tài)
tab_rb_selector.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<? xml version = "1.0" encoding = "utf-8" ?> < selector xmlns:android = "http://schemas.android.com/apk/res/android" > <!-- 點擊 --> < item android:state_checked = "true" > < layer-list > < item > < shape android:shape = "rectangle" > < stroke android:width = "5dp" android:color = "@color/tab_light_color" /> </ shape > </ item > < item android:bottom = "5dp" > < shape android:shape = "rectangle" > < solid android:color = "#fff" /> </ shape > </ item > </ layer-list > </ item > <!-- 默認(rèn) --> < item > < shape > < solid android:color = "#fafafa" /> </ shape > </ item > </ selector > |
設(shè)置了點擊和默認(rèn)的時候的顯示狀態(tài)
最后來實現(xiàn)OneFm類
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
package com.gjn.mynavigation; import java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.HorizontalScrollView; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.RadioGroup.LayoutParams; import android.widget.RadioGroup.OnCheckedChangeListener; public class OneFm extends Fragment implements OnPageChangeListener { private View view; private RadioGroup rg_; private ViewPager vp_; private HorizontalScrollView hv_; private List<Fragment> newsList = new ArrayList<Fragment>(); private OneFmAdapter adapter; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { if (view == null ) { //初始化view view = inflater.inflate(R.layout.fm_one, container, false ); rg_ = (RadioGroup) view.findViewById(R.id.one_rg); vp_ = (ViewPager) view.findViewById(R.id.one_view); hv_ = (HorizontalScrollView) view.findViewById(R.id.one_hv); //設(shè)置RadioGroup點擊事件 rg_.setOnCheckedChangeListener( new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int id) { vp_.setCurrentItem(id); } } //初始化頂部導(dǎo)航欄 initTab(inflater); //初始化viewpager initView(); } /** * 底部導(dǎo)航欄切換后 由于沒有銷毀頂部設(shè)置導(dǎo)致如果沒有重新設(shè)置view * 導(dǎo)致底部切換后切回頂部頁面數(shù)據(jù)會消失等bug * 以下設(shè)置每次重新創(chuàng)建view即可 */ ViewGroup parent = (ViewGroup) view.getParent(); if (parent != null ) { parent.removeView(view); } return view; } /*** * 初始化viewpager */ private void initView() { List<HTab> hTabs = HTabDb.getSelected(); for ( int i = 0 ; i < hTabs.size(); i++) { OneFm1 fm1 = new OneFm1(); Bundle bundle = new Bundle(); bundle.putString( "name" , hTabs.get(i).getName()); fm1.setArguments(bundle); newsList.add(fm1); } //設(shè)置viewpager適配器 adapter = new OneFmAdapter(getActivity().getSupportFragmentManager(),newsList); vp_.setAdapter(adapter); //兩個viewpager切換不重新加載 vp_.setOffscreenPageLimit( 2 ); //設(shè)置默認(rèn) vp_.setCurrentItem( 0 ); //設(shè)置viewpager監(jiān)聽事件 vp_.setOnPageChangeListener( this ); } /*** * 初始化頭部導(dǎo)航欄 * @param inflater */ private void initTab(LayoutInflater inflater) { List<HTab> hTabs = HTabDb.getSelected(); for ( int i = 0 ; i < hTabs.size(); i++) { //設(shè)置頭部項布局初始化數(shù)據(jù) RadioButton rbButton = (RadioButton) inflater.inflate(R.layout.tab_rb, null ); rbButton.setId(i); rbButton.setText(hTabs.get(i).getName()); LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); //加入RadioGroup rg_.addView(rbButton,params); } //默認(rèn)點擊 rg_.check( 0 ); } @Override public void onPageScrollStateChanged( int arg0) { } @Override public void onPageScrolled( int arg0, float arg1, int arg2) { } @Override public void onPageSelected( int id) { setTab(id); } /*** * 頁面跳轉(zhuǎn)切換頭部偏移設(shè)置 * @param id */ private void setTab( int id) { RadioButton rbButton = (RadioButton) rg_.getChildAt(id); //設(shè)置標(biāo)題被點擊 rbButton.setChecked( true ); //偏移設(shè)置 int left = rbButton.getLeft(); int width = rbButton.getMeasuredWidth(); DisplayMetrics metrics = new DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics); int screenWidth = metrics.widthPixels; //移動距離= 左邊的位置 + button寬度的一半 - 屏幕寬度的一半 int len = left + width / 2 - screenWidth / 2 ; //移動 hv_.smoothScrollTo(len, 0 ); } } |
其中有兩個數(shù)據(jù)類和一個碎片類
數(shù)據(jù)類
HTab.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package com.gjn.mynavigation; /*** * 頭部Tab屬性 * */ public class HTab { private String name; public HTab(String name) { super (); this .setName(name); } public String getName() { return name; } public void setName(String name) { this .name = name; } } |
HTabDb.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package com.gjn.mynavigation; import java.util.ArrayList; import java.util.List; public class HTabDb { private static final List<HTab> Selected = new ArrayList<HTab>(); static { Selected.add( new HTab( "今日" )); Selected.add( new HTab( "頭條" )); Selected.add( new HTab( "娛樂" )); Selected.add( new HTab( "財經(jīng)" )); Selected.add( new HTab( "軍事" )); Selected.add( new HTab( "科技" )); Selected.add( new HTab( "時尚" )); Selected.add( new HTab( "體育" )); } /*** * 獲得頭部tab的所有項 */ public static List<HTab> getSelected() { return Selected; } } |
碎片類
OneFm1.java
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
|
package com.gjn.mynavigation; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class OneFm1 extends Fragment { private String name; @Override public void setArguments(Bundle args) { name = args.getString( "name" ); } @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment, container, false ); ((TextView) view.findViewById(R.id.fm_text)).setText(name); return view; } } |
這樣就把頂部的導(dǎo)航欄加入到了第一個fragment里面并且實現(xiàn)了切換功能
最后把fragment.xml貼下,就是每個碎片最默認(rèn)的顯示頁面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "match_parent" android:layout_height = "match_parent" android:gravity = "center" android:orientation = "vertical" > < TextView android:id = "@+id/fm_text" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Large Text" android:textAppearance = "?android:attr/textAppearanceLarge" /> </ LinearLayout > |
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.csdn.net/son_king/article/details/80783500