课堂笔记
- HomePresenterImpl 中,把从网络获取的 categories 数据给 View 层的接口(应该是这个意思)
    @Override
    public void getCategories() {
        Retrofit retrofit = RetrofitManager.getInstance().getRetrofit();
        Api api = retrofit.create(Api.class);
        Call<Categories> task = api.getCategories();
        task.enqueue(new Callback<Categories>() {
            @Override
            public void onResponse(Call<Categories> call, Response<Categories> response) {
                int code = response.code();
                if (code == HttpURLConnection.HTTP_OK) {
                    //请求成功
                    Categories categories = response.body();
                    if (mCallback != null) {
                        mCallback.onCategoryLoaded(categories);
                    }
                } else {
                    //请求失败
                }
            }
            @Override
            public void onFailure(Call<Categories> call, Throwable t) {
                //请求失败
            }
        });
    }
    @Override
    public void registerCallback(IHomeCallback callback) {
        mCallback = callback;
    }
    @Override
    public void unregisterCallback(IHomeCallback callback) {
        mCallback = null;
    }
- HomeFragment 中,在 HomePresenterImpl 注册接口和 getCategories() 后,View 层就有数据了
    @Override
    protected void initPresenter() {
        mHomePresenter = new HomePresenterImpl();
        mHomePresenter.registerCallback(this);
    }
    @Override
    protected void loadData() {
        mHomePresenter.getCategories();
    }
    @Override
    public void onCategoryLoaded(Categories categories) {
        //TODO: categories 有数据
    }
- BaseFragment 中,用 ButterKnife 绑定 rootView ,再增加 protected 类型的 initView() 方法
    private Unbinder mBind;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = loadRootView(inflater, container);
        mBind = ButterKnife.bind(this, rootView);
        initView();
        initPresenter();
        loadData();
        return rootView;
    }
    protected void initView() {
    }
- onDestroyView() 时 ButterKnife 解除绑定
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (mBind != null) {
            mBind.unbind();
        }
        release();
    }
- 同理,在之前 MainActivity 中的 ButterKnife 也要解除绑定
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mBind != null) {
            mBind.unbind();
        }
    }
- 这样,在 HomeFragment 中,就可以用 ButterKnife 找到 TabLayout 和 ViewPager 了
    @BindView(R.id.home_indicator)
    public TabLayout mTabLayout;
    @BindView(R.id.home_pager)
    public ViewPager homePager;
- 给 TabLayout 设置 ViewPager (肌肉记忆?) ,并且给 ViewPager 设置适配器 HomePagerAdapter
    @Override
    protected void initView() {
        mTabLayout.setupWithViewPager(homePager);
        mHomePagerAdapter = new HomePagerAdapter(getChildFragmentManager());
        homePager.setAdapter(mHomePagerAdapter);
    }
public class HomePagerAdapter extends FragmentPagerAdapter {
    public HomePagerAdapter(@NonNull FragmentManager fm) {
        super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
    }
    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return null;
    }
    @NonNull
    @Override
    public Fragment getItem(int position) {
        return null;
    }
    @Override
    public int getCount() {
        return 0;
    }
}
- 在 HomePagerAdapter 写个方法,用来获取 HomeFragment 中已获取的分类数据
    public void setCategoriesData(Categories categories) {
    }
- 在 HomeFragment 调用 setCategoriesData (老师喜欢反着顺序写,我也觉得反着写更顺手)
    @Override
    public void onCategoryLoaded(Categories categories) {
        mHomePagerAdapter.setCategoriesData(categories);
    }
public class HomePagerAdapter extends FragmentPagerAdapter {
    private List<Categories.DataBean> categoriesList = new ArrayList<>();
    public HomePagerAdapter(@NonNull FragmentManager fm) {
        super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
    }
    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return categoriesList.get(position).getTitle();
    }
    @NonNull
    @Override
    public Fragment getItem(int position) {
        HomePagerFragment homePagerFragment = new HomePagerFragment();
        return homePagerFragment;
    }
    @Override
    public int getCount() {
        return categoriesList.size();
    }
    public void setCategoriesData(Categories categories) {
        categoriesList.clear();
        List<Categories.DataBean> data = categories.getData();
        categoriesList.addAll(data);
        notifyDataSetChanged();
    }
}
- HomePagerAdapter 中需要 HomePagerFragment,另需创建 HomePagerFragment 及其布局资源
- 完整的 HomeFragment 代码
public class HomeFragment extends BaseFragment implements IHomeCallback {
    @BindView(R.id.home_indicator)
    public TabLayout mTabLayout;
    @BindView(R.id.home_pager)
    public ViewPager homePager;
    private IHomePresenter mHomePresenter;
    private HomePagerAdapter mHomePagerAdapter;
    @Override
    protected int getRootViewResId() {
        return R.layout.fragment_home;
    }
    @Override
    protected void initPresenter() {
        mHomePresenter = new HomePresenterImpl();
        mHomePresenter.registerCallback(this);
    }
    @Override
    protected void loadData() {
        mHomePresenter.getCategories();
    }
    @Override
    public void onCategoryLoaded(Categories categories) {
        mHomePagerAdapter.setCategoriesData(categories);
    }
    @Override
    protected void initView() {
        mTabLayout.setupWithViewPager(homePager);
        mHomePagerAdapter = new HomePagerAdapter(getChildFragmentManager());
        homePager.setAdapter(mHomePagerAdapter);
    }
    @Override
    protected void release() {
        if (mHomePresenter != null) {
            mHomePresenter.unregisterCallback(this);
        }
    }
}
学习感悟
- HomePagerAdapter 中 setCategoriesData 得到的数据是否需要验证为空?(后面的视频老师都检验了)
    public void setCategoriesData(Categories categories) {
	List<Categories.DataBean> data = categories.getData();
        if (data != null) {
            categoriesList.clear();
            categoriesList.addAll(data);
            notifyDataSetChanged();
        }    
    }
- P 层 取消注册接口 时,是不是不用传接口?用不到吧...
    @Override
    public void registerCallback(IHomeCallback callback) {
        mCallback = callback;
    }
    @Override
    public void unregisterCallback(IHomeCallback callback) {
	//没用到 参数
        mCallback = null;
    }
- Android 初学者一名,请老师和各位同学讨论指正