Fragment的介绍和使用(三)

来源:互联网 发布:免费啪啪的软件 编辑:程序博客网 时间:2024/05/01 07:10

上一节简单实现了Fragment的动态使用,但是还有很多细节没有提及,这一节我们把一些常用的细节说说一说。

Fragment传递参数

上一节里我们可以实现Fragment之间跳转,但是我们需要在跳转的同时传递参数,要怎么办呢?不要着急,Google的工程师也想到了,所以提供了解决方法。

Fragment有个叫做setArguments(Bundle)的方法,用来传递参数;我们可以通过Bundle,添加我们需要的参数,然后再Fragment里使用getArguments()获取。
比如:

Fragment2 fragment2 = new Fragment2();Bundle bundle = new Bundle();bundle.putString("aaa","bbbb");fragment2.setArguments(bundle);

然后我们在Fragment里面可以在onCreate()里面获取这些参数:

Bundle bundle = getArguments(); String v = bundle.getString("aaa");

在官网上,提供了demo,使用的是静态方法。下面我们通过两个Fragment,来展示一下用法。

第一个Fragment,我们叫做FragmentOne;第二个Fragment我们叫做FragmentTwo,我们需要从FragmentOne传递参数到FragmentTwo.

FragmentOne:

public class FragmentOne extends Fragment {    public static final String ARGUMENT_KEY = "ARGUMENT_KEY";    private View rootView;    private Button btnJump2FragmentTwo;    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        rootView = inflater.inflate(R.layout.fragment_layout_one, container, false);        btnJump2FragmentTwo = (Button) rootView.findViewById(R.id.btn_jump_2_fragment_two);        btnJump2FragmentTwo.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Bundle bundle = new Bundle();                bundle.putString(ARGUMENT_KEY,"这个是从FragmentOne传递给FragmentTwo的参数");                FragmentTwo fragmentTwo = FragmentTwo.getFragmentTwo(bundle);                getFragmentManager().beginTransaction().add(R.id.ft_container,fragmentTwo).commit();            }        });        return rootView;    }}

FragmentTwo:

public class FragmentTwo extends Fragment {    public static FragmentTwo getFragmentTwo(Bundle argumentBundle) {        FragmentTwo fragmentTwo = new FragmentTwo();        fragmentTwo.setArguments(argumentBundle);        return fragmentTwo;    }    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Bundle bundle = getArguments();        if (bundle != null) {            String argument = bundle.getString(FragmentOne.ARGUMENT_KEY);            LogUtils.e(argument);        }    }    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        return inflater.inflate(R.layout.fragment_layout_two,container,false);    }}   

在FragmentTwo里面,我们获取到参数后,只打印了一下。

Fragment 启动 Activity

在Fragment里打开一个新的Activity的方式跟Activity之间的跳转一样都是使用startActivity()这个方法;如果需要传递返回值,需要startActivityForResult()onActivityResult配合使用;如果启动了一个新的Activity里面有一个Fragment,需要在Fragment里面执行 setResult(),但是Fragment里不提供这个方法,要如何办呢?我们可以使用 getActivity().setResult()

关于这些内容就不再代码演示了,跟Activity几乎一模一样,大家就按着Activity的实现方式实现就OK了。

Fragment 如何与Activity 交互

官网提供的方式是使用接口回调。

我们首先创建一个Fragment,并且定义一个回调接口,用来在Activity中回调。

