内容简介:
1.设计一个app的门户框架,需要实现4个tab切换效果;
2.在任一tab页实现列表效果;
3.用gitee将项目源码写明;
需求分析:
UI设计:
以手机微信主界面为例:应该将主界面分为三个版块,top,content,bottom;
top.xml
在top界面应该展示出该主界面的标题,即微信,在res.layout包里new一个top.xml文件,来写顶部的LinearLayout。顶部的设计比较简单 ,我们只需要新建一个LinearLayout,插入一个文本框,设置标题并使其居中,然后设置背景颜色为红色、文字颜色大小即可。
content
在content板块中,应该能够根据底部功能栏的切换而随之切换。即可以在AS中使用FrameLayout实现该功能,在FrameLayout中包含四个fragment部件对应四个功能栏即可。在res.layout包里新建四个tab.xml文件,在该界面插入文本框介绍该界面并使文字居中。
bottom.xml
在bottom板块中方,通过分析将其水平划分为四个水平方向上的LinearLayout。在res.layout包里new一个button.xml文件,来写底部部的LinearLayout。下面的button分成四块,每块由一个图标和一段文本构成。所以可以用LinearLayout中再包裹一个LinearLayout,被包裹的每个LinearLayout里包含一个ImageView和TextView控件。
列表实现
可以使用recycleview实现列表,连接其中一个tab界面,创建数据列表,并提供适配器进行展示。
代码模块讲解:
main.xml:
引入其他的xml文件应使用include语法,用"include" 将刚才写的top和button两个组件放到这个main.xml中来,然后中间用FrameLayout标签作为内容区,展示content板块。
该界面的整体布局应该是vertical LinearLayout。
<?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/content"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content"/>
<include
layout="@layout/bottom"/>
</LinearLayout>
bottom.xml:
在res.layout包里new一个button.xml文件,来写底部部的linearLayout。下面的button分成四块,每块由一个图标和一段文本构成。所以可以用LinearLayout中再包裹一个LinearLayout,被包裹的每个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/tab_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_weight="1"
android:src="@drawable/img" />
<TextView
android:id="@+id/textView_chat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="聊天"
android:textSize="30sp" />
在java中的包里创建4个FrameLayout,每个对应不同的界面内容,在FrameLayout类中只留下一个方法,剩下三个与其展示代码相似。代码内容如下:
package com.example.myapplication2;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class BlankFragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.tab1, container ,false);
}
}
并在res.layout 包里面new四个tab.xml文件配置framelayout,其中一个tab1.xml文件代码展示:
<?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:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="520dp"
android:gravity="center"
android:text="这是聊天界面"
android:textSize="50sp"/>
</LinearLayout>
Fragment.Java:
新建四个Java文件分别与四个tab.xml文件建立连接,展示其中一个Java文件的代码:
package com.example.myapplication2;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class BlankFragment2 extends Fragment {
// TODO: Rename and change types and number of parameters
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.tab2, container, false);
}
}
MainActivity.Java:
五个主要函数:onCreate,fragmentHide,initial,onClick,fragmentshow
onCreate:将各个Fragment实例化调用对应函数,当不做任何操作时默认展示第一页。
fragmentHide:在切换界面时,对其他界面进行隐藏。
initial:给Fragment页面初始化。利用activity_main.xml中间布局的控件id:content和fragmentManager将四个Fragment压入中间主体部分。
onClick:对底部按键框的四个按键进行监听,,根据监听结果调用fragment界面。利用条件语句实现。
fragmentshow:展示当前fragment界面
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
Fragment fragment1,fragment2,fragment3,fragment4;
FragmentManager fm;
LinearLayout linearLayout1;
LinearLayout linearLayout2;
LinearLayout linearLayout3;
LinearLayout linearLayout4;
@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);
fm = getSupportFragmentManager();
fragment1 = new BlankFragment1();
fragment2 = new BlankFragment2();
fragment3 = new BlankFragment3();
fragment4 = new BlankFragment4();
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(); //必须单独分行写
}
@Override
public void onClick(View view) { //view全屏幕
fragmentHide();
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);
}
private void fragmentshow(Fragment fragment){
FragmentTransaction transaction=fm.beginTransaction()
.show(fragment);
transaction.commit();
}
Recyclerview:
在tab1中添加recyclerview这个控件,修改其中参数,展示其中代码展示:
<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"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
item.xml:
创建一个item.xml用于展示列表中的样式展览,展示其中代码:
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:text="TextView"
android:textColor="#D62F2F"
android:textSize="35sp" />
其对应的BlankFragment1.Java文件:
在主函数中先连接tab1.xml,创建数据列表,并提供给适配器进行展示,代码展示:
package com.example.myapplication2;
import android.content.Context;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
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 BlankFragment1 extends Fragment {
View view;
RecyclerView recyclerview;
List<String> list;
Myadapter adapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.tab1, container, false);
recyclerview = view.findViewById(R.id.recyclerview);
list = new ArrayList<>();
for (int i = 0; i < 9; i++) {
list.add("这是第" + i + "行数据");
}
adapter = new Myadapter(view.getContext(), list);
recyclerview.setAdapter(adapter);
LinearLayoutManager manager = new LinearLayoutManager(view.getContext());
manager.setOrientation(RecyclerView.VERTICAL);
recyclerview.setLayoutManager(manager);
return view;
}
}
适配器adapter:
Myadapter.java文件中我们着重写三个方法:
-
onCreateViewHolder(),用于创建ViewHolder类,保存item中个控件的引用,方便后续的操作,使其连接到item.xml文件中
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;
}
-
onBindViewHolder(),用于将数据绑定到ViewHolder中的视图上
public void onBindViewHolder(@NonNull Myholder holder, int position) { holder.textView.setText(list1.get(position));
-
getItemCount(),返回数据源的大小,即需要显示的数据项数目 public int getItemCount() { return list1.size(); }
public int getItemCount() { return list1.size(); }
最后定义一个名为Myholder的自定义ViewHolder类,表示每个数据项的视图。
运行结果截图:
总结:
通过此次实验,发现在有些展示页面的调整下可以直接在design界面会相对容易一些,认识到在编写代码方面要熟练使用提示和快捷键补全。在进行xml文件与Java文件的连接的时候要将每个文件使用的id对应清楚,否则会出现运行成功但是不显示的问题,而且当发现运行成功但是打开的软件闪退,我们可以通过看日志来发现问题并及时解决。