【Android】全球诡异降临:只有我能找到Fragment并与Activity进行数据传递

【Android】全球诡异降临:只有我能找到Fragment并与Activity进行数据传递

文章目录


在一个平静的早晨,整个世界突然被一股莫名的力量所震撼。天际的云层像被撕裂的布匹一般,光芒从裂缝中射出,仿佛预示着什么不安的变故。街道上的人们从梦中惊醒,望着天空,眼中闪烁着恐惧和困惑。诡异的现象在全球范围内爆发:动物变异,植物异化,连最平常的物品也开始变得不可思议。

我醒来时,房间里弥漫着一种不安的气氛。手机上的新闻报道充斥着各种惊恐的标题和照片,但我却有种奇怪的感觉,这一切似乎与我有关。离奇的事件频繁发生,但所有的解决方案似乎都与我无关,或许是因为我与这些诡异现象有某种无形的联系。

我走出家门,空气中充满了异样的能量。四周的人们纷纷忙碌地寻找着生存的办法,甚至有些人已经开始崩溃。就在这时,我注意到身边的一切都变得异常清晰,一种前所未有的感觉涌上心头。我发现自己能够看见别人无法看到的东西,感受到别人无法感受到的力量。仿佛整个世界的秘密都在向我展示。

这是个混乱的时代,全球范围内的诡异现象肆虐,而只有我还记得怎么用Activity向Fragment传递数据以及用Fragment向Activity传递数据,甚至还有Fragment之间传递数据,我能在这个世界存活下去吗?

于是我掏出随身的小本本,准备把我脑子里仅存的知识记录下来:

61c9d3c90de7245b0dadcce5b1e36e28

Activity向Fragment传递数据

在Android开发中,Activity和Fragment是两种重要的组件,经常需要相互通信。传递数据从Activity到Fragment是一个常见的需求,下面我们将介绍几种常用的方法来实现这一功能。

方法一:通过Fragment的构造方法传递数据

虽然官方建议不要直接使用Fragment的构造方法传递数据,但这种方法在某些简单的场景下仍然有效。

1. 在Activity中使用带参数的Fragment构造方法:

// 创建Fragment实例并传递数据
MyFragment fragment = MyFragment.newInstance("value");

// 启动Fragment
getSupportFragmentManager().beginTransaction()
        .replace(R.id.fragment_container, fragment)
        .commit();

这里我们顺便来复习一下Fragment的动态启动吧!

启动 Fragment

  • getSupportFragmentManager().beginTransaction():开始一个新的 FragmentTransaction,这是用来在 Activity 中执行 Fragment 操作(如添加、替换或移除)。
  • .replace(R.id.fragment_container, fragment):将指定的 Fragment 替换到 R.id.fragment_container 这个 ViewGroup 中。R.id.fragment_containerActivity 布局中的一个容器视图,fragment 是要添加到这个容器中的 Fragment 实例。
  • .commit():提交事务,将更改应用到 Activity 上,完成 Fragment 的替换操作。

2. 在Fragment中定义构造方法并接收数据:

public class MyFragment extends Fragment {
   

    private static final String ARG_KEY = "key";

    public static MyFragment newInstance(String value) {
   
        MyFragment fragment = new MyFragment();
        Bundle args = new Bundle();
        args.putString(ARG_KEY, value);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
   
        // 获取Fragment的arguments
        Bundle bundle = getArguments();
        if (bundle != null) {
   
            String value = bundle.getString(ARG_KEY);
            // 使用获取到的数据
        }

        return inflater.inflate(R.layout.fragment_layout, container, false);
    }
}

newInstance 方法

  • public static MyFragment newInstance(String value)
    

    这是一个静态工厂方法,用于创建 MyFragment的新实例,并传递数据。这个方法会:

    • 创建一个新的 MyFragment 实例。
    • 创建一个 Bundle 对象来保存参数数据。
    • 将参数存储到 Bundle 中(使用 args.putString(ARG_KEY, value))。
    • Bundle 设置为 Fragmentarguments
    • 返回配置好的 Fragment 实例。

onCreateView 方法

  • @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    

    这是 Fragment 的生命周期方法之一,在 Fragment 的视图创建时调用。这个方法会:

    • 使用 getArguments() 获取 Fragment 的参数 Bundle。如果 Bundle 不为 null,说明参数已经被传递到 Fragment 中。
    • 使用 bundle.getString(ARG_KEY)Bundle 中提取传递的数据。
    • 根据提取的数据进行相应操作(如更新 UI 或执行其他逻辑)。
    • 返回视图的布局(通过 inflater.inflate(R.layout.fragment_layout, container, false) 加载 Fragment 的布局文件)。

这里可能会有一些疑问,newInstance方法尚且可以理解,为什么获取数据一定要写在onCreateView里面呢?写在里面有什么好处?写在别的地方行不行?

Fragment 中获取参数数据通常放在 onCreateView 方法中有其特定的理由,但实际上你也可以在 Fragment 的其他生命周期方法中获取数据。

1. 视图创建时需要数据

