作业目标:根据课上所学,模拟微信门户界面并zai某一页中实现列表功能。
技术支持:layout xml、drawable view、fragment、onClick、recyclerview等。
思路描述:整体页面布局分为上中下部分,上方为微信名框,中间是单独页面显示,下方为多功能栏,因此要使用三个xml文件来完成三部分构成,最后用一个main xml文件把三个部分整合在一起。 切换页面:选择四个fragment布局叠加,然后利用java方法实现界面的切换和隐藏。 列表实现:选择在fragme1实现列表布局,故只需要在showFragment1方法内修改即可。
一、UI实现过程:
(1)门户界面布局(使用xml)
总共三个部分:顶部、底部选择栏、中间主体部分。
1、顶部标题栏
右击鼠标new一个名为top.xml的新文件,再在design界面的控件栏内选择linearlayout布局,选择水平布局,再将textview控件拖入textview框,如下:
随后是确定顶部栏字体大小、颜色、背景颜色,这里采用黑底白字。
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"
android:layout_gravity="top"
android:orientation="vertical">
<TextView
android:id="@+id/TextView5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/black"
android:baselineAligned="false"
android:gravity="center"
android:text="微信"
android:textColor="@color/white"
android:textSize="40sp"/>
</LinearLayout>
2、底部选择栏
初步流程同上,new出新的bottom.xml文件后先选择一个垂直布局(便于划分四个选项栏),再向水平布局拖入四个优先度一致(即平行)的水平线性布局,每个水平布局内拖入一个imageview和textview(注意imageview要在textview上面),然后将每个imageview绑定你需要的图标———要向image view导入图片,右键点击image view并选择set sample data,点击出现图库右下角的browse即可选择已导入drawable的图片即可(图片尺寸在code区内修改),显示如下:
四段代码相似度较高,只需要改一下参数,故只显示一段:
<LinearLayout
android:id="@+id/wx"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@tools:sample/avatars"
tools:src="@drawable/wx" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="微信"
android:textColor="@color/black"
android:textSize="24sp" />
</LinearLayout>
3、中间主体部分
新建四个xml文件,分别命名为fragment1~4,每个xml文件内包括一个水平的layout布局,并插入textview,方式同上,文本内容按自己喜好设定,为了便于识别,在这里使用亮紫色字体,四个界面大同小异,故只放其中一张图片,显示如下:
四段代码也是相似度很高,因此只需要放一段代码进行参考:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".showFragment7" >
<TextView
android:id="@+id/textView7"
android:layout_width="match_parent"
android:layout_height="700dp"
android:gravity="center"
android:text="这是微信界面"
android:textSize="50sp"
android:textColor="@color/purple_500"/>
</LinearLayout>
4、三部分整合
建立一个名为activity_main的xml文件,将顶部和底部导入该文件中,fragment的文件暂时不用,过程同上类似,就不过多赘述了。直接放图:
代码显示(可以按自己想要的来设置参数):
<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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".ui.theme.mainActivity">
<include
android:id="@+id/top"
layout="@layout/top"
android:layout_gravity="top"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="@+id/id_content"
android:layout_width="match_parent"
android:layout_height="520dp"
android:layout_weight="1"
app:layout_constraintBottom_toTopOf="@id/bottom"
app:layout_constraintTop_toBottomOf="@id/top">
</FrameLayout>
<include
android:id="@+id/bottom"
layout="@layout/bottom"
android:layout_width="match_parent"
android:layout_height="80dp"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="0dp" />
</LinearLayout>
(2)Java段
根据讲授内容,实现界面跳转要涉及到as中的活动思想:as中的每个活动最多存在运行、暂停、停止、销毁四种状态。
要实现实验内容,我们可以设想控件完成任务的过程并确定变量名(注意起变量名的时候要保证意义明确)
- 调用程序,为其命名为onCreate,作用是在activity完成初始化以后能够被成功调用
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); linearLayout1 = findViewById(R.id.wx); linearLayout2 = findViewById(R.id.txl); linearLayout3 = findViewById(R.id.fx); linearLayout4 = findViewById(R.id.wd); manager = getSupportFragmentManager(); fragment1 = new showFragment1(); fragment2 = new showFragment2(); fragment3 = new showFragment3(); fragment4 = new showFragment4(); initial(); fragmentHide(); showfragment(fragment1); linearLayout1.setOnClickListener(this); linearLayout2.setOnClickListener(this); linearLayout3.setOnClickListener(this); linearLayout4.setOnClickListener(this); }
- 初始化程序,为其命名为initial,完成初始化
public void initial() { transaction = manager.beginTransaction() .add(R.id.id_content, fragment1) .add(R.id.id_content, fragment2) .add(R.id.id_content, fragment3) .add(R.id.id_content, fragment4) .commit(); }
- 点击方法,为其命名为onClick,作用是输入设备发出信息(如键鼠点击)后获取控件信息
public void onClick(View view) { fragmentHide(); if (view.getId() == R.id.wx) showfragment(fragment1); else if (view.getId() == R.id.txl) showfragment(fragment2); else if (view.getId() == R.id.fx) showfragment(fragment3); else if (view.getId() == R.id.wd) showfragment(fragment4); }
- 显示界面,为其命名为showfragment,此时屏幕上会显示点击(click)后的内容
private void showfragment(Fragment fragment) { transaction = manager.beginTransaction() .show(fragment) .commit(); }
- 隐藏界面,为其命名为fragmentHide为保证四个界面上的text不重叠,需要保证在点击一个界面时,其他三个界面都隐藏
public void fragmentHide() {
transaction = manager.beginTransaction()
.hide(fragment1)
.hide(fragment2)
.hide(fragment3)
.hide(fragment4)
.commit();
}
(3)实现效果(x四张图片较为相似,因此只在这里放出两张)
二、在某一界面实现列表功能
创建一个recyclerview的方法
package com.example.homework_1.ui.theme;
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.homework_1.R;
import java.util.ArrayList;
import java.util.List;
public class showFragment1 extends Fragment{
View view;
Myadapter adapter;
RecyclerView recyclerView;
List<String> list;
public showFragment1() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment1, container, false);
recyclerView = view.findViewById(R.id.recycleview);
list = new ArrayList<>();
for(int i=0;i<10;i++) {
list.add("这是第"+i+"行消息");
}
adapter=new Myadapter(view.getContext(), list);
LinearLayoutManager manager=new LinearLayoutManager(view.getContext());
manager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(manager);
recyclerView.setAdapter(adapter);
return view;
}
}
再在实例中新建一个myadapter的Java方法
package com.example.homework_1.ui.theme;
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 com.example.homework_1.R;
import java.util.List;
public class Myadapter extends RecyclerView.Adapter<Myadapter.Myholder> {
Context context1;
List<String> list1;
public Myadapter(Context context,List list) {
context1=context;
list1 = list;
}
@NonNull
@Override
public Myholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(context1).inflate(R.layout.item,parent,false);
// Inflater inflater=new Inflater(); 这个压缩是像文件压缩一样的真压缩
return new Myholder(view);//holder可以控制控件
}
@Override
public void onBindViewHolder(@NonNull Myholder holder, int position) {
holder.textView.setText(list1.get(position));//值 与控件绑定,这么写报错与list里面的值有关,get不能确定参数类型
}
public int getItemCount(){
return list1.size();
}
public static class Myholder extends RecyclerView.ViewHolder{//定义这个类时,报错的现删掉,再重新补一次,补回来就不报错了
TextView textView;
public Myholder( View itemView)//嵌套类,在外面类中会直接调用里面的MYHolder类的对象,泛型传入,不是对象传值
{
super(itemView);
textView=itemView.findViewById(R.id.textView6);
}
}
}
完成以后layout文件夹中会出现recycview的xml文件,向里面添加一个recycview控件,方法同上:
然后在layout文件夹中创建一个名为item的xml文件,代码段如下:
<androidx.constraintlayout.widget.ConstraintLayout 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:background="@color/white"
android:orientation="horizontal">
<TextView
android:id="@+id/textView6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="TextView"
android:textColor="@color/design_default_color_secondary"
android:textSize="40sp" />
</LinearLayout>
完成这些工作以后开始进行调试,run完得到结果如下:
到这里就差不多了,一些注意事项和心得会放在总结里
三、实验小结
本次实验只是对微信界面进行简单模仿,实验难度并不算很大,但对于像我这样的初学者来说依旧有很多要注意的事项。本次实验中遇到了一些棘手的的情况:其一是自己声明的一些类在方法内根本无法使用,定义完以后整个语句就变灰了,后来查阅资料到settings里面修改了import的设置才发现,as支持自动声明,这也说明了写代码并不一定非要拘泥于形式,至少这些快捷工具能够很大程度解放你的双手,因此熟悉这些工具也是我们重要的一课。其二是我在调试代码的时候发现编译以后并没有报错,然而一运行起来模拟app界面便会闪退,改了很多遍都无功而返,后来发现同学也有类似情况,询问以后发现我的as的主题定义有问题,且sdk出现了问题,修复并且修改as软件包的gradle文本以后整个程序正常运行。