Jacky's blog
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)
  • tutorial
  • jetpack

  • components

  • androidx

    • fragment
      • 基础知识
        • Fragment状态定义
        • Fragment基本操作
        • Fragment生命周期回调
      • 生命周期管理
        • 状态向上转移过程
        • 状态转移详解
        • onAttach详细分析
        • isAdded返回值
      • Fragment管理器
        • getFragmentManager vs getChildFragmentManager
        • 1. getFragmentManager()
        • 2. getChildFragmentManager()
        • Fragment事务管理
      • 数据传递与通信
        • Fragment间数据传递
        • 1. 使用Bundle传递数据
        • 2. 使用ViewModel共享数据
        • 3. Fragment结果API
        • Fragment与Activity通信
        • 1. 接口回调
        • 2. 使用Activity的ViewModel
      • 高级特性
        • Fragment工厂模式
        • Fragment状态保存与恢复
        • Fragment懒加载
      • 常见问题与解决方案
        • 1. Fragment has not been attached yet
        • 2. Fragment状态丢失
        • 3. Fragment重叠问题
        • 4. Fragment生命周期混乱
        • 5. Fragment事务提交失败
        • 6. Fragment内存泄漏
      • 最佳实践
        • 1. Fragment设计原则
        • 2. 性能优化
        • 3. 错误处理
        • 4. 测试策略
      • 实际应用案例
        • 1. 主从Fragment模式
        • 2. 标签页Fragment
        • 3. 对话框Fragment
  • 动态化
  • apm

  • module

  • harmony

  • tool

  • other

  • kotlin

  • 《android》
  • androidx
Jacky
2024-11-21
目录

fragment

  • android developer#fragments (opens new window)
  • FragmentManagerImpl (opens new window)
  • BackStackRecord (opens new window)

# 基础知识

Fragment是Android中的一个重要组件,代表Activity中的行为或用户界面的一部分。Fragment具有自己的生命周期,可以接收自己的输入事件,并且可以在Activity运行时添加或删除。

# Fragment状态定义

static final int INITIALIZING = 0;    // 初始化状态
static final int CREATED = 1;         // 已创建状态
static final int ACTIVITY_CREATED = 2; // Activity已创建状态
static final int STARTED = 3;         // 已启动状态
static final int RESUMED = 4;         // 已恢复状态
1
2
3
4
5

# Fragment基本操作

// 创建Fragment实例
MyFragment fragment = new MyFragment();

// 获取FragmentManager
FragmentManager fragmentManager = getSupportFragmentManager();

// 开始事务
FragmentTransaction transaction = fragmentManager.beginTransaction();

// 添加Fragment
transaction.add(R.id.container, fragment, "tag");

// 替换Fragment
transaction.replace(R.id.container, fragment);

// 移除Fragment
transaction.remove(fragment);

// 隐藏Fragment
transaction.hide(fragment);

// 显示Fragment
transaction.show(fragment);

// 提交事务
transaction.commit();
// 或者立即执行
transaction.commitNow();
// 或者允许状态丢失
transaction.commitAllowingStateLoss();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# Fragment生命周期回调

