AS开发作业(1)---微信app门户页面设计与开发

发布时间 2023-10-15 00:56:33作者: 小光翎

一、项目目标

1.设计一个app的门户框架,需要实现3-4个tab切换效果,本功能要求需要的技术为:activity、xml、fragment

2.在任一tab页中实现列表效果,本功能的实现需要使用recycleview;

二、项目开发版本

开发工具:Android Studio

版本:API 34,Android 13.0

三、项目设计

项目预期设计: 主要由顶部的“微信”、中间的界面与底部的图标与文字构成。除了页面布局,还需要完成聊天、联系人、位置、设置四个页面的跳转,在聊天界面实现列表功能。

                                                                  

 

项目文件主要构成

 

四、项目技术与代码解析

layout布局代码与解析:

  1.顶部“微信”标题

 

<?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:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/black"
        android:gravity="center"
        android:text="微信"
        android:textColor="@color/white"
        android:textSize="30sp" />

</LinearLayout>
top.xml

 

注意,layout布局中:

match_parent:大小由父布局决定,即宽或高和父布局一样。
wrap_content:该控件布局的宽或高由内容的长度决定。
设置固定值,可以是30dp,也可以是120dp,但想要设置为0dp,必须有weight属性(空间占比),且值不为0才可以

  

  2.底部图标

<?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"
    android:background="@color/black">

    <LinearLayout
        android:id="@+id/LinearLayout1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/imageView11"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@drawable/chat" />

        <TextView
            android:id="@+id/textView11"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="聊天"
            android:textColor="@color/white"
            android:textSize="30sp" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/LinearLayout2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/imageView22"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@drawable/contact" />

        <TextView
            android:id="@+id/textView22"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="联系人"
            android:textColor="@color/white"
            android:textSize="30sp" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/LinearLayout3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/imageView33"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@drawable/location" />

        <TextView
            android:id="@+id/textView33"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="位置"
            android:textColor="@color/white"
            android:textSize="30sp" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/LinearLayout4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/imageView44"
            android:layout_width="115dp"
            android:layout_height="100dp"
            android:src="@drawable/sign" />

        <TextView
            android:id="@+id/textView44"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="设置"
            android:textColor="@color/white"
            android:textSize="30sp" />
    </LinearLayout>

</LinearLayout>
button.xml

该部分主要由四个垂直方向的linearlayout线性布局水平布局组成,每个布局中包括一个图标(ImageView)和对应界面名称(TextView),效果如图:

  

  3.中间布局界面,包含主界面main、四个跳转界面tab(tab1/2我做了列表界面,使用了RecyclerView控件,tab3/4是普通界面,使用TextView控件,代码都只放一个为例)和列表行界面item(用来设计列表每一行中的元素布局,这里只放了一个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="match_parent">


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp" />
</LinearLayout>
tab1.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="wrap_content">

    <TextView
        android:id="@+id/textView8"
        android:layout_width="match_parent"
        android:layout_height="520dp"
        android:layout_gravity="center"
        android:gravity="center"
        android:layout_weight="1"
        android:text="这是位置界面"
        android:textSize="50sp" />
</LinearLayout>
tab3.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="wrap_content">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="95dp"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:background="@drawable/shape"
        android:text="TextView"
        android:textColor="@color/black"
        android:textSize="35sp" />
</LinearLayout>
item.xm1
<?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:orientation="vertical">

    <include layout="@layout/top" />

    <FrameLayout
        android:id="@+id/content1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1">
    </FrameLayout>

    <include layout="@layout/button" />
</LinearLayout>
main.xml

main.xml中的FrameLayout布局会指定屏幕上的一块空白区域,本项目中只屏幕中间界面,并分隔开了top和button部分。FrameLayout允许我们在该区域中叠加多个子视图后添加的会覆盖在前添加的视图之上。结合FrameLayout的这一特性和fragment(后文会提到)就可以实现四个界面的切换。最终main.xml(屏幕布局)效果如下:

                                                                              

 

Activity用户界面与Fragment模块:

  1.Fragment模块(该模块有四个,对应4个tab,同样代码以1、3为例)

package com.example.myapplication;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;

import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;


public class Fragment1 extends Fragment {

    RecyclerView recyclerview;
    List<String> list;
    Myadapter adapter;
    Context context;

    @SuppressLint("MissingInflatedId")
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view=inflater.inflate(R.layout.tab1, container, false);
        recyclerview= view.findViewById(R.id.recyclerview);

        list=new ArrayList<String>();//是一个数组,但是链表存储

        context=getContext();

        for (int i=1;i<=6;i++){
            list.add("宝贝"+i+"号");
        }

        adapter=new Myadapter(context,list);//list给adpter

        recyclerview.setAdapter(adapter);

        LinearLayoutManager manager=new LinearLayoutManager(context);
        manager.setOrientation(RecyclerView.VERTICAL);
        recyclerview.setLayoutManager(manager);//控制列表上下左右
        // Inflate the layout for this fragment
        return view;//压缩,整个屏幕的xml压缩到局部
    }
}
fragment1.java
package com.example.myapplication;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;


