作业目标:
1.根据课程内容设计一个app的门户框架,需要实现3-4个tab切换效果;本功能要求需要的技术为:activity、xml、fragment
2、在任一tab页中实现列表效果;本功能的实现需要使用recycleview;
内容和关键代码解析:
1.整体布局预览:
Java控件
xml资源框架
2.文件功能说明:
xml文件
即可扩展标记语言文件,想搭积木一样,把一个一个基础的数据结构拼接起来:
简单文件如
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">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/black"
android:gravity="center"
android:text="我的微信"
android:textColor="@color/white"
android:textSize="25dp" />
</LinearLayout>
item.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:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/item"
android:textSize="20sp"
android:padding="12px"
android:text="hello world"/>
</LinearLayout>
以及四个fragment等等:
这种只有一个模块,几个字的
复杂的如button.xml:
八个板块构成的四个“linearlayout”(线性布局),排成一排
<?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">
<LinearLayout
android:id="@+id/LinearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:background="@color/black"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@android:drawable/ic_menu_call" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="微信"
android:textColor="@color/white"
android:textSize="25dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/LinearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:background="@color/black"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@android:drawable/ic_delete" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="通讯录"
android:textColor="@color/white"
android:textSize="25dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/LinearLayout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:background="@color/black"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@android:drawable/btn_star_big_on" />
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="发现"
android:textColor="@color/white"
android:textSize="25dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/LinearLayout4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/black"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@android:drawable/ic_input_add" />
<TextView
android:id="@+id/textView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="我"
android:textColor="@color/white"
android:textSize="25dp" />
</LinearLayout>
</LinearLayout>
以及include上面提到的top.xml和button.xml的总体布局的
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="match_parent"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="@layout/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="0dp"
android:layout_weight="1">
</FrameLayout>
<include
layout="@layout/button"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
以上就是xml文件的介绍,全部代码会附在文末的链接中
接下来介绍
java控件
后三个fragment类:
234都大同小异,只用重写Fragment父类的createview方法即可
public class Wechat2Fragment extends Fragment {
public Wechat2Fragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_wechat2, container, false);
}
}
return inflater.inflate(R.layout.fragment_wechat2, container, false);
不同的类只用把对应的返回值修改为需要引用的资源即可:fragment_wechat1/2/3/4
WechatFragment.java
文件和其他的略有不同,因为我将fragment_wechat1作为实现列表效果的那一个tab,所以在创建对象时要额外实现recycleview类的有关方法:
public class WechatFragment extends Fragment {
private Context context;
private RecyclerView recyclerView;
private MyAdapter myadapter;
public WechatFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
View view=inflater.inflate(R.layout.fragment_wechat,container,false);
context=view.getContext();
recyclerView=view.findViewById(R.id.rv_main);
myadapter = new MyAdapter(context);
recyclerView.setAdapter(myadapter);
LinearLayoutManager manager=new LinearLayoutManager(context);
manager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(manager);
return view;
}
}
View view=inflater.inflate(R.layout.fragment_wechat,container,false);
使用布局填充器(LayoutInflater)将 R.layout.fragment_wechat.xml 转换为View对象。这个View对象代表了布局文件中的所有UI元素。
context=view.getContext();
获取这个View的上下文,上下文是Android系统中一个重要的概念,它代表了应用环境的信息,如应用资源的位置等。
recyclerView=view.findViewById(R.id.rv_main);
通过ID查找View,这里的ID是R.id.rv_main,通常这是RecyclerView的一个ID。
myadapter = new MyAdapter(context);
创建一个新的MyAdapter对象,Adapters是适配器,用于将数据与视图(如RecyclerView)关联起来。
recyclerView.setAdapter(myadapter);
为RecyclerView设置适配器,告诉RecyclerView如何显示数据。
LinearLayoutManager manager=new LinearLayoutManager(context);
创建一个LinearLayoutManager对象,它是RecyclerView的一个布局管理器,决定了RecyclerView如何在其父布局中显示。
manager.setOrientation(LinearLayoutManager.VERTICAL);
设置布局管理器为垂直方向,也就是说RecyclerView将会从上到下地显示其子项。
recyclerView.setLayoutManager(manager);
将这个布局管理器设置到RecyclerView上。
return view;
返回创建的View对象到父容器中。
综上所述,以上代码的主要功能是创建一个RecyclerView的界面并返回。
接下来看上面提到的适配器类:
Myadapter:
public class MyAdapter extends RecyclerView.Adapter <MyAdapter.LinearViewHolder>{
//context
private Context mContext;
//展示的数据
private List<String> list=new ArrayList<>();
public MyAdapter(Context context){
this.mContext=context;
for(int i=0;i<30;i++){
list.add(String.format("%s-%s", i/10+1,i));
}
}
//onCreateViewHolder方法创建一个viewHolder,viewholder可以理解为一条数据的展示布局,这里我们自定义类LinearViewHolder创建一个只有TextView的item
//这里我们需要创建每条布局使用的layout:layout_linear_item
@NonNull
@Override
public MyAdapter.LinearViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new LinearViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item,parent,false));
}
//onBindViewHolder方法为item的UI绑定展示数据,
@Override
public void onBindViewHolder(MyAdapter.LinearViewHolder holder, int position) {
holder.textView.setText(String.format("Hello World %s", list.get(position)));
}
//item的总长度
@Override
public int getItemCount() {
return 30;
}
//LinearViewHolder可以看作一个item的展示和内部逻辑处理,故而如果需要绑定事件,获取控件的时候要在itemView中获取
//itemView由onCreateViewHolder方法LayoutInflater.inflatec创建
class LinearViewHolder extends RecyclerView.ViewHolder{
private TextView textView;
public LinearViewHolder(View itemView){
super(itemView);
textView=(TextView) itemView.findViewById(R.id.item);
//简单事件处理
textView.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext,textView.getText().toString(),Toast.LENGTH_SHORT).show();
}
});
}
}
}
上述代码主要的功能如下:
创建ViewHolder:在onCreateViewHolder方法中,我创建了一个名为LinearViewHolder的ViewHolder。每个ViewHolder对象都持有对一个UI组件(在这种情况下是一个TextView)的引用,这个组件用于显示列表中项目的数据。
绑定数据到ViewHolder:在onBindViewHolder方法中,我将数据(从列表list中获取的项)绑定到每个ViewHolder的TextView上。这是在每个列表项被渲染到屏幕上时发生的。
设置列表长度:getItemCount方法,返回列表list的长度
设置点击事件:在LinearViewHolder内部,为TextView设置了一个点击事件。当用户点击这个TextView时,会显示一个Toast,内容是该TextView当前显示的文本。
初始化数据:在适配器的构造函数中,初始化了Context对象和一个包含30个字符串的列表。这些字符串被格式化为"Hello World #",其中#是该字符串在列表中的位置(从1开始)。
最后一个文件:MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Fragment WechatFragment=new WechatFragment();
private Fragment Wechat2Fragment=new Wechat2Fragment();
private Fragment Wechat3Fragment=new Wechat3Fragment();
private Fragment Wechat4Fragment=new Wechat4Fragment();
private RecyclerView mRvMain;
private FragmentManager fragmentManager;
private LinearLayout LinearLayout1;
private LinearLayout LinearLayout2;
private LinearLayout LinearLayout3;
private LinearLayout LinearLayout4;
@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);
LinearLayout1.setOnClickListener(this);
LinearLayout2.setOnClickListener(this);
LinearLayout3.setOnClickListener(this);
LinearLayout4.setOnClickListener(this);
initFragment();
}
protected void initFragment() {
fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction=fragmentManager.beginTransaction();
transaction.add(R.id.id_content,WechatFragment);
transaction.add(R.id.id_content,Wechat2Fragment);
transaction.add(R.id.id_content,Wechat3Fragment);
transaction.add(R.id.id_content,Wechat4Fragment);
hideFragment(transaction);
transaction.commit();
}
protected void hideFragment(FragmentTransaction transaction) {
transaction.hide(WechatFragment);
transaction.hide(Wechat2Fragment);
transaction.hide(Wechat3Fragment);
transaction.hide(Wechat4Fragment);
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.LinearLayout1) {
showfragment(1);
} else if (id == R.id.LinearLayout2) {
showfragment(2);
} else if (id == R.id.LinearLayout3) {
showfragment(3);
} else if (id == R.id.LinearLayout4) {
showfragment(4);
}
}
private void showfragment(int i) {
FragmentTransaction transaction=fragmentManager.beginTransaction();
hideFragment(transaction);
switch (i){
case 1:
transaction.show(WechatFragment);
break;
case 2:
transaction.show(Wechat2Fragment);
break;
case 3:
transaction.show(Wechat3Fragment);
break;
case 4:
transaction.show(Wechat4Fragment);
break;
default:
break;
}
transaction.commit();
}
}
上述代码包含了多个方法,具体来说:
- 在
onCreate
方法中,通过findViewById
获取了四个 LinearLayout 的实例,并为它们设置了点击事件处理程序,该处理程序调用了onClick
方法。 - 在
initFragment
方法中,创建了一个 FragmentTransaction 实例,并添加了四个 WechatFragment,这四个 WechatFragment 分别代表微信的不同功能。 - 在
hideFragment
方法中,这四个 WechatFragment 被隐藏。 - 在
onClick
方法中,通过判断被点击的 LinearLayout 的 ID,显示相应的 Fragment。
这段代码的流程是这样的:
- 用户进入应用程序后,四个 LinearLayout 将被创建并添加到布局中。
- 用户可以通过点击不同的 LinearLayout 来显示或隐藏相应的 Fragment。
结果展示:
心得:
难点1:java语言未曾学习过,但是有前两年学习的各种编程语言打基础,还算顺利。
难点2:java类的使用,Android开发中,各种不熟悉的类和方法成为了作业的阻碍,虽然上课时将老师提到的类和方法都记了下来,但各种类,方法,参数之类的东西还是对我造成了较大的阻碍。
难点3:xml的各种属性和标签
总之,虽然过程有些艰难,但是由于老师上课时事无巨细,甚至亲自演示了整个过程,所以我觉得还算顺利,也从这次实验中学到了很多。