Fragment

本文详细介绍了Android中的Fragment,包括Fragment的生命周期、静态与动态加载方式,以及Fragment与Activity之间的值传递,提供了多种传值方法的示例代码。

1、Fragment生命周期

官方Fragment生命周期图
这里写图片描述

方法:
1. onAttach( ) : Fragment已经关联了一个Activity,通过getActitivty()方法可以获取Activity。
2. onCreate( ) :系统初始化Fragment。
3. onCreateView( ):初始化Fragment布局
4. onActivityCreated( ):当Activity的onCreated执行结束后,被调用
5. onStart( ):Fragment可见。
6. onResume( ):Fragment可交互。
7. onPause( ):Fragment处于暂停状态,但依然可见,用户不能与之交互。
8. onStop( ):Fragment完全不可见。
9. onDestoryView( ):销毁与Fragment有关的视图,但未与Activity解除绑定
10. onDestory( ):销毁Fragment。
11. onDetach( ):取消Fragment与Acitivity间的关联。

这里写图片描述

这里写图片描述

验证方式与验证Acitivity生命周期的方法一样。

2、加载Fragment

这里写图片描述

2.1 静态加载Fragment

activity_main.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="match_parent"
    android:id="@+id/line1"
    android:orientation="vertical"
    tools:context="com.example.admin.vip_11.MainActivity">

    <fragment
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        <!--需要加载的布局-->
        tools:layout="@layout/layout_fragment_one"
        <!--包名.类名-->
        android:name="com.example.admin.vip_11.Fragment_one"
        />

</LinearLayout>

注意导包问题与最后的commit()!!!
MainActivity.java

public class MainActivity extends AppCompatActivity {

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

}

layout_fragment_one.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:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是Fragment_one"
        android:textSize="25sp"
        />

</LinearLayout>

Fragment_one.java

public class Fragment_one extends Fragment{
     @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.layout_fragment_one, null);
        return view;
    }

}

2.2 动态加载Fragment

activity_main.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="match_parent"
    android:id="@+id/line1"
    android:orientation="vertical"
    tools:context="com.example.admin.vip_11.MainActivity">

</LinearLayout>

注意导包问题与最后的commit()!!!
MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //Fragment管理
        FragmentManager fragmentManager = getSupportFragmentManager();
        //开启个事务
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //创建Fragment对象
        Fragment_one fragment = new Fragment_one();
        //把fragment添加进事务中
        fragmentTransaction.add(R.id.line1, fragment, "1");
        //提交事务
        fragmentTransaction.commit();
    }

}

其余两个文件不变。

静态加载可以直接将结果显示在activity_main.xml的布局中,而动态加载必须运行在模拟器上才可以看到最终的显示结果。

3、Fragment与Acitivity间的传值

3.1 Framgent给Acitivity传值

这里的传值,使用接口回调来实现。

先修改一下layout_mian.xml与layout_fragment_one中的布局,以便于清晰的看到传值。

<?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="match_parent"
    android:orientation="vertical"
    tools:context="com.example.admin.vip_11.MainActivity">


    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:text="MainActivity"
        android:textSize="25sp"
        android:background="@color/colorAccent"
        />

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/fragmentLayout"
        >

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Fragment"
            android:textAllCaps="false" />

    </LinearLayout>

</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:id="@+id/fragment_one"
    >

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment"
        android:textAllCaps="false" />

</LinearLayout>

第一步,现在Fragment_one.java中创建一个接口,用于传值。并在类中实现该接口,并传入一个String对象。

public class Fragment_one extends Fragment{
    private CallBackValue mCallBackValue;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mCallBackValue = (CallBackValue) getActivity();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.layout_fragment_one, null);
        mCallBackValue.sendValue("Fragment传来的值");
        return view;
    }
}

interface CallBackValue {
    public void sendValue(String s);        
}

第二步,在MainActivity.java中实现接口,并接收从Fragment传来的值。

public class MainActivity extends AppCompatActivity implements CallBackValue{
    @Override
    public void sendValue(String s) {
        TextView textView = findViewById(R.id.text);
        textView.setText(s);
    }

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

    public void FragmentToActovity() {

        FragmentManager fragmentManager = getSupportFragmentManager();
        //开启个事务
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //创建Fragment对象
        Fragment_one fragment = new Fragment_one();

        fragmentTransaction.replace(R.id.fragmentLayout, fragment);
        //提交事务
        fragmentTransaction.commit();
    }
}

这里写图片描述

这里写图片描述

3.2 Activity给Fragment传值

MainActivity.java 添加函数并在onCreate( )中调用。

