本节开始我们会讲解一些 Fragment 在实际开发中的一些实例!而本节给大家讲解的是底部导航栏的实现!而基本的底部导航栏方法有很多种,比如全用 TextView 做,或者用 RadioButton,又或者使用 TabLayout + RadioButton,当然复杂的情况还是得走外层套布局的方法!本节我们用 TextView 来做一个底部导航栏的效果,也熟悉下 Fragment 的使用!
1.要实现的效果图以及工程目录结构
先看看效果图:
接着看看我们的工程的目录结构:
2.实现流程
Step 1:写下底部选项的一些资源文件
我们从图上可以看到,我们底部的每一项点击的时候都有不同的效果是吧!我们是通过是否 selected 来判定的!我们要写的资源文件有:首先是图片,然后是文字,接着是背景!
图片 Drawable 资源:tab_menu_channel.xml
 <?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@mipmap/tab_channel_pressed" android:state_selected="true" />    <item android:drawable="@mipmap/tab_channel_normal" /></selector>
   复制代码
 文字资源:tab_menu_text.xml
 <?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:color="@color/text_yellow" android:state_selected="true" />    <item android:color="@color/text_gray" /></selector>
   复制代码
 背景资源:tab_menu_bg.xml
 <?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_selected="true">        <shape>            <solid android:color="#FFC4C4C4" />        </shape>    </item>    <item>        <shape>            <solid android:color="@color/transparent" />        </shape>    </item></selector>
   复制代码
 Step 2:编写我们的 Activity 布局
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=".MainActivity">
    <RelativeLayout        android:id="@+id/ly_top_bar"        android:layout_width="match_parent"        android:layout_height="48dp"        android:background="@color/bg_topbar">
        <TextView            android:id="@+id/txt_topbar"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:layout_centerInParent="true"            android:gravity="center"            android:textSize="18sp"            android:textColor="@color/text_topbar"            android:text="信息"/>
        <View            android:layout_width="match_parent"            android:layout_height="2px"            android:background="@color/div_white"            android:layout_alignParentBottom="true"/>
    </RelativeLayout>
    <LinearLayout        android:id="@+id/ly_tab_bar"        android:layout_width="match_parent"        android:layout_height="56dp"        android:layout_alignParentBottom="true"        android:background="@color/bg_white"        android:orientation="horizontal">
        <TextView            android:id="@+id/txt_channel"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/tab_menu_bg"            android:drawablePadding="3dp"            android:drawableTop="@drawable/tab_menu_channel"            android:gravity="center"            android:padding="5dp"            android:text="@string/tab_menu_alert"            android:textColor="@drawable/tab_menu_text"            android:textSize="16sp" />
        <TextView            android:id="@+id/txt_message"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/tab_menu_bg"            android:drawablePadding="3dp"            android:drawableTop="@drawable/tab_menu_message"            android:gravity="center"            android:padding="5dp"            android:text="@string/tab_menu_profile"            android:textColor="@drawable/tab_menu_text"            android:textSize="16sp" />
        <TextView            android:id="@+id/txt_better"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/tab_menu_bg"            android:drawablePadding="3dp"            android:drawableTop="@drawable/tab_menu_better"            android:gravity="center"            android:padding="5dp"            android:text="@string/tab_menu_pay"            android:textColor="@drawable/tab_menu_text"            android:textSize="16sp" />
        <TextView            android:id="@+id/txt_setting"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/tab_menu_bg"            android:drawablePadding="3dp"            android:drawableTop="@drawable/tab_menu_setting"            android:gravity="center"            android:padding="5dp"            android:text="@string/tab_menu_setting"            android:textColor="@drawable/tab_menu_text"            android:textSize="16sp"/>
    </LinearLayout>
    <View        android:id="@+id/div_tab_bar"        android:layout_width="match_parent"        android:layout_height="2px"        android:background="@color/div_white"        android:layout_above="@id/ly_tab_bar"/>
    <FrameLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_below="@id/ly_top_bar"        android:layout_above="@id/div_tab_bar"        android:id="@+id/ly_content">
    </FrameLayout>
</RelativeLayout>
   复制代码
 代码解析:
 首先定义顶部标题栏的样式,48dp的LinearLayout中间加上一个TextView作为标题!接着定义一个大小为56dp的LinerLayout对其底部,在这个里面加入四个TextView,比例1:1:1:1, 并且设置相关属性,接着在这个LinearLayout上加一条线段!最后以标题栏和底部导航栏为边界,写一个FrameLayout,宽高match_parent,用做Fragment的容器!
   复制代码
 PS:这里四个 TextView 属性是重复的,你也可以自行抽取出来,编写一个 style,设置下
Step 3:隐藏顶部导航栏
意外发现以前的在 Activity 中调用 requestWindowFeature(Window.FEATURE_NO_TITLE);可以隐藏手机自带顶部导航栏,但是写 demo 时候发现会报错,即使这句话写在了 setContentView()之前!可能是因为继承的是 AppCompatActivity 而非 Activity 类!当然以前的 getSupportActionbar().hide()隐藏掉 Actionbar,但是他还是会在界面上!最后还有一种方法就是自己编写一个 style,然后在 AndroidManifest.xml 中为 Application 设置这个 Theme。
注:把 requestWindowFeature(Window.FEATURE_NO_TITLE);放在 super.onCreate(savedInstanceState);前面就可以隐藏 ActionBar 而不报错。
接着 AndroidManifest.xml 设置下 theme 属性:
 android:theme="@style/Theme.AppCompat.NoActionBar"
   复制代码
 Step 4:创建一个 Fragment 的简单布局与类:
fg_content.xml:
 <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical" android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@color/bg_white">        <TextView        android:id="@+id/txt_content"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:text="呵呵"        android:textColor="@color/text_yellow"        android:textSize="20sp"/>
</LinearLayout>
   复制代码
 MyFragment.java:
 /** * Created by Coder-pig on 2015/8/28 0028. */public class MyFragment extends Fragment {
    private String content;    public MyFragment(String content) {        this.content = content;    }
    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fg_content,container,false);        TextView txt_content = (TextView) view.findViewById(R.id.txt_content);        txt_content.setText(content);        return view;    }}
   复制代码
 代码解析:
就是简单的重写了一个 onCreateView()方法,其他方法可以按需重写!
Step 5:编写 MainActivity.java
先说说我们要考虑的一些关键问题:
- Fragment 什么时候初始化和 add 到容器中?什么时候 hide 和 show? 
- 如何让 TextView 被选中?选中一个 TextView 后,要做一些什么操作? 
- 刚进入 MainActivity 怎么样让一个 TextView 处于 Selected 的状态? 
嗯,接下来一一解答上面这些问题:
- 我们选中 TextView 后对对应的 Fragment 进行判空,如果为空,初始化,并添加到容器中;而 hide 的话,我们定义一个方法 hide 所有的 Fragment,每次触发点击事件就先调用这个 hideAll 方法,讲所有 Fragment 隐藏起来,然后如果 TextView 对应的 Fragment 不为空,我们就将这个 Fragment 显示出来; 
- 这个我们通过点击事件来实现,点击 TextView 后先重置所有 TextView 的选中状态为 false,然后设置点击的 TextView 的选中状态为 true; 
- 这个更简单,我们是通过点击事件来设置选中的,那么在 onCreate()方法里加个触发点击事件的方法不就可以了嘛~ txt_channel.performClick(); 
逻辑都弄懂了,直接上代码咯:
MainActivity.java:
 /** * Created by Coder-pig on 2015/8/28 0028. */public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    //UI Object    private TextView txt_topbar;    private TextView txt_channel;    private TextView txt_message;    private TextView txt_better;    private TextView txt_setting;    private FrameLayout ly_content;
    //Fragment Object    private MyFragment fg1,fg2,fg3,fg4;    private FragmentManager fManager;
    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);        fManager = getFragmentManager();        bindViews();        txt_channel.performClick();   //模拟一次点击,既进去后选择第一项    }
    //UI组件初始化与事件绑定    private void bindViews() {        txt_topbar = (TextView) findViewById(R.id.txt_topbar);        txt_channel = (TextView) findViewById(R.id.txt_channel);        txt_message = (TextView) findViewById(R.id.txt_message);        txt_better = (TextView) findViewById(R.id.txt_better);        txt_setting = (TextView) findViewById(R.id.txt_setting);        ly_content = (FrameLayout) findViewById(R.id.ly_content);
        txt_channel.setOnClickListener(this);        txt_message.setOnClickListener(this);        txt_better.setOnClickListener(this);        txt_setting.setOnClickListener(this);    }
    //重置所有文本的选中状态    private void setSelected(){        txt_channel.setSelected(false);        txt_message.setSelected(false);        txt_better.setSelected(false);        txt_setting.setSelected(false);    }
    //隐藏所有Fragment    private void hideAllFragment(FragmentTransaction fragmentTransaction){        if(fg1 != null)fragmentTransaction.hide(fg1);        if(fg2 != null)fragmentTransaction.hide(fg2);        if(fg3 != null)fragmentTransaction.hide(fg3);        if(fg4 != null)fragmentTransaction.hide(fg4);    }
    @Override    public void onClick(View v) {        FragmentTransaction fTransaction = fManager.beginTransaction();        hideAllFragment(fTransaction);        switch (v.getId()){            case R.id.txt_channel:                setSelected();                txt_channel.setSelected(true);                if(fg1 == null){                    fg1 = new MyFragment("第一个Fragment");                    fTransaction.add(R.id.ly_content,fg1);                }else{                    fTransaction.show(fg1);                }                break;            case R.id.txt_message:                setSelected();                txt_message.setSelected(true);                if(fg2 == null){                    fg2 = new MyFragment("第二个Fragment");                    fTransaction.add(R.id.ly_content,fg2);                }else{                    fTransaction.show(fg2);                }                break;            case R.id.txt_better:                setSelected();                txt_better.setSelected(true);                if(fg3 == null){                    fg3 = new MyFragment("第三个Fragment");                    fTransaction.add(R.id.ly_content,fg3);                }else{                    fTransaction.show(fg3);                }                break;            case R.id.txt_setting:                setSelected();                txt_setting.setSelected(true);                if(fg4 == null){                    fg4 = new MyFragment("第四个Fragment");                    fTransaction.add(R.id.ly_content,fg4);                }else{                    fTransaction.show(fg4);                }                break;        }        fTransaction.commit();    }}
   复制代码
 3.代码下载:
FragmentDemo.zip:FragmentDemo.zip 
评论 (1 条评论)