AS移动开发--类微信界面的实现

预期目标:

设计一个app的门户框架,需要实现3-4个tab切换效果;

功能的实现要求需要的技术为:activity、xml、fragment;

在任一tab页中实现列表效果(本功能的实现需要使用recycleview)。

使用的软件:Andriod Studio

设计思路:

1.实现类微信界面:

将界面分为上、中、下三个子布局,分别为top.xml, tab.xml, button.xml文件,

中间部分的内容分别为tab1.xml,tab2.xml, tab3.xml,tab4.xml。

2.实现列表效果:

将任一tab页面的内容替换成列表。

设计过程:

一、xml页面布局

        XML文件被广泛用于定义Android应用程序的用户界面布局。通过XML可以描述界面中的视图组件、其相对位置关系、样式和属性等。Android使用一种叫做"层叠布局"的方式来解析和渲染这些XML布局文件,从而实现应用程序界面的显示。

1.设计头部布局top.xml

        根元素:布局的根元素是一个LinearLayout,通过xmlns属性指定了命名空间。

        LinearLayout属性:LinearLayout的属性设置为android:layout_width="match_parent"android:layout_height="match_parent",意味着它会占据父容器(通常是屏幕)的全部宽度和高度。

        子视图TextView:FrameLayout中添加了一个TextView作为子视图。TextView是一个文本视图,用于显示文本内容。 

        TextView属性:TextView的属性设置如下:

                android:id="@+id/微信":为TextView指定了一个唯一的ID。
                android:layout_width="match_parent"和android:layout_height="wrap_content":将TextView的宽度设置为与父容器相同,高度根据内容自适应。
                android:layout_weight="1":LinearLayout中有多个子视图时,通过设置权重来占据剩余空间的比例,这里将TextView的权重设置为1。
                android:background="#4CAF50":设置TextView的背景颜色为绿色。
                android:gravity="center":设置文本内容在TextView中的居中对齐。
                android:text="微信":设置TextView的文本内容为"微信"。
                android:textColor="@color/white":设置文本颜色为白色。
                android:textSize="40sp":设置文本大小为40sp 。

<?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">

        <TextView
            android:id="@+id/微信"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#4CAF50"
            android:gravity="center"
            android:text="微信"
            android:textColor="@color/white"
            android:textSize="40sp" />
</LinearLayout>

设计界面展示:

2.设计底部布局bottun.xml

先创建一个水平布局的LinearLayout作为父容器,再创建四个垂直布局的LinearLayout子布局,子布局包含一个图片视图和一个居中对齐的文本视图。

     

  1. 根元素:布局的根元素是一个LinearLayout。

  2. LinearLayout属性:LinearLayout的属性设置为android:layout_width="match_parent"android:layout_height="wrap_content",意味着它会占据父容器的全部宽度,高度根据内容自适应。

  3. LinearLayout:android:orientation="horizontal",布局中组件的排列方式,有horizontal(水平)和vertical(垂直)两种方式。

  4. 子视图LinearLayout1:第一个LinearLayout作为一个底部导航栏中的一个按钮,设置与父容器宽度相等的宽度,并设置权重为1。

  5. ImageView:LinearLayout1中添加了一个ImageView,用于显示一个图标。ImageView的属性设置如下:

    • android:id="@id/imageView1":为ImageView指定了一个唯一的ID。
    • android:layout_width="match_parent"android:layout_height="wrap_content":将ImageView的宽度设置为与父容器相同,高度根据内容自适应。
    • android:contentDescription="消息":设置图标的内容描述为"消息"。
    • android:src="@android:drawable/ic_menu_send":设置图标的资源为系统提供的ic_menu_send图标。
  6. TextView:LinearLayout1中添加了一个TextView,用于显示一个文本标签。TextView的属性设置如下:

    • android:id="@+id/textView1":为TextView指定了一个唯一的ID。
    • android:layout_width="match_parent"android:layout_height="wrap_content":将TextView的宽度设置为与父容器相同,高度根据内容自适应。
    • android:gravity="center":设置文本内容在TextView中的居中对齐。
    • android:text="消息":设置TextView的文本内容为"消息"。
    • android:textSize="25sp":设置文本大小为25sp。

