目录
APP名称:今天练了没
APP版本:v1.0
一、项目总体介绍
项目背景:随着生活水平的提高,人们对于提高身体素质的要求越来越强烈,本App旨在为健身爱好者提供相应的参考查询服务,从而提高训练效率。本App包含健身计划、食物热量表、优秀箴言和简单的低卡食谱四个栏目,每个栏目都有相应的内容。希望用户可以通过这四个栏目的内容,加上实际运动,实现管住嘴、迈开腿,通过自己的努力实现身材管理,达到理想的健身目标。
项目内容:根据课程内容设计app的门户框架,创建四个tab页面,并实现四个tab页面的切换效果;
实现技术:activity、xml、fragment、recycleview;
二、关键步骤与核心技术
1.顶部页面设计:top.xml
○ 在/res/layout目录创建一个top.xml,使用LinearLayout水平布局。
○ LinearLayout内包含一个textView,用于实现文本显示效果。
○ textView中设置字体大小、字体颜色、文字背景颜色。
<?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">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#673AB7"
android:gravity="center"
android:text="今天练了没"
android:textColor="@color/white"
android:textSize="50sp" />
</LinearLayout>
2.底部页面设计:bottom.xml
○ 在/res/layout目录创建一个bottom.xml,使用LinearLayout水平布局。
○ 在LinearLayout的下级创建四个LinearLayout,id分别为LinearLayout1、LinearLayout2、LinearLayout3和LinearLayout4.
○ 每个次级LinearLayout都包含一个imageView和textView并采用水平布局
○ imageView为底部栏目的icon图标。
○ textView位于imageView下方,用于显示栏目名称
<?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="wrap_content"
android:layout_gravity="bottom"
android:baselineAligned="true"
android:gravity="bottom"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="120dp"
app:srcCompat="@drawable/icon_3_" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="我的计划"
android:textSize="24sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/LinearLayout2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView2"
android:layout_width="match_parent"
android:layout_height="120dp"
app:srcCompat="@drawable/icon_1_" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="热量表"
android:textSize="24sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/LinearLayout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView3"
android:layout_width="match_parent"
android:layout_height="120dp"
app:srcCompat="@drawable/icon_4_" />
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="箴言"
android:textSize="24sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/LinearLayout4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="120dp"
app:srcCompat="@drawable/icon_2_" />
<TextView
android:id="@+id/textView4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="低卡食谱"
android:textSize="24sp" />
</LinearLayout>
</LinearLayout>
3.文本栏设置:item.xml
○ 在/res/layout目录创建一个item.xml,使用LinearLayout水平布局。
○ LinearLayout内包含一个textView,用于实现recycleView的文本显示效果。
○ textView中设置字体大小、字体颜色。
<?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">
<TextView
android:id="@+id/textView21"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:text="TextView"
android:textColor="#673AB7"
android:textSize="24sp" />
</LinearLayout>
4.中间内容设计:
4.1 plan.xml
○ 在/res/layout目录创建一个plan.xml,使用ConstraintLayout布局。
○ ConstraintLayout内包含一个recycleView,用于实现每日计划的列表显示效果。
4.2 list.xml
○ 在/res/layout目录创建一个list.xml,使用ConstraintLayout布局。
○ ConstraintLayout内包含一个recycleView,用于实现热量表的列表显示效果。
4.3 sentence.xml
○ 在/res/layout目录创建一个sentence.xml,使用ConstraintLayout布局。
○ ConstraintLayout内包含一个recycleView,用于实现箴言的列表显示效果。
4.4 food.xml
○ 在/res/layout目录创建一个food.xml,使用ConstraintLayout布局。
○ ConstraintLayout内包含一个recycleView,用于实现低卡食谱的列表显示效果。
!每个recycleView的代码和效果都类似,故只展示list.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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycleView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
5. 中间内容:Fragment类
○ 在java包目录下新建四个Java文件,分别命名为fragment1、fragment2、fragment3、fragment4。
○ 每个fragment类分别对应中间内容的四个xml。
○ 每个fragment类内分别包含对中间四个内容的recycleView的配置。
!每个fragmen类的代码都类似,故只对fragment1进行代码展示,根据实际需要改变代码的内容即可:
package com.example.as_homework1;
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 java.util.ArrayList;
import java.util.List;
public class fragment1 extends Fragment {
View view;
MyAdapter myAdapter1;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.plan, container, false);
RecyclerView recyclerView1; //我的计划
//我的计划相关配置
recyclerView1 = view.findViewById(R.id.recycleView1);
List<String> list1 = new ArrayList(); //新建一个列表用于存储数据
list1.add("周一:胸 + 三头\n" +
"\n" +
"哑铃卧推 4 * 10\n" +
"上斜卧推 4 * 12\n" +
"坐姿推胸 4 * 16\n" +
"蝴蝶机夹胸 4 * 10\n" +
"锤式卧推 4 * 10\n" +
"\n" +
"绳索下压 4 * 10\n" +
"绳索前拉 4 * 12\n" +
"哑铃颈后臂屈伸 4 * 12\n" +
"俯身哑铃臂屈伸 4 * 12\n");
list1.add("周二:背 + 二头\n" +
"\n" +
"哑铃二头交替弯举 4*12\n" +
"哑铃二头交替锤式弯举 4*12\n" +
"杠铃弯举 4*12\n" +
"杠铃21炮\n" +
"\n" +
"杠铃划船4*12\n" +
"划船机 4*12\n" +
"高位下拉 4*12\n" +
"哑铃划船 4*12\n");
list1.add("周三:肩 + 臀腿\n" +
"\n" +
"哑铃推肩 4 * 12\n" +
"哑铃飞鸟 4 * 16\n" +
"哑铃前平举 4* 16\n" +
"坐姿哑铃飞鸟 4 * 16\n" +
"蝴蝶机飞鸟 4 * 16\n" +
"\n" +
"杠铃硬拉 4 * 12\n" +
"固定杠铃深蹲 4 * 16\n" +
"负重踮脚 4 * 16\n" +
"卧姿腿弯举 4 * 16\n" +
"卷腹 4 * 16\n");
list1.add("周四:休息日 好好放松\n" +
"\n" +
" 享受一下闲暇时光使身体达到放松的状态\n");
list1.add("周五:胸 + 三头\n" +
"\n" +
"哑铃卧推 4 * 10\n" +
"上斜卧推 4 * 12\n" +
"坐姿推胸 4 * 16\n" +
"蝴蝶机夹胸 4 * 10\n" +
"锤式卧推 4 * 10\n" +
"\n" +
"绳索下压 4 * 10\n" +
"绳索前拉 4 * 12\n" +
"哑铃颈后臂屈伸 4 * 12\n" +
"俯身哑铃臂屈伸 4 * 12\n");
list1.add("周六:背 + 二头\n" +
"\n" +
"哑铃二头交替弯举 4*12\n" +
"哑铃二头交替锤式弯举 4*12\n" +
"杠铃弯举 4*12\n" +
"杠铃21炮\n" +
"\n" +
"杠铃划船4*12\n" +
"划船机 4*12\n" +
"高位下拉 4*12\n" +
"哑铃划船 4*12\n");
list1.add("周日:肩 + 臀腿\n" +
"\n" +
"哑铃推肩 4 * 12\n" +
"哑铃飞鸟 4 * 16\n" +
"哑铃前平举 4* 16\n" +
"坐姿哑铃飞鸟 4 * 16\n" +
"蝴蝶机飞鸟 4 * 16\n" +
"\n" +
"杠铃硬拉 4 * 12\n" +
"固定杠铃深蹲 4 * 16\n" +
"负重踮脚 4 * 16\n" +
"卧姿腿弯举 4 * 16\n" +
"卷腹 4 * 16\n");
//新建一个适配器用于实现文本显示效果
myAdapter1 = new MyAdapter(list1,getContext());
recyclerView1.setAdapter(myAdapter1);
//manager1用于获取文本
LinearLayoutManager manager1 = new LinearLayoutManager(getContext());
manager1.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView1.setLayoutManager(manager1);
// Inflate the layout for this fragment
return view;
}
}
6.适配器:MyAdapter类
○ 在java包目录下新建一个MyAdapter类的java文件。
○ 每个fragment都会调用MyAdapter类中的方法。
○ MyAdapter用于实现中间内容的文本显示。
package com.example.as_homework1;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {
List<String> list1;
Context context1;
public MyAdapter(List list, Context context) {
list1 = list;
context1 = context;
}
@NonNull
@Override
//重写onCreateViewHolder()方法
public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context1).inflate(R.layout.item,parent,false);
MyHolder myHolder = new MyHolder(view);
return myHolder;
}
//重写onBindViewHolder()方法
public void onBindViewHolder(@NonNull MyHolder holder, int position) {
holder.textView.setText(list1.get(position));
}
@Override
//重写getItemCount()方法
public int getItemCount() {
return list1.size();
}
class MyHolder extends RecyclerView.ViewHolder{
TextView textView;
public MyHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView21);
}
}
}
7.MainActivity类
○ 用于进行每个组件的初始化。
○ 对用户的点击操作进行监听来实现tab间的切换。
package com.example.as_homework1;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Fragment fragment1, fragment2, fragment3, fragment4; //创建四个Fragment对象
FragmentManager fragmentManager;
LinearLayout LinearLayout1, LinearLayout2, LinearLayout3, LinearLayout4; //创建四个LinearLayout对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout1 = findViewById(R.id.LinearLayout1);
LinearLayout2 = findViewById(R.id.LinearLayout2);
LinearLayout3 = findViewById(R.id.LinearLayout3);
LinearLayout4 = findViewById(R.id.LinearLayout4);
fragmentManager = getSupportFragmentManager();
//自定义一个初始化函数
fragment1 = new fragment1(); //变量赋值
fragment2 = new fragment2();
fragment3 = new fragment3();
fragment4 = new fragment4();
initial(); //进行初始化
fragmentshow(fragment1);
fragmentshow(fragment2);
fragmentshow(fragment3);
fragmentshow(fragment4);
//对每个LinearLayout设置点击监听器
//监听器用于捕捉用户的点击行为
LinearLayout1.setOnClickListener(this);
LinearLayout2.setOnClickListener(this);
LinearLayout3.setOnClickListener(this);
LinearLayout4.setOnClickListener(this);
}
//fragmenthide()方法用于实现fragment的隐藏效果
private void fragmenthide() {
FragmentTransaction ft = fragmentManager.beginTransaction()
.hide(fragment1)
.hide(fragment2)
.hide(fragment3)
.hide(fragment4);
ft.commit();
}
//fragmentshow()方法用于实现fragment的显示效果
private void fragmentshow(Fragment fragment) {
fragmenthide();
FragmentTransaction ft = fragmentManager.beginTransaction()
.show(fragment);
ft.commit();
}
private void initial() {
FragmentTransaction transaction = fragmentManager.beginTransaction().add(R.id.content, fragment1)
.add(R.id.content, fragment2).add(R.id.content, fragment3).add(R.id.content, fragment4);
transaction.commit();
}
//onClick()方法用户实现fragment的点击切换
@Override
public void onClick(View view) {
if (view.getId() == R.id.LinearLayout1) {
fragmentshow(fragment1);
}
if (view.getId() == R.id.LinearLayout2) {
fragmentshow(fragment2);
}
if (view.getId() == R.id.LinearLayout3) {
fragmentshow(fragment3);
}
if (view.getId() == R.id.LinearLayout4) {
fragmentshow(fragment4);
}
}
}
8.程序界面设置:activity_main.xml
○ 在/res/layout目录存在一个activity_main.xml,使用LinearLayout垂直布局。
○ activity_main.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:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".MainActivity">
<include
layout="@layout/top"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
</FrameLayout>
<include
layout="@layout/bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"/>
</LinearLayout>
三、程序结果展示
○ 点击底部的icon可以实现在不同tab间的切换效果。
○ 每个icon页面均包含相应的列表内容,并可以进行滑动。
tab间的切换效果展示:
每个tab内的滑动效果展示:
四、源码的线上仓库
gitee的源码线上仓库地址:AS_homework1: This repository is for the code of my first homework of Android.