Android——Fragment(碎片)

对于碎片的用法,本人认为最重要的就是动态加载碎片。以及碎片和活动之间进行通信。下面的例子将展示如何动态加载碎片以及如何碎片与活动进行通信。
首先要大家可以将碎片理解成和活动具有类似的功能,甚至可以将其想象成一个活动。
首先我们编写activity_main代码,代码如下:

<?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=".MainActivity"
    android:orientation="horizontal">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="添加碎片" />

        <TextView
            android:id="@+id/text_get"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/btn"
            android:text="无"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/text_get"
            android:text="MainActivity信息为:Hello"
            android:textSize="20sp" />

        <Button
            android:id="@+id/btn_get"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="得到碎片信息" />
    </LinearLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1">

        <FrameLayout
            android:id="@+id/another_right_layout"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"></FrameLayout>
        <FrameLayout
            android:id="@+id/right_layout"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"></FrameLayout>
    </LinearLayout>
</LinearLayout>


布局如图,左侧添加的LinearLayout,右侧分为两部分,每一部分都是一个FrameLayout,用来加载碎片。
然后我们编写碎片对应的XML文件和对应的类,代码如下:

  1. 第一个是right_fragment.xml和其对应的类

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:background="@color/red">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:text="this is right fragment"
        android:textSize="20sp" />
</LinearLayout>

在这里插入图片描述
right_fragment.java文件:

package com.example.fragment_text;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class RightFragment extends Fragment {
    String string;
    View view;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view=inflater.inflate(R.layout.right_fragment,container,false);
        return view;
    }
//得到碎片TextView的内容
    public String getString() {
        TextView textView=view.findViewById(R.id.right_text);
        return textView.getText().toString();
    }
}


  1. 第二个是another_right_fragment.xml和其对应的类

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:background="@color/orange"
    android:orientation="vertical">
    <TextView
        android:id="@+id/text_fragment_get"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:text="无"/>
    <Button
        android:id="@+id/btn_fragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="得到活动信息"
        />
    <TextView
        android:id="@+id/text_fragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment信息:Yeah"
        android:textSize="20sp"/>
</LinearLayout>

在这里插入图片描述
anotherRightFragment.java文件:

package com.example.fragment_text;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.ButtonBarLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

public class AnotherRightFragment extends Fragment {
    private View view;
    private String string;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view=inflater.inflate(R.layout.another_right_fragment,container,false);
        Button button=view.findViewById(R.id.btn_fragment);
        final TextView textView=view.findViewById(R.id.text_fragment);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            //得到活动内TextView的内容
            public void onClick(View v) {
                MainActivity mainActivity=(MainActivity) getActivity();
                TextView textView1=view.findViewById(R.id.text_fragment_get);
                textView1.setText(mainActivity.getString());
            }
        });
        Button button1=view.findViewById(R.id.get_fragment_text);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            //得到另一个碎片TextView的内容
            public void onClick(View v) {
                MainActivity mainActivity=(MainActivity)getActivity();
                TextView textView1=view.findViewById(R.id.another_fragment_text);
                RightFragment rightFragment=new RightFragment();
                rightFragment=(RightFragment) mainActivity.getSupportFragmentManager().findFragmentById(R.id.right_layout);
                textView1.setText(rightFragment.getString());
            }
        });

        return view;
    }

    public String getString() {
        TextView textView=view.findViewById(R.id.text_fragment);
        return textView.getText().toString();
    }
}

在类中,我们继承了Fragment,其中要注意的是继承用 android.support.v4.app.Fragment包,然后重写onCreateView方法,在这个方法中通过LayoutInflater 的 inflate()方法将刚才定义的 left_fragment布局动态加载进来,对于该类中的控件的操作,一般都在此方法中使用,最后返回一个view。就类似活动有一个自己的xml文件和自己的java文件。
最后编写MainActivity文件,代码如下:

