1. 分析demo页面结构
首先,这个页面包含了四个层级,
第一个层级就是学习,课表,图标可以采用一个
LinearLayout
横向布局第二层放置五个
MaterialButton
,并设置icon
图标第三层直接复制第一行并修改文字描述
第四行使用
RecyclerView
绑定数据列表
2. 创建页面资源文件
首先在
res/layout
下创建出来一个fragment_study.xml
的文件,其rootElement
为LinearLayout
,并将根节点布局设置为垂直布局
<?xml version="1.0" encoding="utf-8"?>
<!-- 通过android:orientation="vertical" 设置页面为垂直布局 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
1. 书写第一行
添加一个
LinearLayout
,并将其的布局方式设置为水平布局,依次添加页面上的三个元素,这个时候最右侧的图标是紧挨着课表这个TextView
的,我们可以添加一个View标签,将其宽度设置为0,权重设置为1,这样这个View就会占掉这一行剩余的所有空间
<!--第一行 学习列表-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="学习"
android:textSize="28sp"
android:textStyle="bold"
android:id="@+id/tab_id"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="课表"
android:textStyle="bold"
android:textSize="28sp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"/>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="right"
android:src="@drawable/logo"
android:scaleType="fitCenter"
/>
</LinearLayout>
2. 第二行图标
通过
CardView
可以很方便的创建出来图中的卡片布局,通过app:cardElevation="10dp"
设置阴影
app:cardCornerRadius="10dp"
设置卡片布局的圆角矩形。创建出来一个
LinearLayout
,设置为垂直布局添加图标及文字描述,这里使用的是
MaterialButton
,当然也可以使用LinearLayout
来完成布局.因为父元素
CardView
的背景颜色是白色,并且MaterialButton
给图标设置的默认背景颜色也和白色差不多,所以设置之后是看不出来的,可以自定义颜色,也可以通过app:iconTint="@null"
,不给图标设置背景颜色,这样就会用图标自己本来的颜色填充这个button图标自己会带一个上边框和下边框,可以使用下列代码去除
<com.google.android.material.button.MaterialButton style="@style/Widget.MaterialComponents.Button.UnelevatedButton"/>
<!-- 第二行圆角阴影 功能区域 -->
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@color/white"
app:cardElevation="10dp"
app:cardCornerRadius="10dp"
android:layout_marginTop="15dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<!--
设置了icon之后默认会是白色的,
想要用图标自己的颜色需要设置android:iconTint="@null"
因为materialButton带了描边和阴影重叠了,可以使用下边的取消掉描边
style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
-->
<com.google.android.material.button.MaterialButton
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="收藏"
android:textColor="#333333"
android:backgroundTint="@color/white"
app:icon="@drawable/logo"
app:iconGravity="textTop"
app:iconSize="30dp"
app:iconTint="@null"
style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
android:id="@+id/item_collection"
/>
<com.google.android.material.button.MaterialButton
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="问答"
android:textColor="#333333"
android:backgroundTint="@color/white"
app:icon="@drawable/logo"
app:iconGravity="textTop"
app:iconSize="30dp"
app:iconTint="@null"
style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
android:id="@+id/item_question"
/>
<com.google.android.material.button.MaterialButton
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="笔记"
android:textColor="#333333"
android:backgroundTint="@color/white"
app:icon="@drawable/logo"
app:iconGravity="textTop"
app:iconSize="30dp"
app:iconTint="@null"
style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
android:id="@+id/item_note"
/>
<com.google.android.material.button.MaterialButton
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="手记"
android:textColor="#333333"
android:backgroundTint="@color/white"
app:icon="@drawable/logo"
app:iconGravity="textTop"
app:iconSize="30dp"
app:iconTint="@null"
style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
android:id="@+id/item_hand"
/>
<com.google.android.material.button.MaterialButton
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="下载"
android:textColor="#333333"
android:backgroundTint="@color/white"
app:icon="@drawable/logo"
app:iconGravity="textTop"
app:iconSize="30dp"
app:iconTint="@null"
style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
android:id="@+id/item_download"
/>
</LinearLayout>
</androidx.cardview.widget.CardView>
3. 第三行Tab
直接复制第一行的代码即可
<!-- 第三行切换 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="我的课程"
android:textSize="18sp"
android:textStyle="bold"
android:id="@+id/tab_course"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="我的专栏"
android:textStyle="bold"
android:textSize="18sp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:id="@+id/tab_article"/>
</LinearLayout>
4. 第四行RecyclerView
1. 创建RecycleView
先在父页面中创建出来RecycleView,然后单独书写一个页面来做布局展示
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler_view"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:layout_marginTop="10dp"/>
2. item展示
先确定最外层是一个水平布局的LinearLayout,下边有一个View来做分割线
最左侧需要一个ImageView,中间一个垂直布局的LinearLayout,右侧一个按钮
<?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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="140dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<ImageView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginRight="10dp"
android:id="@+id/item_course_logo"
android:src="@drawable/logo"/>
<!--
我的这里这个LinearLayout设置了width之后总是会把右下角的更多按钮挤下去
所以就设置了0dp weight=1让他占满剩余的空间
-->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/item_course_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="测试第一行"
android:textSize="16dp"
android:textStyle="bold" />
<com.google.android.material.button.MaterialButton
android:id="@+id/item_course_label"
style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:backgroundTint="#FBF5E5"
android:insetTop="0dp"
android:insetBottom="0dp"
android:padding="0dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:text="架构师体系课"
android:textColor="#B49D70"
app:cornerRadius="5dp" />
<TextView
android:id="@+id/item_course_progress"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="测试第三行" />
</LinearLayout>
<ImageView
android:id="@+id/action_more"
android:layout_width="20dp"
android:src="@android:drawable/ic_menu_more"
android:layout_height="20dp"
android:layout_gravity="bottom"
app:tint="@color/purple_700" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#f3f3f3"/>
</LinearLayout>
3. 创建kt文件
1. 创建fragment
在
com.example.myapplication.ui
包下创建study
包,并新建一个文件StudyFragment
package com.example.myapplication.ui.study
class StudyFragment: Fragment(R.layout.fragment_study) {
}
2. 绑定item列表
package com.example.myapplication.ui.study
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.myapplication.R
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.item_study.view.*
class StudyFragment: Fragment(R.layout.fragment_study) {
// 重写加载视图的办法
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recycler_view.layoutManager = LinearLayoutManager(context)
recycler_view.adapter = StudyAdapter()
}
// 创建内部类。否则加载不到context对象
inner class StudyAdapter : RecyclerView.Adapter<StudyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StudyViewHolder {
//加载资源未见为item_study.xml
var view = LayoutInflater.from(context)
.inflate(R.layout.item_study, parent, false)
return StudyViewHolder(view)
}
//这里因为还没有学网络编程,暂时写死20
override fun getItemCount(): Int {
return 20
}
// 绑定item_study里边的图片及文本内容
override fun onBindViewHolder(holder: StudyViewHolder, position: Int) {
holder.itemView.item_course_title.text = "[$position]移动端Android Kotlin开发"
holder.itemView.item_course_label.text = "Kotlin"
holder.itemView.item_course_progress.text = "已学: 100%"
holder.itemView.item_course_logo.setImageResource(R.drawable.logo)
}
}
inner class StudyViewHolder(view: View): RecyclerView.ViewHolder(view) {}
}
3. 修改菜单
- 修改顶部菜单
找到
res/menu/bottom_nav_menu.xml
,赋值一个item并改名成Study
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home" />
<item
android:id="@+id/navigation_dashboard"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_dashboard" />
<!-- 复制出来一个即可,这里的@string/title_study会报错会在下一步解决 -->
<item
android:id="@+id/navigation_study"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_study" />
<item
android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/title_notifications" />
</menu>
2. 添加@stringtitle_study
变量
在其他的title值上ctrl + B/ 鼠标左键,或者是找到
res/values/strings.xml
在里边添加一个变量即可
<resources>
<string name="app_name">My Application</string>
<string name="title_home">Home</string>
<string name="title_study">Study</string>
<string name="title_dashboard">Dashboard</string>
<string name="title_notifications">Notifications</string>
</resources>
- 修改navigation
复制一个
fragment
标签并将id设置为第一步中的id,否则可能加载不出来,如果需要app启动之后就加在我们写的页面,需要修改app:startDestination
为自己创建的fragment对应的id,也就是下边的第六行
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/mobile_navigation"
app:startDestination="@+id/navigation_study">
<fragment
android:id="@+id/navigation_home"
android:name="com.example.myapplication.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/navigation_dashboard"
android:name="com.example.myapplication.ui.dashboard.DashboardFragment"
android:label="@string/title_dashboard"
tools:layout="@layout/fragment_dashboard" />
<fragment
android:id="@+id/navigation_study"
android:name="com.example.myapplication.ui.study.StudyFragment"
android:label="Study"
tools:layout="@layout/fragment_study"
/>
<fragment
android:id="@+id/navigation_notifications"
android:name="com.example.myapplication.ui.notifications.NotificationsFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications" />
</navigation>
- 启动模拟器运行即可
4. 问题及解决办法
- 自己写的fragment上边有一个空白,不顶格
这个问题我也不知道是因为什么导致的,但是可以通过删除
activity_main.xml
根节点中的android:paddingTop="?attr/actionBarSize"
来解决