其他三个LinearLayout中分别包含一个ImageView和一个TextView,用于显示不同的图标和文本标签。

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/bottun"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <LinearLayout
        android:id="@+id/LinearLayout1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        tools:ignore="UseCompoundDrawables">

        <ImageView
            android:id="@id/imageView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:contentDescription="消息"
            android:src="@android:drawable/ic_menu_send" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="消息"
            android:textSize="25sp" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/LinearLayout2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        tools:ignore="UseCompoundDrawables">

        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:contentDescription="联系人"
            android:src="@android:drawable/ic_menu_call" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="联系人"
            android:textSize="25sp" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/LinearLayout3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        tools:ignore="UseCompoundDrawables">

        <ImageView
            android:id="@+id/imageView3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:contentDescription="设置"
            android:src="@android:drawable/ic_menu_preferences" />

        <TextView
            android:id="@+id/textView3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="设置"
            android:textSize="25sp" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/LinearLayout4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        tools:ignore="UseCompoundDrawables">

        <ImageView
            android:id="@+id/imageView4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:contentDescription="朋友圈"
            android:src="@android:drawable/ic_menu_gallery" />

        <TextView
            android:id="@+id/textView4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="朋友圈"
            android:textSize="25sp" />
    </LinearLayout>
</LinearLayout>

设计界面展示:

3.设计中间布局fragment_1.xml

FrameLayout是一种布局容器,用于在Android应用程序中展示视图。允许子视图被放置在堆叠顺序中,进而进行界面整合。

  1. FrameLayout属性:FrameLayout的属性设置如下:

            android:layout_width="match_parent"android:layout_height="match_parent":设置FrameLayout的宽度和高度都为与父容器匹配。
  2. TextView:在FrameLayout中添加了一个TextView作为子视图,用于显示文本内容。TextView的属性设置如下:

    • android:layout_width="match_parent"android:layout_height="match_parent":将TextView的宽度和高度都设置为与父容器匹配,填满整个FrameLayout。
    • android:textSize="45dp":设置文本大小为45dp。
    • android:text="这是微信界面":设置文本内容为"这是微信界面"。
    • android:gravity="center":设置文本内容在TextView中的居中对齐。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".Fragment1">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="45dp"
        android:text="这是微信界面"
        android:gravity="center"/>

</FrameLayout>

设计界面展示:

4.tab布局(tab1.xml、tab2.xml、tab3.xml、tab4.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">

    <TextView
        android:id="@+id/textView5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_gravity="center"
        android:gravity="center"
        android:text="这是聊天界面!"
        android:textSize="45dp"/>
</LinearLayout>

tab1设计界面展示:

5.设计整合布局main_Activity.xml
  1. LinearLayout属性:LinearLayout的属性设置如下:

    • android:layout_width="match_parent"android:layout_height="match_parent":设置LinearLayout的宽度和高度都为与父容器匹配。
    • android:orientation="vertical":设置LinearLayout的子视图垂直排列。
  2. include元素:include元素用于将其他布局文件引入到当前布局中,实现布局的复用性。在这个示例中,有两个include元素:

    • 第一个include元素引用了名为"top"的布局文件,并将其作为LinearLayout的子视图。通过layout="@layout/top"指定引入的布局文件路径。
    • 第二个include元素引用了名为"bottun"的布局文件,并将其作为LinearLayout的子视图。通过layout="@layout/bottun"指定引入的布局文件路径。
  3. FrameLayout:LinearLayout中的第三个元素是一个FrameLayout,用于显示内容。FrameLayout的属性设置如下:

    • android:layout_width="match_parent"android:layout_height="0dp":将FrameLayout的宽度设置为与父容器匹配,并将高度设置为0dp。
    • android:layout_weight="1":设置FrameLayout在垂直方向上占据剩余空间。

该布局文件实现了一个垂直排列的界面,包含一个顶部布局、一个可变内容区域的FrameLayout和一个底部布局。顶部和底部布局通过include引入,而FrameLayout用于动态显示不同的内容。

<?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="match_parent"
    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="0dp"
        android:layout_weight="1">
    </FrameLayout>

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

</LinearLayout>

整合布局界面展示:

二、创建Java文件

创建4个Fragment文件:

当在Android应用中使用Fragment时,通常会在布局文件中包含一个用于容纳Fragment的FrameLayout,并在代码中将具体的Fragment添加到该容器中。

在每个Fragment中添加相应的tab:

Fragment1:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.tab1, container, false);
    }

