# Fragment详解

## 目录
- [Fragment生命周期](#fragment生命周期)
- [Fragment与Activity通信](#fragment与activity通信)
- [Fragment事务](#fragment事务)
- [Fragment回退栈](#fragment回退栈)
- [Fragment懒加载](#fragment懒加载)
- [ViewPager与Fragment](#viewpager与fragment)
- [Fragment最佳实践](#fragment最佳实践)
- [面试常见问题](#面试常见问题)

---

## Fragment生命周期

### 生命周期方法

```java
public class MyFragment extends Fragment {
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        // Fragment 附加到 Activity
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Fragment 创建
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // 创建视图
        return inflater.inflate(R.layout.fragment_my, container, false);
    }
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // 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();
        // 销毁视图
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        // Fragment 销毁
    }
    
    @Override
    public void onDetach() {
        super.onDetach();
        // Fragment 从 Activity 分离
    }
}
```

### 生命周期流程图

```
附加到 Activity:
onAttach() → onCreate() → onCreateView() → onActivityCreated()
→ onStart() → onResume()

切换到后台:
onPause() → onStop()

返回前台:
onStart() → onResume()

从 Activity 分离:
onPause() → onStop() → onDestroyView() → onDestroy() → onDetach()
```

---

## Fragment与Activity通信

### 方式1：接口回调

```java
// Fragment 定义接口
public class MyFragment extends Fragment {
    public interface OnFragmentInteractionListener {
        void onFragmentAction(String data);
    }
    
    private OnFragmentInteractionListener listener;
    
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            listener = (OnFragmentInteractionListener) context;
        }
    }
    
    private void sendDataToActivity() {
        if (listener != null) {
            listener.onFragmentAction("Data from Fragment");
        }
    }
}

// Activity 实现接口
public class MainActivity extends AppCompatActivity 
        implements MyFragment.OnFragmentInteractionListener {
    
    @Override
    public void onFragmentAction(String data) {
        // 处理数据
    }
}
```

### 方式2：ViewModel 共享

```java
// ViewModel
public class SharedViewModel extends ViewModel {
    private MutableLiveData<String> data = new MutableLiveData<>();
    
    public LiveData<String> getData() {
        return data;
    }
    
    public void setData(String value) {
        data.setValue(value);
    }
}

// Fragment A
SharedViewModel viewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
viewModel.setData("Data from Fragment A");

// Fragment B
SharedViewModel viewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
viewModel.getData().observe(this, data -> {
    // 接收数据
});
```

### 方式3：Activity 方法调用

```java
// Activity 提供方法
public class MainActivity extends AppCompatActivity {
    public void updateData(String data) {
        // 更新数据
    }
}

// Fragment 调用
((MainActivity) getActivity()).updateData("Data");
```

---

## Fragment事务

### Fragment 操作

```java
// 添加 Fragment
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.container, new MyFragment(), "tag");
transaction.commit();

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

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

// 显示/隐藏 Fragment
transaction.show(fragment);
transaction.hide(fragment);

// 添加动画
transaction.setCustomAnimations(
    R.anim.enter, R.anim.exit,
    R.anim.pop_enter, R.anim.pop_exit
);
```

### 事务提交

```java
// commit()：异步提交
transaction.commit();

// commitNow()：同步提交（立即执行）
transaction.commitNow();

// commitAllowingStateLoss()：允许状态丢失时提交
transaction.commitAllowingStateLoss();
```

---

## Fragment回退栈

### 回退栈使用

```java
// 添加到回退栈
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container, new FragmentB());
transaction.addToBackStack("fragmentB");
transaction.commit();

// 按 Back 键会返回到上一个 Fragment
```

### 回退栈管理

```java
// 检查是否有回退栈
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
    getSupportFragmentManager().popBackStack();
}

// 返回到指定 Fragment
getSupportFragmentManager().popBackStack("fragmentA", 0);

// 清空回退栈
getSupportFragmentManager().popBackStack(null, 
    FragmentManager.POP_BACK_STACK_INCLUSIVE);
```

---

## Fragment懒加载

### 懒加载实现

```java
public class LazyFragment extends Fragment {
    private boolean isViewCreated = false;
    private boolean isDataLoaded = false;
    
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser && isViewCreated && !isDataLoaded) {
            loadData();
            isDataLoaded = true;
        }
    }
    
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        isViewCreated = true;
        if (getUserVisibleHint() && !isDataLoaded) {
            loadData();
            isDataLoaded = true;
        }
    }
    
    private void loadData() {
        // 加载数据
    }
}
```

### ViewPager2 懒加载

```java
// ViewPager2 使用 FragmentStateAdapter
// 自动处理懒加载
public class MyAdapter extends FragmentStateAdapter {
    public MyAdapter(FragmentActivity activity) {
        super(activity);
    }
    
    @Override
    public Fragment createFragment(int position) {
        return MyFragment.newInstance(position);
    }
    
    @Override
    public int getItemCount() {
        return 3;
    }
}
```

---

## ViewPager与Fragment

### ViewPager 使用

```java
// FragmentPagerAdapter：适合少量 Fragment
public class MyPagerAdapter extends FragmentPagerAdapter {
    private List<Fragment> fragments;
    
    public MyPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }
    
    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }
    
    @Override
    public int getCount() {
        return fragments.size();
    }
}

// FragmentStatePagerAdapter：适合大量 Fragment
public class MyStateAdapter extends FragmentStatePagerAdapter {
    // 实现类似
}
```

### ViewPager2 使用

```java
// ViewPager2 推荐使用
ViewPager2 viewPager = findViewById(R.id.viewPager);
MyAdapter adapter = new MyAdapter(this);
viewPager.setAdapter(adapter);

// TabLayout 关联
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
    tabLayout, viewPager, (tab, position) -> {
        tab.setText("Tab " + position);
    });
tabLayoutMediator.attach();
```

---

## Fragment最佳实践

### 1. 使用 newInstance

```java
public class MyFragment extends Fragment {
    public static MyFragment newInstance(String param) {
        MyFragment fragment = new MyFragment();
        Bundle args = new Bundle();
        args.putString("param", param);
        fragment.setArguments(args);
        return fragment;
    }
}
```

### 2. 避免内存泄漏

```java
@Override
public void onDestroyView() {
    super.onDestroyView();
    // 释放 View 相关资源
    if (handler != null) {
        handler.removeCallbacksAndMessages(null);
    }
}
```

### 3. 使用 ViewModel

```java
// 使用 ViewModel 保存数据
// 避免在 onSaveInstanceState 中保存大量数据
```

---

## 面试常见问题

### Q1: Fragment 生命周期？

**答案：**
onAttach → onCreate → onCreateView → onActivityCreated
→ onStart → onResume → onPause → onStop
→ onDestroyView → onDestroy → onDetach

### Q2: Fragment 和 Activity 的区别？

**答案：**
- **Activity**：独立的界面，可以单独存在
- **Fragment**：必须依附于 Activity，是 Activity 的一部分

### Q3: Fragment 事务？

**答案：**
- 使用 FragmentTransaction 进行 Fragment 操作
- 可以添加、替换、移除 Fragment
- 可以添加到回退栈

### Q4: Fragment 懒加载？

**答案：**
- 只在 Fragment 可见时加载数据
- 使用 setUserVisibleHint 或 onViewCreated
- 提升性能，减少不必要的加载

---

*最后更新：2024年*