public void ActivityToFragment() {
        //Fragment管理
        FragmentManager fragmentManager = getSupportFragmentManager();
        //开启个事务
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //创建Fragment对象
        Fragment_one fragment = new Fragment_one();
        Bundle bundle = new Bundle();
        bundle.putString("key", "MainActivity传来的值");
        fragment.setArguments(bundle);
        //替换会把容器中的所以内容全都替换掉,保持只有一个fragment在显
        //示,减少了界面的层级关系。
        fragmentTransaction.replace(R.id.fragmentLayout, fragment);
        //提交事务
        fragmentTransaction.commit();
    }

layout_main.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="match_parent"
    android:id="@+id/fragmentLayout"
    android:orientation="vertical"
    tools:context="com.example.admin.vip_11.MainActivity">

</LinearLayout>

layout_fragment_one.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"
    android:id="@+id/fragment_one"
    >

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是Fragment_one"
        android:textSize="25sp"
        />

</LinearLayout>

Fragment_one.java

public class Fragment_one extends Fragment{
     @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.layout_fragment_one, null);
        TextView textView = view.findViewById(R.id.text);
        //getArguments()方法获得存入的Bundle对象,并用get()方法放
        //入关键字,最终获取到Object对象。
        textView.setText((String) getArguments().get("key"));
        return view;
    }

}

这里写图片描述

运行程序后,可以看到TextView中的内容变成从Activity中传来的值。

3.3 Fragment给Fragment传值

3.3.1第一种方法

直接把上面的两个方法结合起来就可以。

第一步:这里需要再创建一个Fragment_two.java与layout_fragment_two.xml。

public class Fragment_two extends Fragment{
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.layout_fragment_two, null);
        TextView textView = view.findViewById(R.id.text2);
        if(getArguments().get("key") != null) {
            textView.setText((String) getArguments().get("key"));
        }
        return view;
    }
}
<?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"
    android:id="@+id/fragment_two"
    >

    <TextView
        android:id="@+id/text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="第二个Fragment的TextView"
        android:textSize="25sp"
        />

</LinearLayout>

第二步:当Fragment_one.java中按钮被点击后,将值存入Bundle中。

public class Fragment_one extends Fragment{
    private CallBackValue mCallBackValue;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mCallBackValue = (CallBackValue) getActivity();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.layout_fragment_one, null);
        view.findViewById(R.id.buttonOne).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCallBackValue.sendValue("第一个Fragment传来的值");
            }
        });
        return view;
    }
}

interface CallBackValue {
    public void sendValue(String s);
}

layout_fragmant_one.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"
    android:id="@+id/fragment_one"
    android:orientation="vertical"
    >

    <Button
        android:id="@+id/buttonOne"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是第一个Fragment"
        android:textAllCaps="false"
        />

    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="第一个Fragment的TextView"
        android:textSize="25sp"
        />

</LinearLayout>

第三步:在Fragment_two.java中获取存入Bundle的值,并展示。

MainActivity.java

public class MainActivity extends AppCompatActivity implements CallBackValue{
    private String s;
    @Override
    public void sendValue(String s) {
        this.s = s;
        ActivityToFragment();
    }

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

    public void ActivityToFragment() {
        //Fragment管理
        FragmentManager fragmentManager = getSupportFragmentManager();
        //开启个事务
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //创建Fragment对象
        Fragment_two fragment = new Fragment_two();

        Bundle bundle = new Bundle();
        bundle.putString("key", s);
        fragment.setArguments(bundle);
        fragmentTransaction.replace(R.id.fragmentLayoutTwo, fragment);
        //提交事务
        fragmentTransaction.commit();
    }

    public void FragmentToActovity() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        //开启个事务
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //创建Fragment对象
        Fragment_one fragment = new Fragment_one();

        fragmentTransaction.replace(R.id.fragmentLayoutOne, fragment);
        //提交事务
        fragmentTransaction.commit();
    }

}

activity_main.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="match_parent"
    android:orientation="vertical"
    tools:context="com.example.admin.vip_11.MainActivity">


    <LinearLayout
        android:id="@+id/fragmentLayoutOne"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="@color/colorAccent"
        android:orientation="vertical">

    </LinearLayout>

    <LinearLayout
        android:id="@+id/fragmentLayoutTwo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="@color/colorPrimary"
        android:orientation="vertical">

    </LinearLayout>

</LinearLayout>

这里写图片描述

这里写图片描述

3.3.2 第二种方法

activity_main.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="match_parent"
    android:orientation="horizontal"
    tools:context="com.example.admin.vip_13.MainActivity">

    <fragment
        android:id="@+id/fragment1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:name="com.example.admin.vip_13.FragmentOne"
        />

    <LinearLayout
        android:orientation="vertical"
        android:id="@+id/fragment2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:background="@color/colorAccent"
        >

    </LinearLayout>

</LinearLayout>

layout_fragment_one.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"
    android:orientation="vertical"
    android:gravity="center"
    >

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="确定"
        />

