Android开发笔记-明天计划(三)(主页分页)
原型图
首先复盘一下原型图,常规的上中下结构,即标题、内容、导航栏,不同的页面切换不同的标题栏,所以这个标题栏可能会跟内容并在一起,也可能单独放在最外层,这个不重要。分页的逻辑是将四个页面作为四个子view,放置在当前activity下,简单的点击哪个显示哪个,再隐藏其他的,因为主页可能会做一些手势滑动切换之类的动作,所以页面切换就不用ViewPager做左右滑动切换页面了。
布局框架
框架就是简单的把中间内容和底部导航的位置固定一下,这里采用的是线性布局,然后内容显示的容器设置layout_weight自适应撑开,底部导航就是直接写死46dp的高度。因为是沉浸式状态栏,所以需要这两条:android:clipToPadding="true" android:fitsSystemWindows="true"
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="true" android:fitsSystemWindows="true" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="@color/app_background" /> <LinearLayout android:layout_width="match_parent" android:layout_height="46dp" android:background="@color/white" android:orientation="horizontal"> </LinearLayout> </LinearLayout> </RelativeLayout>
底部导航栏
首先需要准备4个图标,每个图标是两种颜色,如果有条件的话设计师会帮你切好图,没条件的就跟我一起去白嫖吧,白嫖网址:https://www.iconfont.cn/search/index
可以预估一下图标大概多大,这里的话可以用20dp,我习惯性是采用4x的图标,也就是20dp的图标需要的像素大小大概是80X80像素,放在drawable-xxxhdpi中。
drawable文件夹的话一般不放图片,放一些颜色、状态之类的xml文件。字体颜色的话就是txt_开头,纯色(通常是描边、圆角、填充色)只有1中状态的就是bg_开头,如果是多种状态,如按钮这种,就是btn_开头。
将图标导入进来,再写好颜色、状态xml之后,资源如下图所示:
效果为:
布局的话尽量不要写得太生硬,尽量灵活一些,多用些自适应的布局逻辑,因为Android的屏幕的比例千奇百怪,如果写得太生硬的话,16:9可能正常,20:9的时候就严重变形,那就不太美丽了。
其他需要注意的地方我都写代码里面注释了。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="true" android:fitsSystemWindows="true" android:orientation="vertical"> <RelativeLayout android:id="@+id/rly_content" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="@color/app_background" /> <LinearLayout android:layout_width="match_parent" android:layout_height="46dp" android:background="@color/white" android:orientation="horizontal"> <!-- 如果觉得写在同一个xml里面会显得太过臃肿的话,也可以新建一个xml,然后通过include标签引用进来(一些复用性比较多的布局都可以这么处理)--> <!-- Space用于占位,以保证每个图标之间的间隔是一样的--> <Space android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <RelativeLayout android:id="@+id/rly_task" android:layout_width="wrap_content" android:layout_height="match_parent"> <!-- 用RelativeLayout再嵌套一个LinearLayout的意思是让LinearLayout上下居中,从而可以上下的位置一致,会随着图片和文字的高度而动态调整--> <LinearLayout android:layout_width="60dp" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical"> <!-- 把LinearLayout宽度固定60,高度自适应,这样可以固定宽度不会变形,高度也可以根据imageView和TextView的高度自适应--> <!-- ImageView的宽度写最大,高度自适应,然后高度会根据图标的真是高度进行显示,并且是居中的--> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/btn_home_bar_task" /> <!-- 文字正常是用sp单位,但是sp会随着系统设置的字体大小发生改变,会导致部分页面变形,所以我不太想他自己定义,就用dp写死--> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:gravity="center" android:text="任务" android:textColor="@drawable/txt_home_bar" android:textSize="12dp" /> </LinearLayout> </RelativeLayout> <Space android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <RelativeLayout android:id="@+id/rly_tool" android:layout_width="wrap_content" android:layout_height="match_parent"> <LinearLayout android:layout_width="60dp" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical"> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/btn_home_bar_tool" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:gravity="center" android:text="工具" android:textColor="@drawable/txt_home_bar" android:textSize="12dp" /> </LinearLayout> </RelativeLayout> <Space android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <RelativeLayout android:id="@+id/rly_table" android:layout_width="wrap_content" android:layout_height="match_parent"> <LinearLayout android:layout_width="60dp" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical"> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/btn_home_bar_tablel" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:gravity="center" android:text="统计数据" android:textColor="@drawable/txt_home_bar" android:textSize="12dp" /> </LinearLayout> </RelativeLayout> <Space android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <RelativeLayout android:id="@+id/rly_personal" android:layout_width="wrap_content" android:layout_height="match_parent"> <LinearLayout android:layout_width="60dp" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical"> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/btn_home_bar_personal" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:gravity="center" android:text="我的" android:textColor="@drawable/txt_home_bar" android:textSize="12dp" /> </LinearLayout> </RelativeLayout> <Space android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> </LinearLayout> </LinearLayout> </RelativeLayout>
编写切换页面的代码
新建HomeActivity继承BaseAppActivity,新建4个子页面的View,继承BaseAppView,并在MainActivity中编写跳转逻辑,跳转到HomeActivity。
HomeActivity代码:
package com.imxiaoyu.tomorrowplan.module.home; import android.view.View; import android.widget.RelativeLayout; import com.imxiaoyu.tomorrowplan.R; import com.imxiaoyu.tomorrowplan.common.base.BaseAppActivity; import com.imxiaoyu.tomorrowplan.module.home.view.PersonalView; import com.imxiaoyu.tomorrowplan.module.home.view.TableView; import com.imxiaoyu.tomorrowplan.module.home.view.TaskView; import com.imxiaoyu.tomorrowplan.module.home.view.ToolView; public class HomeActivity extends BaseAppActivity implements View.OnClickListener { /** * 常量 */ public final static int PAGE_TASK = 0; public final static int PAGE_TOOL = 1; public final static int PAGE_TABLE = 2; public final static int PAGE_PERSONAL = 3; /** * view */ private TaskView taskView; private ToolView toolView; private TableView tableView; private PersonalView personalView; /** * ui */ private RelativeLayout rlyContent; private RelativeLayout rlyTask; private RelativeLayout rlyTool; private RelativeLayout rlyTable; private RelativeLayout rlyPersonal; @Override protected int getLayoutId() { return R.layout.activity_home; } @Override protected void initData() { } @Override protected void initView() { //找控件的话,我更喜欢这种近乎原始的方式,不太喜欢用注解的方式,1是并不会比现在更省事,也会增加内容支出。 rlyContent = findView(R.id.rly_content); rlyTask = findView(R.id.rly_task, this); rlyTool = findView(R.id.rly_tool, this); rlyTable = findView(R.id.rly_table, this); rlyPersonal = findView(R.id.rly_personal, this); taskView = new TaskView(getActivity()); toolView = new ToolView(getActivity()); tableView = new TableView(getActivity()); personalView = new PersonalView(getActivity()); rlyContent.addView(taskView.getView()); rlyContent.addView(toolView.getView()); rlyContent.addView(tableView.getView()); rlyContent.addView(personalView.getView()); switchPage(PAGE_TASK);//初始化页面 } @Override protected void onCreateActivity() { } @Override public void onClick(View view) { switch (view.getId()){ case R.id.rly_task: switchPage(PAGE_TASK); break; case R.id.rly_tool: switchPage(PAGE_TOOL); break; case R.id.rly_table: switchPage(PAGE_TABLE); break; case R.id.rly_personal: switchPage(PAGE_PERSONAL); break; } } /** * 切换页面 * * @param page */ private void switchPage(int page) { rlyTask.setSelected(false); rlyTool.setSelected(false); rlyTable.setSelected(false); rlyPersonal.setSelected(false); taskView.dismiss(); toolView.dismiss(); tableView.dismiss(); personalView.dismiss(); switch (page) { case PAGE_TASK: rlyTask.setSelected(true); taskView.show(); break; case PAGE_TOOL: rlyTool.setSelected(true); toolView.show(); break; case PAGE_TABLE: rlyTable.setSelected(true); tableView.show(); break; case PAGE_PERSONAL: rlyPersonal.setSelected(true); personalView.show(); break; } } }
其他
码云地址:https://gitee.com/imxiaoyu_admin/tomorrow
本次提交时间:2020年7月17日
本次完成的预览包apk:http://file.doutugongchang.com/app/upload/tomorrow-plan-debug-2020-7-17.apk