public class MyFragment extends Fragment {
    
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        // Fragment首次附加到其Context时调用
        // onCreate将在此之后调用
    }
    
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Fragment被创建时调用
        // 用于初始化Fragment
    }
    
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, 
                           @Nullable ViewGroup container, 
                           @Nullable Bundle savedInstanceState) {
        // 创建Fragment的视图层次结构
        return inflater.inflate(R.layout.fragment_my, container, false);
    }
    
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // 在onCreateView之后调用
        // 用于初始化视图组件
    }
    
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // Activity的onCreate方法完成后调用
        // 可以安全地访问Activity的视图层次结构
    }
    
    @Override
    public void onStart() {
        super.onStart();
        // Fragment变为可见时调用
    }
    
    @Override
    public void onResume() {
        super.onResume();
        // Fragment变为可交互时调用
    }
    
    @Override
    public void onPause() {
        super.onPause();
        // Fragment不再可交互时调用
    }
    
    @Override
    public void onStop() {
        super.onStop();
        // Fragment不再可见时调用
    }
    
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        // Fragment的视图层次结构被销毁时调用
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        // Fragment被销毁时调用
    }
    
    @Override
    public void onDetach() {
        super.onDetach();
        // Fragment从其Context分离时调用
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

# 生命周期管理

# 状态向上转移过程

考虑如下代码,观察生命周期的走向

fragmentManager.beginTransaction()
  // BackStackRecord
  .add(container.getId(), fragment, tag)
  .commitNowAllowingStateLoss();
1
2
3
4

# 状态转移详解

  1. 0 -> 1: 为mHost赋值

    • onAttach: Fragment首次附加到Context
    • onCreate: Fragment被创建
  2. 1 -> 2: 创建视图

    • onCreateView: 创建Fragment的视图层次结构
    • onViewCreated: 视图创建完成后的初始化
    • onActivityCreated: Activity创建完成
    • restoreViewState: 如果可能,恢复视图状态
  3. 2 -> 3: 启动Fragment

    • onStart: Fragment变为可见
  4. 3 -> 4: 恢复Fragment

    • onResume: Fragment变为可交互

# onAttach详细分析

public void onAttach(@NonNull Context context): Called when a fragment is first attached to its context. onCreate will be called after this.

// FragmentManagerImpl#moveToState 的一段代码
if (newState > 0) {
  // ...
  if (f.mSavedFragmentState != null) {
    // ...
  }
  // fragment的 mHost的赋值地方
  f.mHost = this.mHost;
  f.mParentFragment = this.mParent;
  f.mFragmentManager = this.mParent != null ? this.mParent.mChildFragmentManager : this.mHost.getFragmentManagerImpl();
  if (f.mTarget != null) {
      if (this.mActive.get(f.mTarget.mIndex) != f.mTarget) {
          throw new IllegalStateException("Fragment " + f + " declared target fragment " + f.mTarget + " that does not belong to this FragmentManager!");
      }

      if (f.mTarget.mState < 1) {
          this.moveToState(f.mTarget, 1, 0, 0, true);
      }
  }

  this.dispatchOnFragmentPreAttached(f, this.mHost.getContext(), false);
  f.mCalled = false;
  // onAttach 先调用
  f.onAttach(this.mHost.getContext());
  if (!f.mCalled) {
      throw new SuperNotCalledException("Fragment " + f + " did not call through to super.onAttach()");
  }

  if (f.mParentFragment == null) {
      this.mHost.onAttachFragment(f);
  } else {
      f.mParentFragment.onAttachFragment(f);
  }

  this.dispatchOnFragmentAttached(f, this.mHost.getContext(), false);
  if (!f.mIsCreated) {
      this.dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
      // 回调onCreate
      f.performCreate(f.mSavedFragmentState);
      this.dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
  } else {
      f.restoreChildFragmentState(f.mSavedFragmentState);
      f.mState = 1;
  }
  f.mRetaining = false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

# isAdded返回值

  • return false
    • onAttach
    • onCreate
  • return true
    • onCreateView
    • onViewCreated
    • onActivityCreated
    • onStart
    • onResume

# Fragment管理器

# getFragmentManager vs getChildFragmentManager

# 1. getFragmentManager()

定义

  • 方法:Fragment.getFragmentManager()
  • 返回:宿主Activity的FragmentManager

用途

  • 用于在Fragment中访问宿主Activity的FragmentManager
  • 通常用于管理直接附加到Activity的顶层Fragment

场景

  • 在Activity中添加、替换、删除Fragment
  • 在一个Fragment中操作同级的其他顶层Fragment
示例
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.container, new ExampleFragment());
transaction.commit();
1
2
3
4

# 2. getChildFragmentManager()

定义

  • 方法:Fragment.getChildFragmentManager()
  • 返回:当前Fragment的内部FragmentManager

用途

  • 用于在Fragment中嵌套子Fragment
  • 适合在Fragment内部管理其子Fragment的生命周期和操作

场景

  • 当需要嵌套Fragment时(Fragment内的Fragment)
  • 子Fragment的生命周期会跟随父Fragment,而不是宿主Activity
示例
FragmentManager childFragmentManager = getChildFragmentManager();
FragmentTransaction transaction = childFragmentManager.beginTransaction();
transaction.add(R.id.child_container, new ChildFragment());
transaction.commit();
1
2
3
4

# Fragment事务管理

// 基本事务操作
FragmentTransaction transaction = fragmentManager.beginTransaction();

// 添加Fragment到回退栈
transaction.addToBackStack("fragment_tag");

// 设置过渡动画
transaction.setCustomAnimations(
    R.anim.slide_in_right,
    R.anim.slide_out_left,
    R.anim.slide_in_left,
    R.anim.slide_out_right
);

// 设置事务优先级
transaction.setReorderingAllowed(true);

// 提交事务的不同方式
transaction.commit();                    // 异步提交
transaction.commitNow();                 // 同步提交
transaction.commitAllowingStateLoss();   // 允许状态丢失的提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 数据传递与通信

# Fragment间数据传递

# 1. 使用Bundle传递数据

// 创建Fragment并传递参数
MyFragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putString("key", "value");
args.putInt("number", 123);
fragment.setArguments(args);

// 在Fragment中接收参数
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        String value = getArguments().getString("key");
        int number = getArguments().getInt("number");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 2. 使用ViewModel共享数据

// 创建共享ViewModel
public class SharedViewModel extends ViewModel {
    private final MutableLiveData<String> selected = new MutableLiveData<>();
    
    public void select(String item) {
        selected.setValue(item);
    }
    
    public LiveData<String> getSelected() {
        return selected;
    }
}

// 在Fragment中使用
SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
model.getSelected().observe(getViewLifecycleOwner(), item -> {
    // 处理选中的项目
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 3. Fragment结果API

// 设置结果监听器
setFragmentResultListener("requestKey", this, (requestKey, bundle) -> {
    String result = bundle.getString("bundleKey");
    // 处理结果
});

// 发送结果
Bundle result = new Bundle();
result.putString("bundleKey", "result");
setFragmentResult("requestKey", result);
1
2
3
4
5
6
7
8
9
10

# Fragment与Activity通信

# 1. 接口回调

// 定义接口
public interface OnFragmentInteractionListener {
    void onFragmentInteraction(String data);
}

// 在Fragment中
public class MyFragment extends Fragment {
    private OnFragmentInteractionListener mListener;
    
    @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");
        }
    }
    
    private void sendDataToActivity(String data) {
        if (mListener != null) {
            mListener.onFragmentInteraction(data);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 2. 使用Activity的ViewModel

// 在Activity中
public class MainActivity extends AppCompatActivity {
    private MainViewModel viewModel;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        viewModel = new ViewModelProvider(this).get(MainViewModel.class);
    }
}

// 在Fragment中
MainViewModel viewModel = new ViewModelProvider(requireActivity()).get(MainViewModel.class);
viewModel.getData().observe(getViewLifecycleOwner(), data -> {
    // 处理数据
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 高级特性

# Fragment工厂模式

// 使用Fragment工厂创建Fragment
public class MyFragmentFactory extends FragmentFactory {
    @Override
    public Fragment instantiate(@NonNull ClassLoader classLoader, @NonNull String className) {
        if (className.equals(MyFragment.class.getName())) {
            return new MyFragment();
        }
        return super.instantiate(classLoader, className);
    }
}

// 在Activity中设置
getSupportFragmentManager().setFragmentFactory(new MyFragmentFactory());
1
2
3
4
5
6
7
8
9
10
11
12
13

# Fragment状态保存与恢复

public class MyFragment extends Fragment {
    private String savedData;
    
    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("saved_data", savedData);
    }
    
    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
        if (savedInstanceState != null) {
            savedData = savedInstanceState.getString("saved_data");
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# Fragment懒加载

public abstract class LazyFragment extends Fragment {
    private boolean isViewCreated = false;
    private boolean isDataLoaded = false;
    
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        isViewCreated = true;
        loadDataIfNeeded();
    }
    
    @Override
    public void onResume() {
        super.onResume();
        loadDataIfNeeded();
    }
    
    private void loadDataIfNeeded() {
        if (isViewCreated && getUserVisibleHint() && !isDataLoaded) {
            loadData();
            isDataLoaded = true;
        }
    }
    
    protected abstract void loadData();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 常见问题与解决方案

# 1. Fragment has not been attached yet

错误信息

java.lang.IllegalStateException: Fragment has not been attached yet.
android.support.v4.app.Fragment.instantiateChildFragmentManager(Fragment.java:2383)
android.support.v4.app.Fragment.getChildFragmentManager(Fragment.java:845)
1
2
3

原因分析

  • 过早调用getChildFragmentManager()方法
  • Fragment的mHost字段为null
  • Fragment尚未完成附加过程

解决方案

// 检查Fragment是否已附加
if (isAdded()) {
    FragmentManager childFragmentManager = getChildFragmentManager();
    // 执行Fragment操作
}

// 或者在onAttach之后调用
@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    // 现在可以安全地使用getChildFragmentManager()
}
1
2
3
4
5
6
7
8
9
10
11
12

# 2. Fragment状态丢失

问题描述

  • Fragment在配置更改时丢失状态
  • 数据未正确保存和恢复

解决方案

// 使用ViewModel保存数据
public class MyViewModel extends ViewModel {
    private final MutableLiveData<String> data = new MutableLiveData<>();
    
    public LiveData<String> getData() {
        return data;
    }
    
    public void setData(String value) {
        data.setValue(value);
    }
}

// 在Fragment中使用
private MyViewModel viewModel;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    viewModel = new ViewModelProvider(this).get(MyViewModel.class);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 3. Fragment重叠问题

问题描述

  • 多个Fragment同时显示
  • Fragment视图重叠

解决方案

// 使用replace而不是add
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.container, fragment);
transaction.addToBackStack(null);
transaction.commit();

// 或者在添加前检查是否已存在
if (fragmentManager.findFragmentByTag("tag") == null) {
    transaction.add(R.id.container, fragment, "tag");
    transaction.commit();
}
1
2
3
4
5
6
7
8
9
10
11

# 4. Fragment生命周期混乱

问题描述

  • Fragment生命周期回调顺序异常
  • 在错误的生命周期阶段执行操作

解决方案

// 使用getViewLifecycleOwner()观察LiveData
viewModel.getData().observe(getViewLifecycleOwner(), data -> {
    // 处理数据更新
});

// 检查Fragment状态
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    if (getView() != null) {
        // 安全地操作视图
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 5. Fragment事务提交失败

问题描述

  • commit()调用后Fragment未显示
  • 事务被延迟执行

解决方案

// 使用commitNow()立即执行
transaction.commitNow();

// 或者检查Activity状态
if (!isStateSaved()) {
    transaction.commit();
} else {
    transaction.commitAllowingStateLoss();
}

// 在onCreate中延迟提交
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            getViewTreeObserver().removeOnGlobalLayoutListener(this);
            // 执行Fragment操作
        }
    });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 6. Fragment内存泄漏

问题描述

  • Fragment持有Activity或Context引用
  • 异步操作未正确取消

解决方案

// 使用弱引用
private WeakReference<Context> contextRef;

@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    contextRef = new WeakReference<>(context);
}

// 取消异步操作
@Override
public void onDestroy() {
    super.onDestroy();
    // 取消所有异步操作
    if (asyncTask != null) {
        asyncTask.cancel(true);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 最佳实践

# 1. Fragment设计原则

  • 单一职责: 每个Fragment只负责一个功能
  • 可重用性: 设计Fragment时考虑复用性
  • 状态管理: 使用ViewModel管理Fragment状态
  • 生命周期感知: 正确处理生命周期回调

# 2. 性能优化

// 使用Fragment工厂
public class MyFragmentFactory extends FragmentFactory {
    @Override
    public Fragment instantiate(@NonNull ClassLoader classLoader, @NonNull String className) {
        // 自定义Fragment创建逻辑
        return super.instantiate(classLoader, className);
    }
}

// 延迟加载
public class LazyFragment extends Fragment {
    private boolean isDataLoaded = false;
    
    @Override
    public void onResume() {
        super.onResume();
        if (!isDataLoaded && getUserVisibleHint()) {
            loadData();
            isDataLoaded = true;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 3. 错误处理

// 统一的错误处理
public abstract class BaseFragment extends Fragment {
    
    protected void handleError(Throwable throwable) {
        // 统一的错误处理逻辑
        Log.e("BaseFragment", "Error occurred", throwable);
        showErrorDialog(throwable.getMessage());
    }
    
    protected void showErrorDialog(String message) {
        new AlertDialog.Builder(requireContext())
            .setTitle("错误")
            .setMessage(message)
            .setPositiveButton("确定", null)
            .show();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 4. 测试策略

// Fragment单元测试
@RunWith(AndroidJUnit4.class)
public class MyFragmentTest {
    
    @Test
    public void testFragmentCreation() {
        MyFragment fragment = new MyFragment();
        assertNotNull(fragment);
    }
    
    @Test
    public void testFragmentLifecycle() {
        // 测试Fragment生命周期
        FragmentScenario<MyFragment> scenario = FragmentScenario.launch(MyFragment.class);
        scenario.onFragment(fragment -> {
            // 验证Fragment状态
            assertTrue(fragment.isAdded());
        });
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 实际应用案例

# 1. 主从Fragment模式

// 主Fragment
public class MasterFragment extends Fragment {
    private OnItemSelectedListener listener;
    
    public interface OnItemSelectedListener {
        void onItemSelected(String item);
    }
    
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        if (context instanceof OnItemSelectedListener) {
            listener = (OnItemSelectedListener) context;
        }
    }
    
    private void onItemClick(String item) {
        if (listener != null) {
            listener.onItemSelected(item);
        }
    }
}

// 从Fragment
public class DetailFragment extends Fragment {
    public static DetailFragment newInstance(String item) {
        DetailFragment fragment = new DetailFragment();
        Bundle args = new Bundle();
        args.putString("item", item);
        fragment.setArguments(args);
        return fragment;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 2. 标签页Fragment

// 使用ViewPager2和TabLayout
public class TabFragment extends Fragment {
    private ViewPager2 viewPager;
    private TabLayout tabLayout;
    
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_tab, container, false);
        
        viewPager = view.findViewById(R.id.viewPager);
        tabLayout = view.findViewById(R.id.tabLayout);
        
        setupViewPager();
        setupTabLayout();
        
        return view;
    }
    
    private void setupViewPager() {
        FragmentAdapter adapter = new FragmentAdapter(this);
        viewPager.setAdapter(adapter);
    }
    
    private void setupTabLayout() {
        TabLayoutMediator mediator = new TabLayoutMediator(tabLayout, viewPager,
            (tab, position) -> tab.setText("Tab " + (position + 1)));
        mediator.attach();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 3. 对话框Fragment

// 自定义对话框Fragment
public class CustomDialogFragment extends DialogFragment {
    
    public static CustomDialogFragment newInstance(String title) {
        CustomDialogFragment fragment = new CustomDialogFragment();
        Bundle args = new Bundle();
        args.putString("title", title);
        fragment.setArguments(args);
        return fragment;
    }
    
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        String title = getArguments().getString("title");
        
        return new AlertDialog.Builder(requireContext())
            .setTitle(title)
            .setMessage("这是一个自定义对话框")
            .setPositiveButton("确定", (dialog, which) -> {
                // 处理确定按钮点击
            })
            .setNegativeButton("取消", null)
            .create();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

分析一切的来源都是FragmentActivity持有的FragmentController对象!过早调用有可能出现此问题,需要保证mHost != null

#fragment#Android#lifecycle
上次更新: 2025/10/08, 16:24:59
ContentProvider
动态化

← ContentProvider 动态化→

最近更新
01
npx 使用指南
10-12
02
cursor
09-28
03
inspect
07-20
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式