Android 开发之 Fragment

300 阅读3分钟

1. 生命周期

在这里插入图片描述

  • onAttach():Fragment和Activity相关联时调用。可以通过该方法获取Activity引用,还可以通过getArguments()获取参数。
  • onCreate():Fragment被创建时调用
  • onActivityCreated():当Activity完成onCreate()时调用
  • onStart():当Fragment可见时调用。
  • onResume():当Fragment可见且可交互时调用
  • onPause():当Fragment不可交互但可见时调用。
  • onStop():当Fragment不可见时调用。
  • onDestroyView():当Fragment的UI从视图结构中移除时调用。
  • onDestroy():销毁Fragment时调用。
  • onDetach():当Fragment和Activity解除关联时调用。

2. 使用

2.1 静态加载

栗子: 1.定义Fragment布局,新建left_fragment.xml和right_fragment.xml文件

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

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Button" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#00ff00"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:textSize="20sp"
        android:text="this is Fragment" />

</LinearLayout>
  1. 自定义Fragment类,继承Fragment或其子类,重写onCreateView(),在方法中调用inflater.inflate()方法加载Fragment布局文件,接着返回加载的view对象
public class LeftFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.left_fragment, container,false);
        return view;
    }
}
public class RigthFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.right_fragment, container, false);
        return view;
    }
}
  1. 在需要加载Fragment的Activity对应的布局文件中添加Fragment标签
<fragment
    android:id="@+id/left_fragment"
    android:name="com.test.LeftFragment"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1" />
<fragment
    android:id="@+id/right_fragment"
    android:name="com.test.RigthFragment"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    />
  1. 在Activity的onCreate()方法中调用setContentView()加载布局文件即可 注意:静态加载一旦添加就不能在运行时删除

2.2 动态加载

栗子:

  1. 同静态加载一样,首先定义Fragment的布局和类,修改主布局文件,不指定标签的name属性。
  2. 实现Fragment调用
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(this);
        replaceFragment(new RigthFragment());
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                replaceFragment(new AnotherRightFragment());
                break;
            default:
                break;
        }
    }

    private void replaceFragment(Fragment fragment) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();  
        transaction.replace(R.id.right_layout, fragment);
        transaction.commit();
    }
}

3. Fragment 与 Activity 通信

3.1 Activity 传递数据到 Fragment(采用 Bundle 方式)

栗子

  1. Activity 的布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        android:text="我是Activity" />

    <FrameLayout
        android:layout_below="@+id/button"
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="500dp"/>
</LinearLayout>
  1. 设置 Fragment 的布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorAccent"
    >

    <TextView
        android:id="@+id/fragment"
        android:text="我是fragment"
        android:layout_gravity="center"
        android:textSize="30dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <TextView
        android:id="@+id/text"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        android:text="等待Activity发送消息" />

    <Button
        android:id="@+id/button"
        android:layout_gravity="center"
        android:text="点击接收Activity消息"
        android:layout_centerInParent="true"
        android:textSize="20dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>
  1. 设置Activity的类文件
public class Activity2Fragment extends AppCompatActivity {

    TextView text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activcity_2_fragment);
        text = (TextView) findViewById(R.id.text);

        // 步骤1:获取FragmentManager
        FragmentManager fragmentManager = getFragmentManager();

        // 步骤2:获取FragmentTransaction
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        // 步骤3:创建需要添加的Fragment 
        final mFragment fragment = new mFragment();

        // 步骤4:创建Bundle对象
        // 作用:存储数据,并传递到Fragment中
        Bundle bundle = new Bundle();

        // 步骤5:往bundle中添加数据
        bundle.putString("message", "I love Google");

        // 步骤6:把数据设置到Fragment中
        fragment.setArguments(bundle);

        // 步骤7:动态添加fragment
        // 即将创建的fragment添加到Activity布局文件中定义的占位符中(FrameLayout)
        fragmentTransaction.add(R.id.fragment_container, fragment);
        fragmentTransaction.commit();
    }
}
  1. 设置Fragment的类文件
public class mFragment extends Fragment {
    Button button;
    TextView text;
    Bundle bundle;
    String message;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View contentView = inflater.inflate(R.layout.fragment, container, false);
        // 设置布局文件

        button = (Button) contentView.findViewById(R.id.button);
        text = (TextView) contentView.findViewById(R.id.text);

        // 步骤1:通过getArgments()获取从Activity传过来的全部值
        bundle = this.getArguments();

        // 步骤2:获取某一值
        message = bundle.getString("message");

        // 步骤3:设置按钮,将设置的值显示出来
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // 显示传递过来的值
                text.setText(message);

            }
        });

        return contentView;
    }
}

3.2 Fragment 传递数据到 Activity(接口回调)

  1. Activity 的布局文件
<RelativeLayout 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: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="scut.carson_ho.fragment_2_activity.MainActivity">

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        android:text="等待Fragment发送消息" />

    <Button
        android:id="@+id/button"
        android:layout_below="@+id/text"
        android:text="点击接收Fragment消息"
        android:layout_centerInParent="true"
        android:textSize="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <FrameLayout
        android:layout_below="@+id/button"
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="500dp"/>

</RelativeLayout>
  1. 设置 Fragment 的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <TextView
        android:id="@+id/fragment"
        android:text="我是fragment"
        android:gravity="center"
        android:textSize="30dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorAccent"/>

</LinearLayout>
  1. 设置回调接口
public interface ICallBack {
    void get_message_from_Fragment(String string);

}
  1. 设置 Fragment 的类文件
public class mFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View contentView = inflater.inflate(R.layout.fragment, container, false);
        // 设置布局文件
        return contentView;
    }

    // 设置 接口回调 方法
    public void sendMessage(ICallBack callBack){

        callBack.get_message_from_Fragment("消息:我来自Fragment");

    }
}
  1. 设置 Acticvity 的类文件
public class MainActivity extends AppCompatActivity {

    Button button;
    TextView text;

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

        button = (Button)findViewById(R.id.button);
        text = (TextView)findViewById(R.id.text);

        // 步骤1:获取FragmentManager
        FragmentManager fragmentManager = getFragmentManager();

        // 步骤2:获取FragmentTransaction
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        // 步骤3:创建需要添加的Fragment 
        final mFragment fragment = new mFragment();

        // 步骤4:动态添加fragment
        // 即将创建的fragment添加到Activity布局文件中定义的占位符中(FrameLayout)
        fragmentTransaction.add(R.id.fragment_container, fragment);
        fragmentTransaction.commit();


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // 通过接口回调将消息从fragment发送到Activity
                fragment.sendMessage(new ICallBack() {
                    @Override
                    public void get_message_from_Fragment(String string) {
                            text.setText(string);
                    }
                });

            }
        });
    }
}