最近在学习Fragments,记录下来学习的一些心得。
一、Fragments是什么
Fragment翻译为“碎片”,这是Google官方的解释:
Fragment表示 Activity中的行为或用户界面部分。可以将多个片段组合在一个 Activity 中来构建多窗格 UI,以及在多个 Activity 中重复使用某个片段。您可以将片段视为 Activity 的模块化组成部分,它具有自己的生命周期,能接收自己的输入事件,并且您可以在 Activity 运行时添加或移除片段(有点像您可以在不同 Activity 中重复使用的“子 Activity”)。
其实,简而言之就是下面这张图:
这是在手机和平板上使用相同App的例子。更常见的的是下面这些例子:
通过点击不同的底部导航栏目切换不同的页面,底部导航栏都链接着不同的Fragment,有三个导航栏,所以就有3个Fragments。
二、栗子
Fragment分为动态添加和静态添加巴拉巴拉的,我们这里用动态添加,毕竟静态添加很easy!
下面通过一个简单的栗子来了解一下Fragment的使用。
如图,我么将实现一下功能,单击图中的 你 显示一个图片,然后单击我显示一张图片,单击他又显示另外一张图片。而承载你、我、他的图片区域就是Fragment。
首先创建一个项目:HandsomeBoy。
然后按照下面的标示创建相关文件。
代码:
YouFragment.java
public class YouFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_you,null);
return view;
}
}
知识点
:
onCreateView()
方法是第一绘制Fragment UI时调用的方法,这个方法返回一个View对象,但是如果Activity不需要Fragment绘制界面也可以返回null。
对应的layout:fragment_you.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/you"/>
</RelativeLayout>
MyFragment.java
public class MyFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_my,null);
}
}
fragment_my.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/me"/>
</RelativeLayout>
HimFragment.java
public class HimFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_him,null);
}
}
fragment_him.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/him"/>
</RelativeLayout>
OK! Fragment的准备工作我们已经完成了,然后着手准备头部的状态栏了。由于Fragment都是在Activity俩面实现的,所以头部当然要写在activity_main里面啦!
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private FragmentManager manager;
private FragmentTransaction transaction;
private RadioButton rb_you,rb_my,rb_him;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = getSupportFragmentManager();
transaction = manager.beginTransaction();
transaction.add(R.id.content_layout,new YouFragment());
transaction.commit();
initView();
}
public void initView(){
rb_you = findViewById(R.id.rb_you);
rb_my = findViewById(R.id.rb_my);
rb_him = findViewById(R.id.rb_him);
rb_you.setOnClickListener(this);
rb_my.setOnClickListener(this);
rb_him.setOnClickListener(this);
}
@Override
public void onClick(View v) {
transaction = manager.beginTransaction();
switch (v.getId()){
case R.id.rb_you:
transaction.replace(R.id.content_layout,new YouFragment());
break;
case R.id.rb_my:
transaction.replace(R.id.content_layout,new MyFragment());
break;
case R.id.rb_him:
transaction.replace(R.id.content_layout,new HimFragment());
break;
}
transaction.commit();
}
}
知识点
:
Transaction
是一个事务对象,具有原子性,简单来说就是要么不执行,要么全执行。
为了得到Transaction对象首先要获得FragmentManager对象,然后用FragmentManager对象调用BeginTransction()方法得到Transaction对象,接着调用Transaction对象的对应方法。主要用到这样几个方法:
1、add(int i,Fragment fragment)
第一个参数是需要将fragment添加到的控件,第二个参数是要添加的Fragment对象。上面这个栗子中需要将Fragment对象添加到activity_main的id名为content_layout的控件中。下面的类似。
2、replace(int i,Fragment fragment)
3、remove(Fragment fragment)
MainActivity中还有一个需要注意的地方,直接用MainActivity实现了OnClickListener这个接口,所以需要实现他的抽象方法onClick(),我们使用这个方法来实现单击不同的按钮切换不同的按钮。
这样就实现了Fragment的动态添加。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/title_layout"
android:layout_width="match_parent"
android:layout_height="50dp">
<RadioGroup
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioButton
android:id="@+id/rb_you"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="你"
android:textSize="25sp"
android:textColor="#08ff00"
android:button="@null"
android:gravity="center"/>
<RadioButton
android:id="@+id/rb_my"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="我"
android:textSize="25sp"
android:textColor="#08ff08"
android:button="@null"
android:gravity="center"/>
<RadioButton
android:id="@+id/rb_him"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="他"
android:textSize="25sp"
android:textColor="#08ff08"
android:button="@null"
android:gravity="center"/>
</RadioGroup>
</LinearLayout>
<LinearLayout
android:id="@+id/content_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
</RelativeLayout>
知识点
:
由于点击不同的按钮需要显式不同的Fragment,所以按钮之间应该互斥,即点击A时要确保B、C不会被执行,点击B时要确保A、C不会被执行,点击C时要确保A、B不会被执行,所以这里用到了RadioButton这个控件,按钮的长度被设置为0,然后用layout_weight来设置控件占据的比例。这里三个控件的比例为1:1:1,所以现实的长度是一样的。利用button=“@null”,来消除RadioButton的圆点,gravity设置居中。
三、解锁成就
下面是令人激动的时刻,因为你独立的实现了这个效果,也相信你能举一反三,在具体的Fragment添加自己的逻辑,来完善他。下面是我的成果。
#######四、下集预告
前面说过Fragment表示 Activity中的行为或用户界面部分,Activity是有生命周期的,那么Fragment肯定也有生命周期嘛?下次讲解,诸君请插眼,方便下次gank!
为啥上传的图片尺寸这么大啊!!!