onCreateViewFragment 的生命周期方法,在 Fragment 的视图被创建时调用。这个方法的主要任务是创建并返回 Fragment 的视图布局。

  • 依赖数据初始化视图:如果你的视图布局需要依赖于从 Bundle 中获取的数据进行初始化(如填充文本、设置图像等),那么在 onCreateView 中获取数据是合适的。这确保了在视图创建时,数据已经准备好,并且可以用于正确地配置视图。

2. 视图生命周期的一部分

onCreateView 中获取数据可以确保数据在视图创建时就已被处理好。这样,视图就可以立即根据这些数据进行正确的布局和配置。

  • 避免视图未创建问题:如果在 Fragment 的其他生命周期方法(如 onAttachonCreate)中获取数据,但视图还未创建,那么在设置视图的内容时可能会遇到问题。onCreateView 确保视图已被创建,因此可以直接使用数据进行视图的配置。

在其他生命周期方法中获取数据的考虑

1. onAttachonCreate

你可以在 onAttachonCreate 方法中获取数据,但这通常不是最推荐的做法,原因如下:

  • 视图未创建:在这些方法中获取数据时,视图尚未创建。因此,你不能直接用这些数据来更新视图。如果需要在这些方法中处理数据,你需要等到视图创建后才能使用这些数据进行视图更新。

2. 适用场景

尽管在 onCreateView 中获取数据是常见做法,但在其他生命周期方法中获取数据也有其适用场景。例如:

  • onCreate:如果需要在视图创建之前进行一些初始化操作或准备数据(如设置变量),可以在 onCreate 中完成。
  • onActivityCreated:如果需要在 Fragment 的视图创建完成后再进行一些操作,onActivityCreated 可以用来确保 Activity 的视图已经创建完成。

方法二:通过Argument传递

假设我们有一个DataPassFragment,并且我们希望在Activity中的一个按钮点击事件中传递数据给这个Fragment。以下是详细的代码:

1. 定义Fragment类并接收数据

首先,我们定义DataPassFragment,并在其中处理通过Arguments传递的数据。

public class DataPassFragment extends Fragment {
   

    private static final String ARG_STRING_DATA = "data";
    private static final String ARG_INT_DATA = "int_Data";
    
    private String stringData;
    private int intData;

    @Override
    public void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
   
            stringData = getArguments().getString(ARG_STRING_DATA);
            intData = getArguments().getInt(ARG_INT_DATA);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
   
        View view = inflater.inflate(R.layout.fragment_data_pass, container, false);

        // 使用接收到的数据
        TextView textView = view.findViewById(R.id.textView);
        textView.setText("String Data: " + stringData + "\nInt Data: " + intData);

        return view;
    }
}

接收数据

  • @Override public void onCreate(Bundle savedInstanceState):在 Fragment 创建时调用的生命周期方法。在这里,你可以安全地获取并处理传递给 Fragment 的数据。
  • stringData = getArguments().getString(ARG_STRING_DATA);intData = getArguments().getInt(ARG_INT_DATA);:从 Bundle 中提取字符串和整数数据。

2. 在Activity中传递数据

接下来,我们在Activity中定义一个方法,通过Arguments将数据传递给DataPassFragment。假设我们有一个按钮点击事件来触发这个方法。

public class MainActivity extends AppCompatActivity {
   

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

        Button button = findViewById(R.id.button_pass_data);
        button.setOnClickListener(new View.OnClickListener() {
   
            @Override
            public void onClick(View view) {
   
                passDataByArgument(view);
            }
        });
    }

    public void passDataByArgument(View view) {
   
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        
        DataPassFragment dataPassFragment = new DataPassFragment();
        
        Bundle bundle = new Bundle();
        bundle.putString("data", "这是通过Argument传递的数据");
        bundle.putInt("int_Data", 10);
        dataPassFragment.setArguments(bundle);

        fragmentTransaction.replace(R.id.fragment_container_view, dataPassFragment);
        fragmentTransaction.commit();
    }
}

传递数据

  • public void passDataByArgument(View view):定义一个方法来处理数据传递。
  • FragmentManager fragmentManager = getSupportFragmentManager();:获取 FragmentManager 实例,用于管理 Fragment
  • FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();:开始一个新的 FragmentTransaction,用来执行 Fragment 操作(如替换、添加等)。
  • 创建 Fragment 和设置数据
    • DataPassFragment dataPassFragment = new DataPassFragment();:创建一个新的 DataPassFragment 实例。
    • Bundle bundle = new Bundle();:创建一个 Bundle 对象来存储数据。
    • bundle.putString("data", "这是通过Argument传递的数据");bundle.putInt("int_Data", 10);:将数据存储到 Bundle 中。
    • dataPassFragment.setArguments(bundle);:将 Bundle 设置为 Fragment 的参数。
  • 替换现有 Fragment
    • fragmentTransaction.replace(R.id.fragment_container_view, dataPassFragment);:将当前显示的 Fragment 替换为新的 dataPassFragment,并将其添加到 R.id.fragment_container_view 这个容器视图中。
    • fragmentTransaction.commit();:提交事务,应用替换操作。

最后放上两个布局文件:

3. Fragment布局文件

fragment_data_pass.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:padding="16dp">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值