public class BlankFragment extends Fragment {    //定义一个回调接口    private OnFragmentInteractionListener mListener;    public BlankFragment() {    }    public static BlankFragment newInstance(Bundle arg) {        BlankFragment fragment = new BlankFragment();        Bundle args = new Bundle();        fragment.setArguments(args);        return fragment;    }    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        if (getArguments() != null) {            Bundle args = getArguments();        }    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment_blank, container, false);        Button button = (Button) view.findViewById(R.id.btn_change_text);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //将下面的这些文字传递给Activity                onButtonPressed("我要修改Activity中的文字");            }        });        return view;    }    public void onButtonPressed(String text) {        if (mListener != null) {            mListener.onFragmentInteraction(text);        }    }    @Override    public void onAttach(Context context) {        super.onAttach(context);        if (context instanceof OnFragmentInteractionListener) {            mListener = (OnFragmentInteractionListener) context;        } else {            throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener");        }    }    @Override    public void onDetach() {        super.onDetach();        mListener = null;    }    /**     * 回调的接口,需要在Activity中实现,当我们的Fragment有操作时,会通过里面的方法通知到Activity     */    public interface OnFragmentInteractionListener {        //通知到Activity Fragment 有操作,并且将需要的参数传递给Activity        void onFragmentInteraction(String text);    }}

在Activity中就简单多了,只需要继承Fragment中实现的接口,并将Fragment显示到界面,就Ok了。

public class BlankActivity extends AppCompatActivity implements BlankFragment.OnFragmentInteractionListener {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_blank);        //获取Fragment的实例,这里我们不需要传递参数        BlankFragment fragment = BlankFragment.newInstance(null);        //将Fragment加入到Activity中        getFragmentManager().beginTransaction().add(R.id.ft_container, fragment).commit();    }    @Override    public void onFragmentInteraction(String text) {        TextView textView = (TextView) findViewById(R.id.textView);        textView.setText(text);    }}

当我们点击Fragment中的按钮时,Activity中TextView的文字就会发生改变:

Android提供的常用Fragment

DialogFragment

仅仅从字面上,就知道这是一个类似对话框的Fragment,它可以很容易的实现自定义对话框;当然它还依然是一个Fragment,跟其它的Fragment有一样的生命周期,只是它被封装成了一个专门显示Dialog的Fragment。它没有自己的界面,这需要我们继承它,然后重写它的onCreateView()方法,然后自定义界面就OK。下面我来看代码:

首先我写一下布局:

<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:layout_margin="10dp"              android:orientation="vertical"              android:padding="15dp"              tools:context="com.liteng.app.fragments.commonfragment.MyDialogFragment">    <TextView        android:id="@+id/textView2"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:text="这是Dialog的标题"/>    <TextView        android:id="@+id/textView3"        android:layout_width="match_parent"        android:layout_height="100dp"        android:layout_below="@+id/textView2"        android:text="这是Dialog的内容"        android:textSize="28sp"/>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@+id/textView3"        android:orientation="horizontal">        <Button            android:id="@+id/btnOk"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="确定"/>        <Button            android:id="@+id/btnCancel"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="取消"/>    </LinearLayout></LinearLayout>

然后对应的,我们创建一个DialogFragment的子类:

public class MyDialogFragment extends DialogFragment implements View.OnClickListener {    private View rootView;    private TestActivity mActivity;    //在Fragment附着在Activity上时,获取要附着的Activity实例。    @Override    public void onAttach(Activity activity) {        super.onAttach(activity);        mActivity = (TestActivity) activity;    }    //创建Fragment 实例    public static MyDialogFragment newInstance(String arg) {        MyDialogFragment f = new MyDialogFragment();        Bundle args = new Bundle();        args.putString("arg", arg);        f.setArguments(args);        return f;    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        rootView = inflater.inflate(R.layout.fragment_my_dialog, container, false);        initViews();        return rootView;    }    private void initViews() {        rootView.findViewById(R.id.btnOk).setOnClickListener(this);        rootView.findViewById(R.id.btnCancel).setOnClickListener(this);    }    //监听Dialog消失    @Override    public void onDismiss(DialogInterface dialog) {        super.onDismiss(dialog);        Toast.makeText(getActivity(), "Dialog Dismiss", Toast.LENGTH_SHORT).show();    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.btnOk:                //通过Activity的实例来调用Dialog消失的方法                mActivity.dismissDialog();                Toast.makeText(getActivity(), "Dialog OK", Toast.LENGTH_SHORT).show();                break;            case R.id.btnCancel:                //取消Dialog的显示,使用返回键也可以达到同样的结果                mActivity.dismissDialog();                Toast.makeText(getActivity(), "Dialog Cancel", Toast.LENGTH_SHORT).show();                break;        }    }}

最后我们把DialogFragment显示出来。

public class TestActivity extends AppCompatActivity {    MyDialogFragment mDialogFragment;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_test);        mDialogFragment = MyDialogFragment.newInstance(null);    }    public void showDialog(View view) {        //点击按钮时,显示Dialog        mDialogFragment.show(getFragmentManager(), "dialog");    }    //Dialog 消失    public void dismissDialog(){        mDialogFragment.dismiss();    }}

下面我们看显示效果:

如果不想自己去定义界面,也可以在 DialogFragment 里面实现Android自带的AlertDialog效果,我们只需要在重写DialogFragmentonCreateDialog(),然后在里面是实现AlertDialog就OK了。

@Overridepublic Dialog onCreateDialog(Bundle savedInstanceState) {    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());    builder.setTitle("标题");    builder.setMessage("消息提示!!!");    builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {        @Override        public void onClick(DialogInterface dialog, int which) {            Toast.makeText(getActivity(),"确定",Toast.LENGTH_SHORT).show();        }    });    builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {        @Override        public void onClick(DialogInterface dialog, int which) {            Toast.makeText(getActivity(),"取消",Toast.LENGTH_SHORT).show();        }    });    return builder.create();}

效果图如下:

ListFragment

这个Fragment里面封装了一个ListView,我们只需要是 setListAdapter方法,给ListView设置一个Adapter就OK。

public class MyListFragment extends ListFragment {    private List<String> mList;    public MyListFragment() {        mList = new ArrayList<>();        for (int i = 0; i < 10; i++) {            mList.add("Title = " + i);        }    }    //创建Fragment 实例    public static MyListFragment newInstance(String arg) {        MyListFragment f = new MyListFragment();        Bundle args = new Bundle();        args.putString("arg", arg);        f.setArguments(args);        return f;    }    @Override    public void onActivityCreated(Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, mList);        setListAdapter(adapter);    }}

效果如下:
当然如果我们需要行点击事件,可以重写它的onListItemClick 方法即可:

@Overridepublic void onListItemClick(ListView l, View v, int position, long id) {    Toast.makeText(getActivity(), "点击的是第" + position + "项", Toast.LENGTH_SHORT).show();}

其它还有 PreferenceFragmentWebViewFragment,这里就不再一一介绍了,大家有兴趣可以研究一下。

0 0
原创粉丝点击