Android 中 Fragment 的基本使用
1. 基础了解
Fragment 有自己的生命周期
Fragment 依赖于 Activity
Fragment 通过 getActivity() 可以获取所在的 Activity; Activity 通过 FragmentManager 的 findFragmentById()
或 findFragmentByTag() 获取 FragmentFragment 和 Activity 是多对多的关系
2. 了解使用
Activity 嵌一个 Fragment, 点击按钮切换另一个.
ContainerActivity 文件
package com.example.hello.fragment;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import android.os.Bundle;
import android.widget.Button;
import com.example.hello.R;
public class ContainerActivity extends AppCompatActivity {
private AFragment aFragment;
private BFragment bFragment;
private Button btnChange;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_container);
btnChange = findViewById(R.id.btn_change_fragment);
btnChange.setOnClickListener(v -> {
// 切换
if (bFragment == null) {
bFragment = new BFragment();
}
// 防止实例
Fragment fragment = getSupportFragmentManager().findFragmentByTag("a");
if (fragment != null) {
getSupportFragmentManager().beginTransaction().hide(fragment).add(R.id.content_fragment, bFragment).addToBackStack(null).commitAllowingStateLoss();
} else {
getSupportFragmentManager().beginTransaction().replace(R.id.content_fragment, bFragment).addToBackStack(null).commitAllowingStateLoss();
}
});
// 实例化
aFragment = new AFragment("参数");
// 将 aFragment 放入到 Activity 中
getSupportFragmentManager().beginTransaction().add(R.id.content_fragment, aFragment, "a").commitAllowingStateLoss();
}
}
activity_container.xml
<?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"
android:padding="15dp"
tools:context=".fragment.ContainerActivity">
<Button
android:id="@+id/btn_change_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/changeFragment" />
<FrameLayout
android:id="@+id/content_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
AFragment
package com.example.hello.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.example.hello.R;
public class AFragment extends Fragment {
private TextView tvA;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.fragment_a, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tvA = view.findViewById(R.id.fragment_tv);
}
}
<?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"
android:padding="15dp">
<TextView
android:id="@+id/fragment_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/fragmentA"
android:textColor="@color/black"
android:textSize="20sp" />
</LinearLayout>
BFragment
package com.example.hello.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.example.hello.R;
public class BFragment extends Fragment {
private TextView tvB;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.fragment_b, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tvB = view.findViewById(R.id.fragment_tv);
}
}
<?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"
android:padding="15dp">
<TextView
android:id="@+id/fragment_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/fragmentB"
android:textColor="@color/black"
android:textSize="20sp" />
</LinearLayout>
3. 传递参数
向 Fragment 传递参数.
新版本的可以用构造函数.
// 实例化
aFragment = new AFragment("参数");
AFragment
package com.example.hello.fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.example.hello.R;
public class AFragment extends Fragment {
private TextView tvA;
private String title;
public AFragment(String title) {
this.title = title;
}
public AFragment() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.fragment_a, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tvA = view.findViewById(R.id.fragment_tv);
if (title != null) {
tvA.setText(title);
}
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
}
@Override
public void onDetach() {
super.onDetach();
}
}
4. Fragment 和 Activity 的通信
AFragment 文件
package com.example.hello.fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.example.hello.R;
public class AFragment extends Fragment {
private TextView tvA;
private Button btnChangeContent;
private String title;
private ChangeContent changeContent;
public AFragment(String title) {
this.title = title;
}
public AFragment() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.fragment_a, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tvA = view.findViewById(R.id.fragment_tv);
if (title != null) {
tvA.setText(title);
}
btnChangeContent = view.findViewById(R.id.btn_change_content);
btnChangeContent.setOnClickListener(v -> {
changeContent.setContent("改变的内容");
});
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
// 没有实现该接口会报错
changeContent = (ChangeContent) context;
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onDetach() {
super.onDetach();
}
/**
* 通信
*/
public interface ChangeContent {
void setContent(String title);
}
}
fragment_a.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"
android:padding="15dp">
<Button
android:id="@+id/btn_change_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/changeContent" />
<TextView
android:id="@+id/fragment_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/fragmentA"
android:textColor="@color/black"
android:textSize="20sp" />
</LinearLayout>
ContainerActivity 文件实现 AFragment 中接口进行通信.
package com.example.hello.fragment;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import android.os.Bundle;
import android.widget.Button;
import com.example.hello.R;
public class ContainerActivity extends AppCompatActivity implements AFragment.ChangeContent {
private AFragment aFragment;
private BFragment bFragment;
private Button btnChange;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_container);
btnChange = findViewById(R.id.btn_change_fragment);
btnChange.setOnClickListener(v -> {
// 切换
if (bFragment == null) {
bFragment = new BFragment();
}
// 防止实例
Fragment fragment = getSupportFragmentManager().findFragmentByTag("a");
if (fragment != null) {
getSupportFragmentManager().beginTransaction().hide(fragment).add(R.id.content_fragment, bFragment).addToBackStack(null).commitAllowingStateLoss();
} else {
getSupportFragmentManager().beginTransaction().replace(R.id.content_fragment, bFragment).addToBackStack(null).commitAllowingStateLoss();
}
});
// 实例化
aFragment = new AFragment("参数");
// 将 aFragment 放入到 Activity 中
getSupportFragmentManager().beginTransaction().add(R.id.content_fragment, aFragment, "a").commitAllowingStateLoss();
}
/**
* 改变内容
*
* @param title 内容
*/
@Override
public void setContent(String title) {
btnChange.setText(title);
}
}