android Realizes Bottom Navigation Bar

  • 2021-09-12 02:04:11
  • OfStack

Bottom navigation bar I choose to use FragmentTabHost + Fragment to achieve, this method is easier to use, code is not much

The first is the starting 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> 

You can also write directly in the xml file


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


This xml file is one view plus one tab view to display fragments, tab to place the number of buttons at the bottom

Then there is 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=" Home page " 
 android:textColor="@color/tab_color" /> 
 
</LinearLayout> 

This is the xml file for the layout settings of each bottom button

Then there is the code of 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); 
 
 // Initialization FragmentTabHost 
 initHost(); 
 // Initialize the bottom navigation bar  
 initTab(); 
 // Select by default  
 mTabHost.onTabChanged(TabDb.getTabsTxt()[0]); 
 } 
 
 private void initTab() { 
 String[] tabs = TabDb.getTabsTxt(); 
 for (int i = 0; i < tabs.length; i++) { 
  // New TabSpec 
  TabSpec tabSpec = mTabHost.newTabSpec(TabDb.getTabsTxt()[i]); 
  // Settings 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); 
  // Join TabSpec 
  mTabHost.addTab(tabSpec,TabDb.getFramgent()[i],null); 
 } 
 } 
 /*** 
 *  Initialization Host 
 */ 
 private void initHost() { 
 mTabHost = (FragmentTabHost) findViewById(R.id.main_tab); 
 // Call setup Method   Settings view 
 mTabHost.setup(this, getSupportFragmentManager(),R.id.main_view); 
 // Remove the dividing line  
 mTabHost.getTabWidget().setDividerDrawable(null); 
 // Monitor events  
 mTabHost.setOnTabChangedListener(this); 
 } 
 
 @Override 
 public void onTabChanged(String arg0) { 
 // How many switching interfaces are obtained from the dividing line  
 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); 
  // Modify the current interface button color picture  
  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]); 
  } 
 } 
 } 
} 

Among them, TabDb class is used to set the data of navigation bar and the resource when the picture is switched
The following are the TabDb classes


package com.gjn.mynavigation; 
 
public class TabDb { 
 /*** 
 *  Get all items at the bottom  
 */ 
 public static String[] getTabsTxt() { 
 String[] tabs = {" Home page "," Transaction "," Location "," Mine "}; 
 return tabs; 
 } 
 /*** 
 *  Get all fragments  
 */ 
 public static Class[] getFramgent(){ 
 Class[] cls = {OneFm.class,TwoFm.class,ThreeFm.class,FourFm.class}; 
 return cls ; 
 } 
 /*** 
 *  Get all the pictures before clicking  
 */ 
 public static int[] getTabsImg(){ 
 int[] img = {R.drawable.home1,R.drawable.glod1,R.drawable.xc1,R.drawable.user1}; 
 return img ; 
 } 
 /*** 
 *  Get all clicked pictures  
 */ 
 public static int[] getTabsImgLight(){ 
 int[] img = {R.drawable.home2,R.drawable.glod2,R.drawable.xc2,R.drawable.user2}; 
 return img ; 
 } 
} 

At this point, the bottom navigation bar is completely realized.

Now to implement the top navigation bar, see a lot of the final use of RadioGroup+ViewPager to achieve
The first is to design an xml layout for the first fragment: 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> 

Set the top navigation bar and display view
This is followed by the layout of each item in the navigation bar

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=" Today " > 
</RadioButton> 

In which the selector file is set to control the clicked and unclicked status

tab_rb_selector.xml


<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" > 
 <!--  Click  --> 
 <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> 
 <!--  Default  --> 
 <item > 
 <shape > 
  <solid android:color="#fafafa"/> 
 </shape> 
 </item> 
</selector> 

Set the display status when clicking and default
Finally, the OneFm class is implemented


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) { 
  // Initialization 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); 
  // Settings RadioGroup Click event  
  rg_.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
 
  @Override 
  public void onCheckedChanged(RadioGroup group, int id) { 
   vp_.setCurrentItem(id); 
  } 
  } 
  // Initialize the top navigation bar  
  initTab(inflater); 
  // Initialization viewpager 
  initView(); 
 } 
 /**
 *  After the bottom navigation bar is switched,   Because the top setting has not been destroyed, if it is not reset, view 
 *  Cause the bottom to switch back to the top page data will disappear, etc. bug 
 *  The following settings are recreated each time view You can  
 */ 
 ViewGroup parent = (ViewGroup) view.getParent(); 
 if (parent != null) { 
  parent.removeView(view); 
 } 
 return view; 
 } 
 /*** 
 *  Initialization 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); 
 } 
 // Settings viewpager Adapter  
 adapter = new OneFmAdapter(getActivity().getSupportFragmentManager(),newsList); 
 vp_.setAdapter(adapter); 
 // Two viewpager Switch No Reload  
 vp_.setOffscreenPageLimit(2); 
 // Set the default  
 vp_.setCurrentItem(0); 
 // Settings viewpager Monitor events  
 vp_.setOnPageChangeListener(this); 
 } 
 /*** 
 *  Initialize the header navigation bar  
 * @param inflater 
 */ 
 private void initTab(LayoutInflater inflater) { 
 List<HTab> hTabs = HTabDb.getSelected(); 
 for (int i = 0; i < hTabs.size(); i++) { 
  // Setting header item layout initialization data  
  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); 
  // Join RadioGroup 
  rg_.addView(rbButton,params); 
 } 
 // Default click  
 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); 
 } 
 /*** 
 *  Page jump toggle header offset setting  
 * @param id 
 */ 
 private void setTab(int id) { 
 RadioButton rbButton = (RadioButton) rg_.getChildAt(id); 
 // Set the title to be clicked  
 rbButton.setChecked(true); 
 // Offset setting  
 int left = rbButton.getLeft(); 
 int width = rbButton.getMeasuredWidth(); 
 DisplayMetrics metrics = new DisplayMetrics(); 
 getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics); 
 int screenWidth = metrics.widthPixels; 
 // Moving distance =  The position on the left  + button Width of 1 Half  -  Of the screen width 1 Half  
 int len = left + width / 2 - screenWidth / 2; 
 // Moving  
 hv_.smoothScrollTo(len, 0); 
 } 
} 

There are two data classes and one fragment class

Data class

HTab.java


package com.gjn.mynavigation; 
 
/*** 
 *  Head Tab Attribute  
 * 
 */ 
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


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


0

Fragments
OneFm1.java


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


1

In this way, the top navigation bar is added to the first fragment and the switching function is realized
Finally, paste fragment. xml, which is the most default display page for each fragment


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


2

Related articles: