Fragemnt 碎片

《Android Fragment 非常详细的一篇》

关于fragment的生命周期:
在这里插入图片描述

Fragemnt是一个碎片,只是覆盖原来的布局而已,当Fragemnt和原来的布局一样大,则完全覆盖,
若小,则没有覆盖完原来的布局,原来的布局还会显示没有覆盖的部分,
但该fragment最大只能和原来的布局一样大,即fragment使宽和高都设置的match_parent。

一:基本用法:

添加和移除的例子:

先上图:原本为蓝色的背景被紫色覆盖了,说明原来的控件id为 ll_main_content 被fragment_one.xml布局覆盖了
在这里插入图片描述

Step 1:创建一个fragment布局:fragment_one.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_Root"
    android:background="@color/colorPrimary"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="第一个fragment"/>

</LinearLayout>

Step 2:创建一个继承fragment的类

    //==Step 1 :继承 Fragment
public class FragmentOne extends Fragment {


    //==Step 2 :重写onCreateView
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        /**将xml(布局)资源文件加载成为View
         inflate()的作用就是将一个xml定义的布局文件实例化为view控件对象
         resource(第一个参数):View的layout的ID,即某个布局文件
         root(第二个参数):填的是形参的ViewGroup对象,需要附加到resource资源文件的根控件,inflate()会返回一个View对象。
             如果第三个参数attachToRoot为true,就将这个root作为根对象返回,
             否则仅仅将这个root对象的LayoutParams属性附加到resource对象的根布局对象上,也就是布局文件resource的最外层的View上。
             如果root为null则会忽略view根对象的LayoutParams属性(注意,即相当于没有设置布局)。
         attachToRoot(第三个参数):是否将root附加到布局文件的根视图上
         */
        View view=inflater.inflate(R.layout.fragment_one,container,false);

        LinearLayout llRoot=view.findViewById(R.id.ll_Root);//可以获取该布局的控件id

        return view;
    }
}

Step 3: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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <!--此处为添加fragment的地方-->
    <LinearLayout
        android:id="@+id/ll_main_content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@color/colorAccent"
        android:orientation="horizontal"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/bt_load"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="加载" />

        <Button
            android:id="@+id/bt_remove"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="移除"/>

    </LinearLayout>
    
</LinearLayout>

Step 4:MainActivity的代码如下:

public class MainActivity extends AppCompatActivity {
    private FragmentOne fragmentOne;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //获取控件
        Button btLoad=findViewById(R.id.bt_load);//加载
        Button btRemove=findViewById(R.id.bt_remove);//移除
        
        btLoad.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //=====================加载fragment
                //1.获取fragment管理器
                FragmentManager fragmentManager=MainActivity.this.getSupportFragmentManager();
                //2.开启fragment事务
                FragmentTransaction transaction=fragmentManager.beginTransaction();
                //3.创建写好的fragment,把要显示的fragment对象添加到transaction
                fragmentOne = new FragmentOne();
                //参数1为要把fragment加载到哪个控件的id,参数2为要加载的fragment
                transaction.add(R.id.ll_main_content, fragmentOne);
                //4.显示fragment
                transaction.show(fragmentOne);
                //5.提交事务
                transaction.commit();
            }
        });

        btRemove.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //==移除fragment  ps:因为transaction 只能提交一次,所以只能再次创建该对象
                FragmentManager fragmentManager=MainActivity.this.getSupportFragmentManager();
                FragmentTransaction transaction=fragmentManager.beginTransaction();
                transaction.remove(fragmentOne).commit();
            }
        });
        
    }
}

二、懒加载和切换不同的fragment

先上图:红色边白色,说明切换了fragment了
在这里插入图片描述

Step 1:在此之前先准备需要用到的文件:在drawable 层 添加

1.bg_order_top.xml:作用:在button上面画一条灰色的线

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!--因为下面画了一个四边有1dp灰色的白色矩形,我们要的是只有上面有灰色,
        所以除了top,其它都加-1dp的边距,让其它的灰色边框去掉
    -->
    <item
        android:bottom="-1dp"
        android:right="-1dp"
        android:left="-1dp">

        <!-- 画背景:rectangle 为画矩形-->
        <shape android:shape="rectangle">

            <!--画一个白色的矩形背景 ps:colorWhite为白色,自己去color文件添加-->
            <solid
                android:color="@color/colorWhite"/>

            <!--在白色的四边上加上1dp的灰色	ps:colorGray 灰色,自己去color文件添加-->
            <stroke android:width="1dp"
                android:color="@color/colorGray"/>

        </shape>

    </item>

</layer-list>

2.selector_rb_main_home.xml 作用:当选中按钮时,按钮背景为一张图片,不选中时,为另一图片。 ps:这用到的图片,自行准备

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--注意!!android:state_checked="true" 所在的item一定要在排在其它item的上面(排第一)-->

    <!--android:state_checked="true" 说明,当该复选框被选中时,就调用这个item,该item的图片为:ic_rb_home_red-->
    <item android:drawable="@drawable/ic_rb_home_red" android:state_checked="true"/>
    <!--当不选中时,调用该item,图片为:ic_rb_home-->
    <item android:drawable="@drawable/ic_rb_home"/>
</selector>

3.selector_rb_main_user.xml 作用同上

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_rb_user_red" android:state_checked="true"/>
    <item android:drawable="@drawable/ic_rb_user"/>
</selector>

4.selector_rb_main.xml 作用:当按钮选中时,为一种颜色,不选中时为另一种颜色(ps:颜色请自行去color文件写)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorRed"
        android:state_checked="true"/>
    <item android:color="@color/colorBlack"/>
</selector>

Step 2:准备两个fragment用的布局:

1.fragment_home.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_Root"
    android:background="@color/colorRed"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="第一个fragment"/>


</LinearLayout>

2.fragment_user.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_Root"
    android:orientation="vertical"
    android:background="@color/colorWhite"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="第二个fragment"/>

</LinearLayout>

Step 3:准备两个class继承fragment:

1.HomeFragment

    //==Step 1 :继承 Fragment
public class HomeFragment extends Fragment {


    //==Step 2 :重写onCreateView
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        /**将xml(布局)资源文件加载成为View
         inflate()的作用就是将一个xml定义的布局文件实例化为view控件对象
         resource(第一个参数):View的layout的ID,即某个布局文件
         root(第二个参数):填的是形参的ViewGroup对象,需要附加到resource资源文件的根控件,inflate()会返回一个View对象。
             如果第三个参数attachToRoot为true,就将这个root作为根对象返回,
             否则仅仅将这个root对象的LayoutParams属性附加到resource对象的根布局对象上,也就是布局文件resource的最外层的View上。
             如果root为null则会忽略view根对象的LayoutParams属性(注意,即相当于没有设置布局)。
         attachToRoot(第三个参数):是否将root附加到布局文件的根视图上
         */
        View view=inflater.inflate(R.layout.fragment_home,container,false);

        LinearLayout llRoot=view.findViewById(R.id.ll_Root);//可以获取该布局的控件id

        return view;
    }
}

2.UserFragment

    //==Step 1 :继承 Fragment
public class UserFragment extends Fragment {

    //==Step 2 :重写onCreateView
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view=inflater.inflate(R.layout.fragment_user,container,false);

        return view;
    }
}

Step 4: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"
    android:background="@color/colorWhite"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <!--被fragment覆盖的部分-->
    <LinearLayout
        android:id="@+id/ll_main_content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal" />

    <!--功能按钮-->
    <RadioGroup
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="5dp"
        android:orientation="horizontal"
        android:background="@drawable/bg_order_top"
        android:paddingTop="5dp">

        <RadioButton
            android:id="@+id/rb_main_home"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:button="@null"
            android:gravity="center_horizontal"
            android:drawableTop="@drawable/selector_rb_main_home"
            android:text="主页"
            android:textColor="@drawable/selector_rb_main"/>


        <RadioButton
            android:id="@+id/rb_main_user"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:button="@null"
            android:gravity="center_horizontal"
            android:drawableTop="@drawable/selector_rb_main_user"
            android:textColor="@drawable/selector_rb_main"
            android:text="我的" />

    </RadioGroup>

</LinearLayout>

Step 5:开始使用:MainActivity 代码如下:

public class MainActivity extends AppCompatActivity {

    private RadioButton rbHome;
    private RadioButton rbUser;

    private Fragment[] fragments=new Fragment[]{null,null};//存放fragment

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //=====Step 1:获取控件
        rbHome = findViewById(R.id.rb_main_home);
        rbUser = findViewById(R.id.rb_main_user);

        //======Step 2:懒加载:默认选择的fragment(HomeFragment)
        initFragment(0);
        //默认选中主页
        rbHome.setChecked(true);

        //======Step 3:点击事件监听
        listenerView();


    }

    private void listenerView() {

        //Step 3.1:点击rbHome(主页) 切换为主页的(HomeFragment)
        rbHome.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                initFragment(0);
            }
        });

        //Step 3.2:点击rbUser(我的) 切换为我的的(UserFragment)
        rbUser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                initFragment(1);
            }
        });

    }


    public void initFragment(int value){

        //===========加载fragment
        //1.获取fragment管理器
        FragmentManager fragmentManager=this.getSupportFragmentManager();
        //2.开启fragment事务
        FragmentTransaction transaction=fragmentManager.beginTransaction();

        //3.声明全局的数组fragments ,把要显示的fragment对象添加到transaction
        if (fragments[value]==null){

            switch (value){
                case 0://0 时 切换为 HomeFragment
                    fragments[value]=new HomeFragment();
                    break;
                case 1://1 时 切换为 UserFragment
                    fragments[value]=new UserFragment();
                    break;
            }

            transaction.add(R.id.ll_main_content,fragments[value]);
        }

        //4.隐藏其它fragment
        for (int i = 0; i < fragments.length; i++) {
            if (fragments[i]!=null && value!=i){
                transaction.hide(fragments[i]);
            }
        }

        //5.显示fragment并提交
        transaction.show(fragments[value]).commit();
    }

}

PS:当要在当前fragment获取当前的content 或 activity时,要在此方法获取:

例部分代码如下:

public class HomeFragment extends Fragment {


    private Activity activity;
    //在方法获取当前content,在onCreateView获取有时会获取不到
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        this.activity= (Activity) context;
    }

PS:在fragment直接传参可以用bundle:例:

要传参的fragment(继承fragment的类):

    Bundle bundle=new Bundle();
    bundle.putInt("int",12);
    bundle.putString("string","小明");
    //例如 要接受参数的fragment 名为:HomeFragmentList ,就如下设置其参数
	HomeFragmentList home=new HomeFragmentList();
	home.setArguments(bundle);

要接受的fragment:部分代码如下:

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Bundle bundle=getArguments();
                int it=bundle.getInt("it");
        String str=bundle.getString("string");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值