为什么要在Fragment中使用setArgument?
我们知道,当app的屏幕进行旋转或者其他的配置变化的时候,Fragment会执行它的周期变化,重新创建Fragment并加载(除非设置了setRetainInstance(true)),那么在重建的时候Fragment中的变量就会被重新初始化,运行中的状态将无法保留。
setArgument中的Bundle可以用来存放各种需要保持的数据,即使Fragment由于配置改变而重建,这些保存的数据也不会被清除。
下面我们将通过一个实例来测试一下,在实例的Fragment中共有3个TextView和一个Button,为了使测试的内容更清晰,下面把三个TextView对应的字符串列表如下:
textview1->banana, textview2->apple, textview3->pear
对应的三个字符串:
- mParam1: 在Fragment.newInstance中传入,并保存在setArgument中,但是在点击按钮时未更新到Argument中
- mParam2: Fragment中的私有变量,和Argument无任何交互
- mParam3: 在Fragment.newInstance中传入,并保存在setArgument中,并且在点击按钮时更新到了Argument中
测试程序的布局代码和java代码如下:
Fragment部局文件的代码
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <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"               tools:context="com.bcoder.myapplication.TestFragment"               android:orientation="vertical">     <!-- TODO: Update blank fragment layout -->     <TextView         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:text="textview1"         android:id="@+id/textview1"/>     <TextView         android:text="TextView"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:id="@+id/textview2"/>     <TextView         android:text="TextView"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:id="@+id/textview3"/>     <Button         android:text="Button"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:id="@+id/button1"/> </LinearLayout> | 
Fragment的Java代码
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | package com.bcoder.myapplication; import android.content.Context; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; public class TestFragment extends Fragment {     private static final String ARG_PARAM1 = "param1";     private static final String ARG_PARAM3 = "param3";     private String mParam1;     private String mParam2;     private String mParam3;     TextView mTextView1;     TextView mTextView2;     TextView mTextView3;     Button button1;     View fragmentView;     public TestFragment() {         // Required empty public constructor     }     public static TestFragment newInstance(String param1, String param3) {         TestFragment fragment = new TestFragment();         Bundle args = new Bundle();         args.putString(ARG_PARAM1, param1);         args.putString(ARG_PARAM3, param3);         fragment.setArguments(args);         return fragment;     }     @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         if (getArguments() != null) {             mParam1 = getArguments().getString(ARG_PARAM1);             mParam3 = getArguments().getString(ARG_PARAM3);         }     }     @Override     public View onCreateView(LayoutInflater inflater, ViewGroup container,                              Bundle savedInstanceState) {         fragmentView = inflater.inflate(R.layout.fragment_test, container, false);         initViews();         mTextView1.setText(mParam1);         mTextView2.setText(mParam2);         mTextView3.setText(mParam3);         return fragmentView;     }     private void initViews() {         mTextView1 = (TextView) fragmentView.findViewById(R.id.textview1);         mTextView2 = (TextView) fragmentView.findViewById(R.id.textview2);         mTextView3 = (TextView) fragmentView.findViewById(R.id.textview3);         button1 = (Button) fragmentView.findViewById(R.id.button1);         button1.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View view) {                 mParam1 = "banana2";                 mTextView1.setText(mParam1);                 mParam2 = "apple";                 mTextView2.setText(mParam2);                 mParam3 = "pear click";                 getArguments().putString(ARG_PARAM3, mParam3);                 mTextView3.setText(mParam3);             }         });     }     @Override     public void onAttach(Context context) {         super.onAttach(context);     }     @Override     public void onDetach() {         super.onDetach();     } } | 
主Activity的代码
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package com.bcoder.myapplication; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.LinearLayout; public class MainActivity extends AppCompatActivity {     LinearLayout layoutContainer;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         initViews();         TestFragment fragment = TestFragment.newInstance("banana", "pear");         FragmentManager manager = getSupportFragmentManager();         FragmentTransaction transaction = manager.beginTransaction();         transaction.add(R.id.layoutFragmentContainer, fragment);         transaction.commit();     }     private void initViews() {         layoutContainer = (LinearLayout) findViewById(R.id.layoutFragmentContainer);     } } | 
主Activity的布局文件代码
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?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:id="@+id/activity_main"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:paddingBottom="@dimen/activity_vertical_margin"     android:paddingLeft="@dimen/activity_horizontal_margin"     android:paddingRight="@dimen/activity_horizontal_margin"     android:paddingTop="@dimen/activity_vertical_margin"     tools:context="com.bcoder.myapplication.MainActivity"     android:orientation="vertical">     <LinearLayout         android:orientation="vertical"         android:layout_width="match_parent"         android:layout_height="match_parent"         android:id="@+id/layoutFragmentContainer">     </LinearLayout> </LinearLayout> | 
程序启动时显示默认如下内容:
textview1和textview3的值取自getArgument并显示在了屏幕上,当点击按钮时会重新给三个String变量赋值,并显示到textview中,如下图:
这时三个字符串变量都有了新的值,那么当我们把屏幕进行一下旋转操作后,看结果如何呢?
由图可知,字符串1回到了最初的状态(创建Fragment时传入的值),而字符串2被清除了。
字符串3因为在点击按钮的时候重新被保存在getArgument中,而没有任何的变化的被保留下来了。
因此大家在给Fragment传入参数的时候最好通过setArgument进行保存,而不是简单的通过一个变量进行保存。
注意:
- setArgument只能在Fragment中创建后(MyFragment fragment = new MyFragment())立即调用,如果在Fragment被附加到Activity中后再调用就会报错,可以在按钮的点击事件中添加一下setArgument的调用进行一下试验,应用将被异常终止。




 
                 微信扫一扫,打赏作者吧~
微信扫一扫,打赏作者吧~