溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

android實現(xiàn)底部導(dǎo)航欄的方法

發(fā)布時間:2021-04-17 09:55:14 來源:億速云 閱讀:155 作者:小新 欄目:移動開發(fā)

這篇文章給大家分享的是有關(guān)android實現(xiàn)底部導(dǎo)航欄的方法的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

底部導(dǎo)航欄我選擇用FragmentTabHost+Fragment來實現(xiàn),這個方法比較好用,代碼量也不多

首先是開始的activity_main.xml

<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文件里面寫

<android.support.v4.view.FragmentTabHost > 
</android.support.v4.view.FragmentTabHost>

這xml文件就一個view加一個tab  view用來顯示碎片,tab用來放置底部按鈕的數(shù)量

再來是tab_foot.xml

<?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的代碼

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(); 
 //默認選中 
 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類

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

<?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

<?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

<?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> 
 <!-- 默認 --> 
 <item > 
 <shape > 
  <solid android:color="#fafafa"/> 
 </shape> 
 </item> 
</selector>

 設(shè)置了點擊和默認的時候的顯示狀態(tài)
最后來實現(xiàn)OneFm類

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è)置默認 
 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); 
 } 
 //默認點擊 
 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

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

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

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貼下,就是每個碎片最默認的顯示頁面

<?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>

感謝各位的閱讀!關(guān)于“android實現(xiàn)底部導(dǎo)航欄的方法”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI