QQ人群里使用最多的手机APP之一,它的设计、排版都深受大众的喜爱,那么你想不想知道QQ的底部导航是如何实现的呢?其实很简单,通过Fragment+FragmentTabHost我们就可以轻松实现类似QQ底部导航的效果。
第一步:看到QQ底部导航只要有三栏,第一栏是“消息”,第二栏“联系人”,第三栏“动态”,可以自由的在这三栏导航中来回的切换,然后在上面展示不同的内容。这三栏中的一个特点是:文字的上面是一张图标,所以在制作布局的时候我们可以只需要一个模板就可以了,我们将这个模板命名为qq_nav_item.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="wrap_content"
- android:gravity="center"
- android:orientation="vertical" >
- <ImageView
- android:id="@+id/qq_nav_icon_iv"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:focusable="false"
- android:padding="3dp"
- android:src="@drawable/tab_message_btn">
- </ImageView>
- <TextView
- android:id="@+id/qq_nav_text_tv"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="消息"
- android:textSize="10dp"
- android:textColor="@color/change_color_text">
- </TextView>
- </LinearLayout>
第二步:我们看到QQ在切换到当前状态的时候,图标和文字颜色都发生了改变,那是在控件中添加了颜色切换器(命名为change_color_text.xml)和图标切换器(命名为one_change_icon_image.xml,two_change_icon_image.xml,three_change_icon_image.xml),因为图标有三种,颜色只有一种变化,所有需要声明三个图标切换器,代码如下:
- <!--颜色切换器-->
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="#0033FF" android:state_selected="true"/>
- <item android:color="#cccccc"/>
- </selector>
- <!--one_change_icon_image.xml-->
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/message_icon_pressed" android:state_selected="true"/>
- <item android:drawable="@drawable/message_icon_normal"/>
- </selector>
- <!--two_change_icon_image.xml-->
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/contact_icon_pressed" android:state_selected="true"/>
- <item android:drawable="@drawable/contact_icon_normal"/>
- </selector>
- <!--three_change_icon_image.xml-->
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/dynamic_icon_pressed" android:state_selected="true"/>
- <item android:drawable="@drawable/dynamic_icon_normal"/>
- </selector>
第三步:我们可以制作QQ主页面了,命名为qq_main_layout.xml,在这个布局中使用FragmentTabHost,实现导航内容之间的切换,FlameLayout里面用于显示导航下的内容,比如消息导航中,FlameLayout里面显示当前正在聊天的窗口,代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <FrameLayout
- android:id="@+id/qq_tabcontent"
- android:layout_width="fill_parent"
- android:layout_height="0dip"
- android:layout_weight="1" />
- <android.support.v4.app.FragmentTabHost
- android:id="@+id/tabhost"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="#ffffff">
- <FrameLayout
- android:id="@+id/tabcontent"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_weight="0" />
- </android.support.v4.app.FragmentTabHost>
- </LinearLayout>
第四步:创建三个Fragment页面,分别在导航切换到“消息”、“联系人”、“动态”时展示对应的内容,分别命名MessageFragment.java,ContactFragment.java和DynamicFragment.java,在这里我们主要显示QQ导航制作,关于内容页面我将在下一篇文章中介绍。这里我们就简单在内容中的Fragment输出有些提示文字,使用统一的布局:fragment_content.xml,代码如下:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- <TextView
- android:id="@+id/fragment_content_tv"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:gravity="center"
- android:textSize="20dp"
- android:text="QQ内容显示页面" />
- </RelativeLayout>
- /*
- MessageFragment.java
- */
- import android.os.Bundle;
- import android.support.v4.app.Fragment;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- public class MessageFragment extends Fragment{
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_content, null);
- }
- }
- /*
- ContactFragment.java
- */
- import android.os.Bundle;
- import android.support.v4.app.Fragment;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- public class ContactFragment extends Fragment{
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_content, null);
- }
- }
- /*
- DynamicFragment.java
- */
- import android.os.Bundle;
- import android.support.v4.app.Fragment;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- public class DynamicFragment extends Fragment{
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_content, null);
- }
- }
第五步:创建Activity类,命名为QQMainActivity.java解析布局文件,同时将MessageFragment,ContactFragment和DynamicFragment嵌入到导航中,展示指定QQ导航下的内容,代码如下:
- 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.widget.ImageView;
- import android.widget.TabHost.TabSpec;
- import android.widget.TextView;
- public class QQMainActivity extends FragmentActivity{
- //定义FragmentTabHost对象
- private FragmentTabHost mTabHost;
- //定义一个布局
- private LayoutInflater layoutInflater;
- //定义数组来存放Fragment界面
- private Class fragmentArray[] = {MessageFragment.class,ContactFragment.class,DynamicFragment.class};
- //定义数组来存放导航图标
- private int mImageViewArray[] = {R.drawable.one_change_icon_image,R.drawable.two_change_icon_image,R.drawable.three_change_icon_image};
- //Tab选项卡的文字
- private String mTextviewArray[] = {"消息", "联系人", "动态"};
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.qq_main_layout);
- initView();
- }
- /**
- * 初始化组件
- */
- private void initView(){
- //实例化布局对象
- layoutInflater = LayoutInflater.from(this);
- //实例化TabHost对象,得到TabHost
- mTabHost = (FragmentTabHost)findViewById(R.id.tabhost);
- mTabHost.setup(this, getSupportFragmentManager(), R.id.qq_tabcontent);
- //得到fragment的个数
- int count = fragmentArray.length;
- for(int i = 0; i < count; i++){
- //为每一个Tab按钮设置图标、文字和内容
- TabSpec tabSpec = mTabHost.newTabSpec(mTextviewArray[i]).setIndicator(getTabItemView(i));
- //将Tab按钮添加进Tab选项卡中
- mTabHost.addTab(tabSpec, fragmentArray[i], null);
- }
- }
- /**
- * 给Tab按钮设置图标和文字
- */
- private View getTabItemView(int index){
- View view = layoutInflater.inflate(R.layout.tab_item_view, null);
- ImageView imageView = (ImageView) view.findViewById(R.id.qq_nav_icon_iv);
- imageView.setImageResource(mImageViewArray[index]);
- TextView textView = (TextView) view.findViewById(R.id.qq_nav_text_tv);
- textView.setText(mTextviewArray[index]);
- return view;
- }
- }
总结:按照步骤下来,仿QQ导航我们算是完成了,不懂做的博友们可以收藏,留着备用,那个我们每天都再用的QQ导航原来制作起来也就那样,还算简单吧?后期整理源码后,提供下载,尽请期待!