Fragment的介绍和使用(三)

上一节简单实现了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的文字就会发生改变:
Fragment的介绍和使用(三)_第1张图片

Android提供的常用Fragment

DialogFragment

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

首先我写一下布局:



    

    

    

        

然后对应的,我们创建一个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();
    }
}

下面我们看显示效果:
Fragment的介绍和使用(三)_第2张图片

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

@Override
public 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();
}

效果图如下:
Fragment的介绍和使用(三)_第3张图片

ListFragment

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

public class MyListFragment extends ListFragment {
    private List 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 adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, mList);
        setListAdapter(adapter);
    }
}

Fragment的介绍和使用(三)_第4张图片

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

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

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

你可能感兴趣的:(Android)