public class Fragment3 extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.tab3, container, false);//压缩,整个屏幕的xml压缩到局部
    }
}
fragment3.java

  首先都通过inflate函数将四个tab界面压缩到局部即屏幕中间获得视图view,交由fragment模块来控制。为了提高代码重用性和改善用户体验,一个Activity页面中可以包含多个Fragment模块,进行分组和模块化管理。在fragment1中,利用view来创建列表对象RecyclerView,生成要显示的list,传给Myadapter适配器连接数据与RecyclerView,即将数据映射到列表上。

Myadapter代码:

package com.example.myapplication;

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;
import java.util.zip.Inflater;

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) {

        //Inflater,java的真的zip压缩器,不是我们要的

        View view=LayoutInflater.from(context1).inflate(R.layout.item,parent,false); //官方压缩器
        //inflater返回值是一个view(压缩后的)
        Myholder myholder=new Myholder(view);
        return myholder;//把每行数据inflater压缩
    }

    @Override
    public void onBindViewHolder(@NonNull Myholder holder, int position) {

        holder.textView.setText(list1.get(position));//get也不确定返回类型,list要给定,自动返回string

    }//bind绑定,连接list数据和viewholder(指向行的指针,java没有指针,自定义viewholder的子类因为每行数据类型不确定)

    @Override
    public int getItemCount() {
        return list1.size();
    }//数据绑定,list有多少行

    public class Myholder extends RecyclerView.ViewHolder{

            TextView textView;
        public Myholder(@NonNull View itemView) {
            super(itemView);

            textView=itemView.findViewById(R.id.textView1);
        }

    }//泛型传入viewholder类
}
Myadapter.java

 

  2.MainActivity用户界面

Fragment模块中,我们将四个tab压入四个fragment,可以通过fragment模块化管理进行页面的隐藏和显示,即页面切换。在MainActivity中,主要包含以下一个方法:

(1).初始化Fragment

    private void initial() {

        FragmentTransaction ft=fm.beginTransaction()
                .add(R.id.content1,fragment1)
                .add(R.id.content1,fragment2)
                .add(R.id.content1,fragment3)
                .add(R.id.content1,fragment4);
        ft.commit();//get也没有,交互实例基于管理器,以commit形式提交,ft是事务执行对象,commit前面的都是事务,commit和执行要分开进行
    }//初始化
初始化

(2).显示与隐藏Fragment

    private void fragmenthide() {
        FragmentTransaction ft=fm.beginTransaction()
                .hide(fragment1)
                .hide(fragment2)
                .hide(fragment3)
                .hide(fragment4);//隐藏之后涉及点击功能
        ft.commit();
    }//初始隐藏字幕


    private void fragmentshow(Fragment fragment) {
        FragmentTransaction ft=fm.beginTransaction()
                .show(fragment);
        ft.commit();
    }//显示
显示与隐藏

(3).MainActivity主体代码与图标点击,对应动作实现切换界面

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    Fragment fragment1,fragment2,fragment3,fragment4;

    FragmentManager fm;//fragment管理器
    //FragmentTransaction ft;//fragment交互(通信一对一,交互是批量动作,带commit),放外面不利于事务独立性,函数都可以用

    LinearLayout linearLayout1,linearLayout2,linearLayout3,linearLayout4;

    @SuppressLint("MissingInflatedId")

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        linearLayout1=findViewById(R.id.LinearLayout1);
        linearLayout2=findViewById(R.id.LinearLayout2);
        linearLayout3=findViewById(R.id.LinearLayout3);
        linearLayout4=findViewById(R.id.LinearLayout4);

        fragment1=new Fragment1();
        fragment2=new Fragment2();
        fragment3=new Fragment3();
        fragment4=new Fragment4();
        fm=getSupportFragmentManager();//new用不了用get,new要重写构造函数

        initial();//初始化

        fragmenthide();//隐藏字幕
        fragmentshow(fragment1);//默认聊天界面

        //屏幕click监听,全局监听以免代码冗余
        linearLayout1.setOnClickListener(this);
        linearLayout2.setOnClickListener(this);
        linearLayout3.setOnClickListener(this);
        linearLayout4.setOnClickListener(this);

    }

    public void onClick(View view) {

        //点一个再点一个会叠加?

        fragmenthide();

        int id=view.getId();
        if(id==R.id.LinearLayout1) {
            fragmentshow(fragment1);
        }
        if(id==R.id.LinearLayout2) {
            fragmentshow(fragment2);
        }
        if(id==R.id.LinearLayout3){
            fragmentshow(fragment3);
        }
        if(id==R.id.LinearLayout4) {
            fragmentshow(fragment4);
        }


    }//点击
MainActivity主体与点击

注意:在初始化底部图标的对象(4个linearlayout,用来点击)和fragment后,要先隐藏四个界面,只默认显示第一个界面,不然会产生四个界面的重叠(上文frameout中介绍过)。同理,在点击下一个页面之前要将所有界面进行隐藏。

 

五、项目展示