ApiDemos--FragmentArguments的例子分析

来源:互联网 发布:网络实时监控 app 编辑:程序博客网 时间:2024/05/16 15:16

ApiDemos--FragmentArguments的例子分析

 

FragmentArguments这个类向我们展示了两种向Fragment传递参数的方式,一种是在XML中使用属性传递参数,一种是动态地setArguments()方式来设置参数。我们先来看看这两种方式的不同。

1) 通过属性传递参数

此方式就是在XML布局文件设置某个属性来传递参数,通常的布局文件形式如下:

/layout/fragment_arguments.xml

<fragment class="com.example.android.apis.app.FragmentArguments$MyFragment"                android:id="@+id/embedded"                android:layout_width="0px" android:layout_height="wrap_content"                android:layout_weight="1"                apidemos:arguments_label="@string/fragment_arguments_embedded" />

其中的apidemos:arguments_label就是要传递的属性值,当然apidemos是我们的自定义空间名字,arguments_label是我们自定义的属性值。apidemos这个值定义形式如下:

xmlns:apidemos="http://schemas.android.com/apk/res/com.example.android.apis"即xmlns:<自定义空间名>="http://schemas.android.com/apk/res/<应用程序包名>"

 

那么自定义属性的值定义方法是,在/res/values/attrs.xml中如下定义:

<?xml version="1.0" encoding="utf-8"?><resources><declare-styleable name="FragmentArguments">        <attr name="arguments_label" format="string" />    </declare-styleable></resources>

 

上面那个值”FragmentArguments”我们会在代码中用到,我们在其中定义了属性”arguments_label”,它的值是”string”类型。

 

1)动态地setArguments()形式

这个形式是在代码中实现的,通常形式如下:

FragmentTransaction ft = getFragmentManager().beginTransaction();Fragment newFragment = new Fragment();newFragment.setArguments(…);ft.add(R.id.container, newFragment);ft.commit();

 

然后在某处调用Fragment.getArguments()就可以取得传递进来的参数,非常简单。

 

 

看过了上面的参数传递方式之后,如果你已经完全理解了,那么这篇文章你无须再看了。

 

现在开始分析FragmentArguments类,它的定义如下:

 

public class FragmentArguments extends Activity {    @Override protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.fragment_arguments);/*如果发生屏幕翻转或者其他引起该Activity重建的事件,这个savedInstanceState就不为空,这个时候就不应该再ft.add Fragment了,因为重建时Framework会自动恢复视图层中的Fragment。*/        if (savedInstanceState == null) {            // First-time init; create fragment to embed in activity.            FragmentTransaction ft = getFragmentManager().beginTransaction();            Fragment newFragment = MyFragment.newInstance("From Arguments");            ft.add(R.id.created, newFragment);            ft.commit();        }    }}

 

在onCreate()中通过调用setContentView()设置了界面布局,布局文件中设置了属性参数,那么在MyFragment启动的时候,就可以读取这个属性值了,方法如下:

public static class MyFragment extends Fragment {        CharSequence mLabel;/**         * Parse attributes during inflation from a view hierarchy into the         * arguments we handle.         */        @Override public void onInflate(Activity activity, AttributeSet attrs,                Bundle savedInstanceState) {            super.onInflate(activity, attrs, savedInstanceState);            TypedArray a = activity.obtainStyledAttributes(attrs,                    R.styleable.FragmentArguments);            mLabel = a.getText(R.styleable.FragmentArguments_arguments_label);            a.recycle();        }}

 

通过在回调onInflate中调用TypedArray的get方法就可以获取对应的自定义属性的值。onInflate()在Fragment的生命周期中处于onAttach()之前。

 

在MyFragment的newInstance()中我们可以动态添加参数,代码如下:

/**         * Create a new instance of MyFragment that will be initialized         * with the given arguments.         */        static MyFragment newInstance(CharSequence label) {            MyFragment f = new MyFragment();            Bundle b = new Bundle();            b.putCharSequence("label", label);            f.setArguments(b);            return f;        }

 

在它的onCreate()回调中就可以读取这个动态参数,代码如下:

/**         * During creation, if arguments have been supplied to the fragment         * then parse those out.         */        @Override public void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            Bundle args = getArguments();            if (args != null) {                mLabel = args.getCharSequence("label", mLabel);            }        }

 

然后把参数mLabel显示在屏幕中,我们就可以看到效果了。效果图如下:



 

当然了,如果旋转一下屏幕,效果略有不同:


之所以效果不同,是因为/res/layout-land/下也定义了布局文件Fragement_arguments.xml。

 

如果你对上面的TextView的带有白边的背景图疑惑的话,那么是因为TextView设置了自己的背景为android.R.drawable.gallery_thumb,那么这个gallery_thumb到底是什么样的drawable呢?在目录/sdk/platforms/android-19/data/res/drawable中有文件

gallery_thumb.xml,定义如下:

<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2008 The Android Open Source Project<selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/frame_gallery_thumb_selected" />    <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/frame_gallery_thumb_pressed" />    <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/frame_gallery_thumb_pressed" />    <item android:drawable="@drawable/frame_gallery_thumb" /></selector>

 

原来这个drawable是个StateListDrawable,不同的状态下显示不同的图片,这些图片同样可以在同个文件夹或就近的位置找到,我把图贴出来方便大家查看吧。

     frame_gallery_thumb.9.png


  frame_gallery_thumb_pressed.9.png


 frame_gallery_thumb_selected.9.png

 

由于那个TextView是不可点击的,如果设置这个TextVie.setClickable(true);你就能看到效果了。

 

请下载参考完整源码



0 0
原创粉丝点击