package com.example.fragment_text;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private String string;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = findViewById(R.id.btn);
        Button button1 = findViewById(R.id.btn_get);
        TextView textView1 = findViewById(R.id.text);
        string = textView1.getText().toString();
        button.setOnClickListener(this);
        button1.setOnClickListener(this);

    }
//得到TextView内容的方法
    public String getString() {
        return string;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn:
                AnotherRightFragment anotherRightFragment = new AnotherRightFragment();
                repalceFragment(anotherRightFragment, R.id.another_right_layout);
                repalceFragment(new RightFragment(), R.id.right_layout);
                break;
                //和碎片进行通信,得到碎片内的方法
            case R.id.btn_get:
                anotherRightFragment = (AnotherRightFragment) getSupportFragmentManager().findFragmentById(R.id.another_right_layout);
                TextView textView = findViewById(R.id.text_get);
                textView.setText(anotherRightFragment.getString());
                break;
        }
    }
//动态加载碎片方法
    private void repalceFragment(Fragment fragment, int layout) {
        FragmentManager fragmentManager = getSupportFragmentManager();//获取FragmentManager
        FragmentTransaction transaction = fragmentManager.beginTransaction();//开启一个事物
        transaction.replace(layout, fragment);//向容器内添加或替换碎片,传入id和待添加的碎片实例
        transaction.addToBackStack(null);//模拟返回栈
        transaction.commit();//提交事务
    }
}

可以看到,首先我们给左侧碎片中的按钮注册了一个点击事件,然后将动态添加碎片的 逻辑都放在了点击事件里进行。结合代码可以看出,动态添加碎片主要分为 5步。

  • 创建待添加的碎片实例。
  • 获取到 FragmentManager,在活动中可以直接调用 getFragmentManager()方法得到。
  • 开启一个事务,通过调用 beginTransaction()方法开启。
  • 向容器内加入碎片,一般使用 replace()方法实现,需要传入容器的 id和待添加的碎 片实例。
  • 提交事务,调用 commit()方法来完成。
  • 其中我们添加了一个返回栈的方法,因为通过点击按钮添加了一个碎片之后,这时按下 Back键程序就会直接退出。如果想按下 Back键可以回到上一个碎片,则需要addToBackStack方法,此时就碎片会像栈一样先进后出。
    碎片与活动间的通信

1.为了方便碎片和活动之间进行通信,FragmentManager提供了一个类似于 findViewById()
的方法,专门用于从布局文件中获取碎片的实例,代码如下所示:

AnotherRightFragment anotherRightFragment = (AnotherRightFragment) getSupportFragmentManager().findFragmentById(R.id.another_right_layout);
TextView textView = findViewById(R.id.text_get);
textView.setText(anotherRightFragment.getString());

调用 FragmentManager的 findFragmentById()方法,可以在活动中得到相应碎片的实例, 然后就能轻松地调用碎片里的方法了。
2.在每个碎片中都可以通过调用 getActivity()方法来得到和当前碎片相关联 的活动实例,代码如下所示:

MainActivity mainActivity=(MainActivity) getActivity();
                TextView textView1=view.findViewById(R.id.text_fragment_get);
                textView1.setText(mainActivity.getString());

有了活动实例之后,在碎片中调用活动里的方法就变得轻而易举了。另外当碎片中需要 使用 Context对象时,也可以使用 getActivity()方法,因为获取到的活动本身就是一个 Context 对象了。

碎片与碎片通信
,首先在一个碎片中 可以得到与它相关联的活动,然后再通过这个活动去获取另外一个碎片的实例,这样也就实 现了不同碎片之间的通信功能

MainActivity mainActivity=(MainActivity)getActivity();
                TextView textView1=view.findViewById(R.id.another_fragment_text);
                RightFragment rightFragment=new RightFragment();
                rightFragment=(RightFragment) mainActivity.getSupportFragmentManager().findFragmentById(R.id.right_layout);
                textView1.setText(rightFragment.getString());

需要注意的是,进行通信时,获取实例是必须用(你需要得到的实例类)强制转换,不然会报错

猜你喜欢

转载自blog.csdn.net/qq_41430142/article/details/86644275