要求:
设计一个app首页
根据课堂展示结果设计app门户界面,包含4个tab切换效果。
功能说明:
1、页面顶部显示app名称
2、页面有中间显示框
3、页面具有底部选择框,并且具有选择事件
4、在页面底部选择框进行改变的时候,中间显示框的页面同步改变
功能分析:
微信主界面其实是由三个大的layout拼接而成的一个LinearLayout布局,我们需要写一个top,一个bottom,四个根据底部事件触发显示的FrameLayout,FrameLayout就是微信界面中的中间部分,也就是我们需要输出文字的部分,用一个用一个主LinearLayout把这三部分链接在一起。
1、top:一个顶部的LinearLayOut 显示顶部内容,即app名称
2、bottom:底部的4个标签,使用4个LinearLayOut 并且是横向布局
3、四个Fragment 分别对应4个页面的内容,即微信、朋友、通讯录、设置
bottom功能设计分析
底部共有四个图标采用LinearLayout布局,每一个LinearLayout包含一个imagebutton和TextView,每点击一个图标,对应的Fragment显示。
为了扩大点击范围,及无论点击imagebutton还是TextView都能触发对应事件,需要将子控件的click事件关闭,父控件的click事件才能生效。
当点击相应的图标时,不仅图标颜色发生变化,下方文字也应该产生变化。
top功能分析:
原本app初始化时,使用的默认主题的父类是DarkActionBar,他默认的actionBar是黑色的,因此,如果再添加一个top,就会有两actionbar,因此为了只显示我们自定义的top,急需要改变其父类:NoActionBar,同时设置其属性windowNoTitle为true.
Java部分
为底部四个LinearLayout建立事件监听,当点击某个按钮就显示对应的Fragment,同时隐藏其他Fragment,按钮文字颜色也改变。
代码实现
1、顶部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="65dp"
android:background="#000000"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:layout_weight="1"
android:text="@string/app_name"
android:textColor="#ffffff"
android:textSize="20sp" />
</LinearLayout>
- gravity 组件的子组件在组件中的位置
- layout_gravity 组件自身在父组件中的位置
- layout_weight属性的意义就是将父控件的剩余空间按照设置的权重比例再分配,也就是在布局的时候,系统先按照view的layout_width和layout_height来布局,然后再根据layout_weight对view的位置进行调整
2、bottom.xml文件:
一下是部分代码,以一个图标为例:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/id_tab_weixin"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:background="#000000"
android:orientation="vertical">
<ImageButton
android:id="@+id/id_tab_weixin_img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#000000"
android:clickable="false"
android:contentDescription="@string/app_name"
app:srcCompat="@drawable/tab_weixin_pressed" />
<TextView
android:id="@+id/id_text_weixin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="微信"
android:textColor="#ffffff"
android:gravity="center"
android:clickable="false"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
- orientation = “horizontal” 指定布局内控件排列方式为 水平排列,“vertical” 指定布局内控件排列方式为垂直排列
- layout_width="0dp"与layout_weight="1"表示不设置控件宽度,显示按照layout_weight的比例进行展示,每个控件权重相同即表示平均分布
- clickable="false"当关闭所有子控件的点击事件,父控件的点击事件才能生效
3、activity_main.xml
activity_main.xml的主要工作就是将写好的top.xml和button.xml导入到主窗体中显示,以include标签和FrameLayout标签将top.xml、button.xml、tab01.xml导入显示。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/top" />
<FrameLayout
android:id="@+id/id_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
<include layout="@layout/bottom" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
4、MainActivity代码
所需变量:
private Fragment mTab01 = new weixinFragment();
private Fragment mTab02 = new friendFragment();
private Fragment mTab03 = new contactFragment();
private Fragment mTab04 = new settingFragment();
private FragmentManager fm;
private LinearLayout mTabWeixin;
private LinearLayout mTabFrd;
private LinearLayout mTabContact;
private LinearLayout mTabSettings;
private ImageButton mImgWeixin;
private ImageButton mImgFrd;
private ImageButton mImgContact;
private ImageButton mImgSettings;
private TextView mTextWeixin;
private TextView mTextFrd;
private TextView mTextContact;
private TextView mTextSetting;
- mTab01:中间的fragment
- fm:用来管理以上Fragment,绑定与控制fragment
- mImgWeixin:对应button.xml中的ImageView,用来改变图标
- mTextWeixin:对应button.xml中的TextView,用来改变字体颜色
5、初始化tabBar即控件元素
private void initView(){
mTabWeixin = (LinearLayout)findViewById(R.id.id_tab_weixin);
mTabFrd = (LinearLayout)findViewById(R.id.id_tab_frd);
mTabContact = (LinearLayout)findViewById(R.id.id_tab_contact);
mTabSettings = (LinearLayout)findViewById(R.id.id_tab_setting);
mImgWeixin = (ImageButton)findViewById(R.id.id_tab_weixin_img);
mImgFrd = (ImageButton)findViewById(R.id.id_tab_frd_img);
mImgContact = (ImageButton)findViewById(R.id.id_tab_contact_img);
mImgSettings = (ImageButton)findViewById(R.id.id_tab_setting_img);
mTextWeixin=(TextView)findViewById(R.id.id_text_weixin);
mTextFrd=(TextView)findViewById(R.id.id_text_frd);
mTextContact=(TextView)findViewById(R.id.id_text_contact);
mTextSetting=(TextView)findViewById(R.id.id_text_setting);
}
6、初始化Fragment:
将activity_main.xml文件中的fragment与四个tab01绑定起来:
private void initFragment() {
fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.id_content,mTab01);
transaction.add(R.id.id_content,mTab02);
transaction.add(R.id.id_content,mTab03);
transaction.add(R.id.id_content,mTab04);
transaction.commit();
}
7、初始化四个tab的监听事件
private void initEvent(){
mTabWeixin.setOnClickListener(this);
mTabFrd.setOnClickListener(this);
mTabContact.setOnClickListener(this);
mTabSettings.setOnClickListener(this);
}
8、为四个tab设置点击监听:
@Override
public void onClick(View v) {
resetimg();
switch (v.getId()){
case R.id.id_tab_weixin:
setSelect(0);
break;
case R.id.id_tab_frd:
setSelect(1);
break;
case R.id.id_tab_contact:
setSelect(2);
break;
case R.id.id_tab_setting:
setSelect(3);
break;
default:
break;
}
}
显示对应的fragment,tab颜色变化,在每次点击之后,先把所有图标、字体恢复默认,然后再设置某一个图标、字体状态:
private void setSelect(int i){
resetimg();
FragmentTransaction transaction=fm.beginTransaction();
hidefragment(transaction);
switch (i){
case 0:
transaction.show(mTab01);
mImgWeixin.setImageResource(R.drawable.tab_weixin_pressed);
mTextWeixin.setTextColor(Color.rgb(56, 166, 29));
break;
case 1:
transaction.show(mTab02);
mImgFrd.setImageResource(R.drawable.tab_find_frd_pressed);
mTextFrd.setTextColor(Color.rgb(56, 166, 29));
break;
case 2:
transaction.show(mTab03);
mImgContact.setImageResource(R.drawable.tab_address_pressed);
mTextContact.setTextColor(Color.rgb(56, 166, 29));
break;
case 3:
transaction.show(mTab04);
mImgSettings.setImageResource(R.drawable.tab_settings_pressed);
mTextSetting.setTextColor(Color.rgb(56, 166, 29));
break;
default:
break;
}
transaction.commit();
}
恢复默认状态方法:
private void resetimg(){
mImgWeixin.setImageResource(R.drawable.tab_weixin_normal);
mImgFrd.setImageResource(R.drawable.tab_find_frd_normal);
mImgContact.setImageResource(R.drawable.tab_address_normal);
mImgSettings.setImageResource(R.drawable.tab_settings_normal);
mTextSetting.setTextColor(Color.WHITE);
mTextWeixin.setTextColor(Color.WHITE);
mTextContact.setTextColor(Color.WHITE);
mTextFrd.setTextColor(Color.WHITE);
}
运行界面
展示:
微信界面
朋友界面:
通讯录界面:
设置界面:
源代码仓库地址
gitee仓库地址:
https://gitee.com/hubu8/android