一、功能说明
用过微信的小伙伴都知道,进入微信之后屏幕会大致分为三部分,最上面的部分显示标题,中间部分显示内容,最下会有不同图标,点击之后会进入不同的功能界面。
不只是微信,很多APP都采取这样的布局,在这样的布局之中,最基本也是最重要的功能就是点击下方的图标,中间部分变为相应内容,在本文中也将主要讲述该功能。
二、程序分析
在本案例中,首先需要将页面基本的上中下部分结构搭建出来,之后再利用 Fragment 完成页面切换功能,大致分为 UI 设计与页面切换功能两部分。
(一)UI设计
- 首先将所有的图片资源放入【res】-【drawable】文件夹中,由于要做出点击与未点击的不同效果,有四个tab,则一共需要八张图片。
- 在layout文件夹中创建
top.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">
<TextView
android:id="@+id/textView1"
android:textSize="40sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/black"
android:layout_weight="1"
android:gravity="center"
android:textColor="@color/white"
android:text="@string/top_name" />
</LinearLayout>
- 在layout文件夹中创建
bottom.xml
文件,并设置其样式,样式为一个外层 horizental 的 LinearLayout 中平铺四个内层 vertical 的 LinearLayout。内层 LinearLayout 中放一个 ImageButton 和一个 TextView。值得注意的是,需要在每个 LinearLayout 中加上 onClick 属性,并在其中的 ImageButton 里设置 clickable=“false”。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="@drawable/bottom_bar"
android:orientation="horizontal"
android:baselineAligned="false">
<LinearLayout
android:id="@+id/linear_chat"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:onClick="onClick">
<ImageButton
android:id="@+id/img_chat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#121515"
android:contentDescription="@string/top_name"
android:clickable="false"
app:srcCompat="@drawable/tab_weixin_pressed" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="微信"
android:textColor="@color/white"
android:textSize="15dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linear_friend"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:onClick="onClick">
<ImageButton
android:id="@+id/img_friend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#121515"
android:clickable="false"
android:contentDescription="@string/top_name"
app:srcCompat="@drawable/tab_find_frd_normal" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="好友"
android:textColor="@color/white"
android:textSize="15dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linear_contact"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:onClick="onClick">
<ImageButton
android:id="@+id/img_contact"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#121515"
android:clickable="false"
android:contentDescription="@string/top_name"
app:srcCompat="@drawable/tab_address_normal" />
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="通讯录"
android:textColor="@color/white"
android:textSize="15dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linear_setting"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:onClick="onClick">
<ImageButton
android:id="@+id/img_setting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#121515"
android:clickable="false"
android:contentDescription="@string/top_name"
app:srcCompat="@drawable/tab_settings_normal" />
<TextView
android:id="@+id/textView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="设置"
android:textColor="@color/white"
android:textSize="15dp" />
</LinearLayout>
</LinearLayout>
- 删除原有的 activity_main.xml 文件,新建一个外层是 LinearLayout 的主xml文件
layout_main.xml
,利用 include 和FrameLayout 标签进行 top 和 bottom 的布局。
<?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">
<include
android:id="@id/top"
android:layout_width="match_parent"
android:layout_height="50sp"
layout="@layout/top"
/>
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
<include
android:id="@id/bottom"
layout="@layout/bottom"/>
</LinearLayout>
当前界面如下:
(二)页面切换功能
- 布局完成之后,新建四个空白的 Fragment,分别设置xml页面其中的 TextView 内容。
- 在主程序MainActivity中,首先找到四个 Fragment 和所有控件,再把四个 fragment 放到 FrameLayout 中去。
// Fragment初始化函数
public void initFragment(){
fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
// 要把四个fragment放到id为content的FrameLayout中去
transaction.add(R.id.content,chatFragment);
transaction.add(R.id.content,friendFragment);
transaction.add(R.id.content,contactFragment);
transaction.add(R.id.content,settingFragment);
transaction.commit();
}
// 找到所有的控件
private void initView(){
tabChat = (LinearLayout)findViewById(R.id.linear_chat);
tabFriend = (LinearLayout)findViewById(R.id.linear_friend);
tabContact = (LinearLayout)findViewById(R.id.linear_contact);
tabSetting = (LinearLayout)findViewById(R.id.linear_setting);
imgChat = (ImageButton)findViewById(R.id.img_chat);
imgFriend = (ImageButton)findViewById(R.id.img_friend);
imgContact = (ImageButton)findViewById(R.id.img_contact);
imgSetting = (ImageButton)findViewById(R.id.img_setting);
}
- 考虑写一个函数 selectTab 进行切换控制,在这个函数中,首先将所有的 Fragment 隐藏,再依据每个按钮对应的数字进行中间 content 内容的切换,而隐藏所有Fragment 的函数也需要自己另外编写。
// 利用函数控制页面切换
private void selectTab(int i){
FragmentTransaction transaction = fragmentManager.beginTransaction();
hideFragment(transaction); // 将全部界面隐藏
switch (i){
case 1:
transaction.show(chatFragment);
// 设置图片为绿色的(表示选中)
imgChat.setImageResource(R.drawable.tab_weixin_pressed);
break;
case 2:
transaction.show(friendFragment);
imgFriend.setImageResource(R.drawable.tab_find_frd_pressed);
break;
case 3:
transaction.show(contactFragment);
imgContact.setImageResource(R.drawable.tab_address_pressed);
break;
case 4:
transaction.show(settingFragment);
imgSetting.setImageResource(R.drawable.tab_settings_pressed);
break;
default:
break;
}
transaction.commit();
}
// 先隐藏所有的fragment
private void hideFragment(FragmentTransaction transaction){
transaction.hide(chatFragment);
transaction.hide(friendFragment);
transaction.hide(contactFragment);
transaction.hide(settingFragment);
}
- 对点击事件进行监听,为每个按钮设置相应的数字,selectTab 函数才知道哪个数字对应哪个按钮。在监听函数 onClick 中,首先要将所有图标变灰(否则某个图标被点击之后再点击其他图标,该图标也会是绿色),随后再根据相应点击的 LinearLayout 设置数字。
// 监听响应函数
@Override
public void onClick(View v) {
resetImg();
switch (v.getId()){
case R.id.linear_chat:
Log.v("wsm","第一个tab被点击");
selectTab(1);
break;
case R.id.linear_friend:
Log.v("wsm","第二个tab被点击");
selectTab(2);
break;
case R.id.linear_contact:
Log.v("wsm","第三个tab被点击");
selectTab(3);
break;
case R.id.linear_setting:
Log.v("wsm","第四个tab被点击");
selectTab(4);
break;
}
}
// 还原初始图标函数
private void resetImg() {
imgChat.setImageResource(R.drawable.tab_weixin_normal);
imgFriend.setImageResource(R.drawable.tab_find_frd_normal);
imgContact.setImageResource(R.drawable.tab_address_normal);
imgSetting.setImageResource(R.drawable.tab_settings_normal);
}
- 设置局部监听(对底部LinearLayout的监听),由于目前设置的监听为全局监听,十分消耗内存,所以重新编写一个函数 initEvent() 仅对底部的四个 LinearLayout 进行监听.
// 设置局部监听
private void initEvent() {
tabChat.setOnClickListener(this);
tabFriend.setOnClickListener(this);
tabContact.setOnClickListener(this);
tabSetting.setOnClickListener(this);
}
- 在 onCreate 函数中调用初始化控件函数 initView()、控件监听函数 initEvent()、初始化Fragment函数 initFragment()、控制页面切换函数 selectTab() 并设置默认值1。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
// 初始化LinearLayout和ImageButton
initView();
// 设置控件的监听函数
initEvent();
// 初始化Fragment
initFragment();
selectTab(1);
}
三、运行界面
- 点击第一个“聊天”按钮:
- 点击第二个“好友”按钮:
- 点击第三个“通讯录”按钮
- 点击第四个“设置”按钮
四、完整源代码
源码gitee地址:类微信页面设计基础练习源代码