</LinearLayout>

layout_fragment_two.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"
    android:orientation="vertical"
    android:gravity="center"
    >

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:layout_gravity="center"
        android:layout_marginLeft="10dp"
        />
</LinearLayout>

FragmentOne.java

public class FragmentOne extends Fragment {
    private EditText mEditText;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.layout_fragment_one, null);
        Button button = view.findViewById(R.id.button);
        mEditText = view.findViewById(R.id.editText);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String s = mEditText.getText().toString();
                FragmentTwo fragmentTwo = (FragmentTwo) getFragmentManager().findFragmentById(R.id.fragment2);
                fragmentTwo.setData(s);
            }
        });
        return view;
    }
}

FragmentTwo.java

public class FragmentTwo extends Fragment{

    private TextView mTextView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.layout_fragment_two, null);
        mTextView = view.findViewById(R.id.text);
        return view;
    }

    public void setData(String s) {
        mTextView.setText(s);
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        FragmentTwo fragmentTwo = new FragmentTwo();
        fragmentTransaction.replace(R.id.fragment2, fragmentTwo);
        fragmentTransaction.commit();
    }
}

首先,要先在MainAcitivity中动态绑定FragmentTwo,否则将会产生空指针异常。在FragmentTwo中定义setData方法,用于传入FragmentOne中输入的String值。调用getFragmentManager().findFragmentById(R.id.fragment2)方法并进行强转,获取到FragmentTwo对象。在调用其setData方法,传值成功。

3.3.3 第三种方法

将次代码

FragmentTwo fragmentTwo = (FragmentTwo) getFragmentManager().findFragmentById(R.id.fragment2);
                fragmentTwo.setData(s);

替换为

TextView textView = getActivity().findViewById(R.id.text);
                textView.setText(s);

其余不变。
第三种方法是直接获取到FragmentTwo中的TextView对象,并对其直接赋值。

### 定义 Fragment 意思是“碎片、片段”,表示 Activity 中的行为或用户界面部分,是 Activity 的模块化组成部分,可将多个片段组合在一个 Activity 中来构建多窗格 UI,也能在多个 Activity 中重复使用某个片段。它具有自己的生命周期,能接收自己的输入事件,可在 Activity 运行时添加或移除,可当作“子 Activity”在不同 Activity 中复用。Fragment 作为 Activity 界面的一部分必须依附于 Activity,与 Activity 一样拥有自己的生命周期,还能处理用户的交互动作。同一个 Activity 可以有一个或多个 Fragment 作为界面内容,可动态添加、删除 Fragment,灵活控制 UI 内容,也可用于解决部分屏幕适配问题 [^2][^4][^5]。 ### 使用方法 #### 静态使用 将 Fragment 当成普通的 View 一样声明在 Activity 的布局中,事件处理交给 Fragment。步骤如下: 1. 在 Activity 布局中添加 fragment 控件,用于加载想要显现的视图。 2. 创建 Fragment 类继承 Fragment,重写其中的 onCreateView(),使用 inflate 加载 Fragment 布局并返回视图 [^2]。 #### 动态使用 动态加载时,因有许多完成特定功能的 Fragment,所以需要对其进行管理,这时用到 FragmentManage 类。对 Fragment 进行添加、移除、替换等操作需通过 Fragment 事务处理,用到 FragmentTransaction 类。步骤如下: 通过 FragmentManager.beginTransaction() 开始一个事务,可在事务中对 Fragment 进行操作,如添加 add()、移除 remove()、替换 replace() 等,最后提交事务 commit(),还有 addToBackStack()、attach() 等操作。注意,Fragment 通过 ID 或者 Tag 作为标识,对 Fragment 操作后一定要提交,即调用 commit() [^2]。 ### 应用场景 Fragment 的目的是为了解决在不同的显示屏上动态和灵活的 UI 设计。可用于构建多窗格 UI,在同一个 Activity 中组合多个片段;可动态添加、删除 Fragment,灵活控制 UI 内容;还能用来解决部分屏幕适配问题 [^2][^4]。 ### 代码示例 以下是自定义 MyFragmentPagerAdapter 继承自 FragmentPagerAdapter 的示例代码: ```java import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; public class MyFragmentPagerAdapter extends FragmentPagerAdapter { public MyFragmentPagerAdapter(FragmentManager fm) { super(fm); } // 滑动的过程中呈现的Fragment的确定 @Override public Fragment getItem(int arg0) { Fragment fragment = null; switch (arg0) { case 0: fragment = new FragmnetFirst(); break; case 1: fragment = new FragmentSecond(); break; case 2: fragment = new FragmentThird(); break; } return fragment; } // 滑动的过程中可以呈现Fragment的个数 @Override public int getCount() { return 3; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值