现在市面上很多下方是导航条,上方是Fragment的App,这样布局的好处是让MainActivity从复杂的逻辑中抽取出来,在Fragment中做切换
实现这种UI效果,可以使用GOOGLE的BottomNavigationBar,gitHub的下载地址:https://github.com/Ashok-Varma/
BottomNavigation; 而在这里 ,我写了一个万能框架,来放置底部的导航栏
首先MainActivity的布局文件:
<?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="#f9f9fc"
android:orientation="vertical">
<FrameLayout
android:id="@+id/main_fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<RelativeLayout
android:paddingTop="12px"
android:background="@drawable/menu_bg"
android:id="@+id/main_bottome_switcher_container"
android:layout_width="match_parent"
android:layout_height="98px">
<RelativeLayout
android:id="@+id/fl_bottom_news"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:paddingLeft="60px">
<ImageView
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/selector_mainbottom_news" />
<TextView
android:textSize="22px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="8px"
android:layout_marginLeft="60px"
android:text="信息"
android:textColor="@color/main_bottom_tv_color" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/fl_bottom_notice"
android:layout_toRightOf="@id/fl_bottom_news"
android:paddingLeft="50px"
android:paddingRight="50px"
android:layout_width="wrap_content"
android:layout_height="match_parent"
>
<ImageView
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/selector_mainbottom_action" />
<TextView
android:layout_marginBottom="8px"
android:textSize="22px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:gravity="center"
android:text="公告"
android:textColor="@color/main_bottom_tv_color" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/fl_bottom_work"
android:layout_toRightOf="@id/fl_bottom_notice"
android:paddingLeft="50px"
android:paddingRight="43px"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/selector_mainbottom_work"/>
<TextView
android:layout_marginBottom="8px"
android:textSize="22px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:gravity="center"
android:text="工作"
android:textColor="@color/main_bottom_tv_color" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/fl_bottom_phonelist"
android:layout_toRightOf="@id/fl_bottom_work"
android:paddingLeft="43px"
android:paddingRight="43px"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/selector_mainbottom_phonelist"/>
<TextView
android:layout_marginBottom="8px"
android:textSize="22px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:gravity="center"
android:text="联系人"
android:textColor="@color/main_bottom_tv_color" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/fl_bottom_user"
android:layout_toRightOf="@id/fl_bottom_phonelist"
android:layout_width="match_parent"
android:paddingLeft="43px"
android:layout_height="match_parent">
<ImageView
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/selector_mainbottom_me"/>
<TextView
android:layout_marginBottom="8px"
android:textSize="22px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:text="我的"
android:textColor="@color/main_bottom_tv_color" />
</RelativeLayout>
</RelativeLayout>
</LinearLayout>
有朋友好奇 我这里的布局怎么使用的px进行适配,具体 可以看我上篇文章"使用AutoLayout用px写布局完成安卓下的适配"
上方是一个FrameLayout,用于放置Fragment,而下方导航条使用RelativeLayout,中间包裹很多子控件RelativeLayout
MainActivity中的代码:
package com.hanzheng.znxl;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import com.hanzheng.znxl.base.BaseActivity;
import com.hanzheng.znxl.base.BaseFragment;
import com.hanzheng.znxl.factory.FragmentFactory;
import java.util.ArrayList;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
public class MainActivity extends BaseActivity {
@Bind(R.id.main_fragment_container)
FrameLayout mMainFragmentContainer;
@Bind(R.id.main_bottome_switcher_container)
RelativeLayout mMainBottomeSwitcherContainer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
init();
setListener();
}
private List<BaseFragment> fragments = new ArrayList<>();
private void init() {
onClickListener.onClick(mMainBottomeSwitcherContainer.getChildAt(0));
}
private View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
int index = mMainBottomeSwitcherContainer.indexOfChild(view);
changeUi(index);
changeFragment(index);
}
};
private void setListener() {
int childCount = mMainBottomeSwitcherContainer.getChildCount();
for (int i = 0; i < childCount; i++) {
RelativeLayout childVIew = (RelativeLayout) mMainBottomeSwitcherContainer.getChildAt(i);
childVIew.setOnClickListener(onClickListener);
}
}
private void changeFragment(int index) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.hide(FragmentFactory.createFragment(0));
ft.hide(FragmentFactory.createFragment(1));
ft.hide(FragmentFactory.createFragment(2));
ft.hide(FragmentFactory.createFragment(3));
ft.hide(FragmentFactory.createFragment(4));
BaseFragment fragment = FragmentFactory.createFragment(index);
if(!fragment.isAdded()) {
ft.add(R.id.main_fragment_container,fragment,"" + index);
}
ft.show(fragment);
ft.commit();
}
private void changeUi(int index) {
int childCount = mMainBottomeSwitcherContainer.getChildCount();
for (int i = 0; i < childCount; i++) {
if (i == index) {
//每个控件都要切换状态
setEnable(mMainBottomeSwitcherContainer.getChildAt(i), false);
} else {
setEnable(mMainBottomeSwitcherContainer.getChildAt(i), true);
}
}
}
private void setEnable(View item, boolean b) {
item.setEnabled(b);
if (item instanceof ViewGroup) {
int childCount = ((ViewGroup) item).getChildCount();
for (int i = 0; i < childCount; i++) {
setEnable(((ViewGroup) item).getChildAt(i), b);
}
}
}
}
注释写的很少,这里解释下,
默认选中导航条中的第一个元素, 导航条中元素的点击事件 改变自身UI,并且做Fragment的Hide和show操作 ;changeUi方法中setEnable()方法使用到了递归操作,目的是把导航条下的元素 布局 全部设置状态
而这里替换的Fragment使用到了工厂设计模式,具体代码:
package com.hanzheng.znxl.factory;
import com.hanzheng.znxl.base.BaseFragment;
import com.hanzheng.znxl.fragment.ActionFragment;
import com.hanzheng.znxl.fragment.MeFragment;
import com.hanzheng.znxl.fragment.MessageFragment;
import com.hanzheng.znxl.fragment.PhoneListFragment;
import com.hanzheng.znxl.fragment.WorkFragment;
/**
* Created by zmybi on 29/12/2016.
*/
public class FragmentFactory {
private static MessageFragment sMessageFragment;
private static ActionFragment sActionFragment;
private static WorkFragment sWorkFragment;
private static PhoneListFragment sPhoneListFragment;
private static MeFragment sMeFragment;
private static MessageFragment getMessageFragment(){
if (sMessageFragment==null){
sMessageFragment = new MessageFragment();
}
return sMessageFragment;
}
private static ActionFragment getActionFragment(){
if (sActionFragment==null){
sActionFragment = new ActionFragment();
}
return sActionFragment;
}
private static WorkFragment getWorkFragment(){
if (sWorkFragment==null){
sWorkFragment = new WorkFragment();
}
return sWorkFragment;
}
private static PhoneListFragment getPhoneListFragment(){
if (sPhoneListFragment==null){
sPhoneListFragment = new PhoneListFragment();
}
return sPhoneListFragment;
}
private static MeFragment getMeFragment(){
if (sMeFragment==null){
sMeFragment = new MeFragment();
}
return sMeFragment;
}
public static BaseFragment createFragment(int index){
switch (index){
case 0:
return getMessageFragment();
case 1:
return getActionFragment();
case 2:
return getWorkFragment();
case 3:
return getPhoneListFragment();
case 4:
return getMessageFragment();
}
return null;
}
}
至此:一个简单的上方是Fragment下方是导航条的UI框架搭建完成了,当后期UI改变的时候,只需要更改XML文件中的布局即可,不需要关系具体的代码逻辑