Day2_25_第五天 Fragment高级进阶

主宰稳场 提交于 2020-02-26 02:26:27

一.Fragment回退栈

通过代码,将fragment加入到栈中,按返回键时会将fragment弹栈

public class Main2Activity extends AppCompatActivity {
    private FragmentManager supportFragmentManager;
    private BlankFragment blankFragment;
    private Button butBack;


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

        initViews();
    }

    private void initViews() {
        supportFragmentManager = getSupportFragmentManager();//获取碎片管理者
        FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();//创建事务
        blankFragment = new BlankFragment();//创建碎片
        butBack = (Button) findViewById(R.id.but_back);

        fragmentTransaction.add(R.id.content_layout2, blankFragment);//添加到布局里
        fragmentTransaction.addToBackStack("1");//添加到回退栈
        fragmentTransaction.commit();//提交事务

        butBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                supportFragmentManager.popBackStack();//弹栈
            }
        });
    }


}

添加到回退栈需要用到事务里的 addToBackStack() 方法
而手动弹栈需要用到碎片管理者的 popBackStack() 方法

二.Fragment传值

1.Activity给Fragment传值

在Activity中将Fragment对象调用 setArguments() 方法进行设置传值,该方法的参数是一个 Bundle 对象,需要创建Bundle对象,再将要传递的值设置到Bundle对象里

public class Main3Activity extends AppCompatActivity {
    private EditText etText;
    private Button butSend;

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

    private void initViews() {

        etText = (EditText) findViewById(R.id.et_text);
        butSend = (Button) findViewById(R.id.but_send);

        final FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = manager.beginTransaction();
        BlankFragment3 fragment3 = new BlankFragment3();
        fragmentTransaction.replace(R.id.content_lay, fragment3);
        fragmentTransaction.commit();

        butSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String s = etText.getText().toString();
                BlankFragment3 blankFragment3 = new BlankFragment3();

                Bundle bundle = new Bundle();//创建Bundle对象
                bundle.putString("val",s);
                blankFragment3.setArguments(bundle);//传值

                FragmentTransaction transaction = manager.beginTransaction();
                transaction.replace(R.id.content_lay,blankFragment3);
                transaction.commit();
            }
        });

    }
}

在传递的Fragment中直接调用 getArguments() 方法获取Bundle对象,取出传递的数据(如果在onCreateView()方法中获取到的Bundle需要进行非空判断,否则在创建Fragment对象时会空指针异常)

public class BlankFragment3 extends Fragment {
    private TextView textShow;


    public BlankFragment3() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        View view = inflater.inflate(R.layout.fragment_blank_fragment3, container, false);
        textShow = (TextView) view.findViewById(R.id.text_show);
        Bundle arguments = getArguments();//获取传递的数据
        if (arguments != null) {
            String val = arguments.getString("val");
            textShow.setText(val);
        }
        return view;
    }

}

Activity中的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".Main3Activity">
    <EditText
        android:id="@+id/et_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/but_send"
        android:text="发送"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:id="@+id/content_lay"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

    </LinearLayout>


</LinearLayout>

Fragment中的布局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".BlankFragment3">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/text_show"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>

效果展示(上方为Activity中的控件,下方TextView为Fragment中的控件)
在这里插入图片描述

2.Fragment给Activity传值

Fragment给Activity传值中,需要用到接口回调的方式进行传值
1.创建接口
2.在Fragment中声明一个接口的对象
3.Activity实现接口
4.使Fragment中的对象=Activity,父类指向子类引用
5.接口的参数就可以在Activity中使用

Activity中的代码

public class Main4Activity extends AppCompatActivity implements BlankFragment4.MyListener {
    private TextView teShow;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main4);
        teShow = (TextView) findViewById(R.id.te_show);
    }

    @Override
    public void msg(String s) {
        teShow.setText(s);
    }
}

Fragment中的代码

public class BlankFragment4 extends Fragment {
    private EditText et;
    private Button buSend;


    public BlankFragment4() {
        // Required empty public constructor
    }

    public interface MyListener{
        void msg(String s);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        myListener = (MyListener) getActivity();
    }

    private MyListener myListener;


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

        et = (EditText) view.findViewById(R.id.et);
        buSend = (Button) view.findViewById(R.id.bu_send);
        buSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String s = et.getText().toString();
                myListener.msg(s);
            }
        });
        // Inflate the layout for this fragment
        return view;
    }

}

在Fragment中的接口对象赋值时,要注意比onCreateView()方法先执行,否则接口对象为空,空指针异常

Activity中的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".Main4Activity">

    <TextView
        android:text="..........."
        android:id="@+id/te_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <fragment
        android:id="@+id/fr"
        android:name="com.example.day2_25.BlankFragment4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

Fragment中的布局

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".BlankFragment4">

    <!-- TODO: Update blank fragment layout -->
    <EditText
        android:id="@+id/et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/bu_send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="发送" />

</LinearLayout>

效果展示(上方TextView为Activity中的控件,下方为Fragment中的控件)
在这里插入图片描述

3.Fragment给Fragment传值

三种方式

  • 在Fragment中获取到另一个Fragment的对象进行操作

动态创建的fragment通过findFragmentByTag得到另一个的Fragment的对象。
静态创建的fragment通过findFragmentById得到另一个的Fragment的对象。

  • 通过上述2的接口回调方法,意思相同
  • 通过上述1的setArguments,getArguments方法进行传值

下面展示第一种方法

Fragment1中的代码

public class BlankFragment51 extends Fragment {
    private TextView fTeShow;


    public BlankFragment51() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_blank_fragment51, container, false);
        // Inflate the layout for this fragment
        fTeShow = (TextView) view.findViewById(R.id.f_teShow);
        return view;
    }

    public void setTextView(String s) {
        fTeShow.setText(s);
    }
}

Fragment2中的代码

public class BlankFragment52 extends Fragment {
    private EditText fEt;
    private Button fBut;


    public BlankFragment52() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_blank_fragment52, container, false);
        fEt = (EditText) view.findViewById(R.id.f_et);
        fBut = (Button) view.findViewById(R.id.f_but);
        fBut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fragmentManager = getFragmentManager();
                BlankFragment51 fragmentById = (BlankFragment51) fragmentManager.findFragmentById(R.id.f1);
                fragmentById.setTextView(fEt.getText().toString());
            }
        });

        return view;
    }

}

在Fragment1中自定义一个设置的方法将要设置的数据通过参数形式传递
Activity中的布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Main5Activity">

    <fragment
        android:id="@+id/f1"
        android:name="com.example.day2_25.BlankFragment51"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <fragment
        android:id="@+id/f2"
        android:name="com.example.day2_25.BlankFragment52"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

</LinearLayout>

Fragment1中的布局文件

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".BlankFragment51">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/f_teShow"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="123456" />

</LinearLayout>

Fragment2中的布局文件

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".BlankFragment52">

    <!-- TODO: Update blank fragment layout -->
    <EditText
        android:id="@+id/f_et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/f_but"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="发送" />

</LinearLayout>

效果展示(左边为Fragment1中的控件,右边为Fragment2中的控件)
在这里插入图片描述

三.Fragment多层嵌套

就是在Fragment布局中引入另一个Fragment
基本操作相同
值得注意的是获取碎片管理者时需要通过
FragmentManager childFragmentManager = getChildFragmentManager()
其余操作一样

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!