onCreateView() ,通过 LayoutInflater 将 XML 布局文件 R.layout.tab1 实例化为一个 View 对象,并将其返回作为 Fragment 的视图。inflater.inflate() 方法的第三个参数是一个布尔值,表示是否将生成的 View 添加到 container 容器中。
 

MainActivity:实现导航栏和 Fragment布局 切换功能
 

1.在onCreate中定义四个 Fragment:Fragment1Fragment2Fragment3 和 Fragment4。用来实现tab.xml界面显示。

2.定义FragmentManager 类型的变量 fm,用于管理 Fragment 对象的生命周期和切换操作。

3.定义四个 LinearLayout 类型的变量:linearLayout1、linearLayout2、linearLayout3 和 linearLayout4,通过findViewById方法找到FrameLayout容器,实现button.xml界面显示。

        fragment1=new Fragment1();
        fragment2=new Fragment2();
        fragment3=new Fragment3();
        fragment4=new Fragment4();
        fm=getSupportFragmentManager();

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

4.定义initial() 方法用于初始化 Fragment。

  1. 获取FragmentManager实例:通过FragmentManager fm = this.getSupportFragmentManager();获取FragmentManager实例。

  2. 开启一个Fragment事务:通过fm.beginTransaction()开启一个Fragment事务,并获取到对应的FragmentTransaction对象。

  3. 添加Fragment到事务中:通过add方法向事务中添加对应的Fragment实例,这里将四个Fragment都添加到了同一个事务中,并且都添加到了名为content的布局容器中。

  4. 提交事务:通过调用commit方法提交事务,将添加操作生效。

    private void initial() {
        FragmentTransaction ft=fm.beginTransaction()
                .add(R.id.content,fragment1)
                .add(R.id.content,fragment2)
                .add(R.id.content,fragment3)
                .add(R.id.content,fragment4);
        ft.commit();
    }

5.定义Fragmenthide()用于隐藏Fragment,将所有的fragment界面都隐藏,避免重叠显示。

    private void fragmenthide() {

        FragmentTransaction ft=fm.beginTransaction()
                .hide(fragment1)
                .hide(fragment2)
                .hide(fragment3)
                .hide(fragment4);
        ft.commit();
    }

6.定义fragmentshow(),用于展示Fragment相应的tab.xml界面。

 private void fragmentshow(Fragment fragment) {
        FragmentTransaction transaction=fm.beginTransaction()
                .show(fragment);
        transaction.commit();
    }

7.定义onClick() 实现了 View.OnClickListener 接口,用于处理底部导航栏中选项的点击事件。

public void onClick(View view)
    {
        fragmenthide();
        /*switch (view.getId())
        {
            case R.id.LinearLayout1 : fragmentshow(fragment1);
            case R.id.LinearLayout2 : fragmentshow(fragment2);
            case R.id.LinearLayout3 : fragmentshow(fragment3);
            case R.id.LinearLayout4 : fragmentshow(fragment4);
            default:   break;
        }*/
        if (view.getId()==R.id.LinearLayout1)
            fragmentshow(fragment1);
        else if (view.getId()==R.id.LinearLayout2) {
            fragmentshow(fragment2);
        } else if (view.getId()==R.id.LinearLayout3) {
            fragmentshow(fragment3);
        } else if (view.getId()==R.id.LinearLayout4) {
            fragmentshow(fragment4);
        }
    }

整合代码:

package com.example.myapplication;
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;
    Fragment fragment2;
    Fragment fragment3;
    Fragment fragment4;
    FragmentManager fm;
    FragmentTransaction ft;
    LinearLayout linearLayout1,linearLayout2,linearLayout3,linearLayout4;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fragment1=new Fragment1();
        fragment2=new Fragment2();
        fragment3=new Fragment3();
        fragment4=new Fragment4();
        fm=getSupportFragmentManager();

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


        initial();
        fragmenthide();
        fragmentshow(fragment1);

        linearLayout1.setOnClickListener(this);
        linearLayout2.setOnClickListener(this);
        linearLayout3.setOnClickListener(this);
        linearLayout4.setOnClickListener(this);

    }

    private void fragmenthide() {

        FragmentTransaction ft=fm.beginTransaction()
                .hide(fragment1)
                .hide(fragment2)
                .hide(fragment3)
                .hide(fragment4);
        ft.commit();
    }

    private void initial() {
        FragmentTransaction ft=fm.beginTransaction()
                .add(R.id.content,fragment1)
                .add(R.id.content,fragment2)
                .add(R.id.content,fragment3)
                .add(R.id.content,fragment4);
        ft.commit();
    }

    public void onClick(View view)
    {
        fragmenthide();
        /*switch (view.getId())
        {
            case R.id.LinearLayout1 : fragmentshow(fragment1);
            case R.id.LinearLayout2 : fragmentshow(fragment2);
            case R.id.LinearLayout3 : fragmentshow(fragment3);
            case R.id.LinearLayout4 : fragmentshow(fragment4);
            default:   break;
        }*/
        if (view.getId()==R.id.LinearLayout1)
            fragmentshow(fragment1);
        else if (view.getId()==R.id.LinearLayout2) {
            fragmentshow(fragment2);
        } else if (view.getId()==R.id.LinearLayout3) {
            fragmentshow(fragment3);
        } else if (view.getId()==R.id.LinearLayout4) {
            fragmentshow(fragment4);
        }
    }

    private void fragmentshow(Fragment fragment) {
        FragmentTransaction transaction=fm.beginTransaction()
                .show(fragment);
        transaction.commit();
    }

}

完整界面展示:

三、实现列表效果

1.修改tab2.xml(联系人)界面

修改为recycleview布局

<?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/recycleview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"/>

</LinearLayout>
2.新建item.xml,设计列表布局格式,做为内容容器填充到recyclerview中去
<?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="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"

        android:text="TextView"
        android:textColor="@color/black"
        android:textSize="35sp" />
</LinearLayout>
3.添加Myadapter.java,用于将数据绑定到 RecyclerView 中进行显示。
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;


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

        Myholder holder = new Myholder(view);

        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull Myholder holder, int position) {
        holder.textView.setText(list1.get(position));
    }

    @Override
    public int getItemCount() {
        return list1.size();
    }

    public class Myholder extends RecyclerView.ViewHolder{
        TextView textView;
        public Myholder(@NonNull View itemView) {
            super(itemView);
            textView=itemView.findViewById(R.id.textView1);
        }
    }
}
4.对Fragment2.java(联系人界面)进行修改
  1. 创建视图:通过LayoutInflater的inflate方法将布局文件tab2(R.layout.tab2)转换为View对象,并传入了container(父容器)和false(是否将返回的View添加到父容器中)。

  2. 初始化RecyclerView:获取到视图中的RecyclerView控件,并将其与成员变量recyclerView关联。

  3. 创建数据列表:初始化了一个空的ArrayList,并使用循环向其中添加了9个字符串元素。

  4. 创建适配器并设置给RecyclerView:实例化了MyAdapter适配器,并将上下文和数据列表传入构造函数。然后将适配器设置给RecyclerView。

  5. 设置RecyclerView布局管理器:创建LinearLayoutManager布局管理器的实例manager,并将其方向设置为垂直。最后将布局管理器设置给RecyclerView。

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 Fragment2 extends Fragment{   //继承自Fragment类的Fragment3类。在该类中,重写了onCreateView方法用于创建视图
    private RecyclerView recyclerView;
    private List<String> list= new ArrayList<>();
    private Context context;
    private Myadapter myadapter;

    @SuppressLint("MissingInflatedId")
    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
        View view=inflater.inflate(R.layout.tab2,container,false);
        context=view.getContext();
        recyclerView=view.findViewById(R.id.recycleview);
        list=new ArrayList();
        for (int i=0; i<9;i++)
        {
            list.add("这是第"+i+"行数据");
        }
        myadapter = new Myadapter(context,list);
        recyclerView.setAdapter(myadapter);
        LinearLayoutManager manager=new LinearLayoutManager(context);
        manager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(manager);

        return view;

    }
}

界面展示:

四、总结

        1.高版本的AS中,默认情况下资源 id 将是非final 的,使用它们在 switch case 语句中可能会导致编译错误。使用 if-else 语句更具灵活性,并且通常不会受到工具链和编译器的限制。

        2.特别注意界面设计的id,不要重名。

        3.巧用快速修复,大部分问题都能被快速修复。

五、仓库链接

github-ASweixin

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值