void hideProgressBar();

void showMsg(String msg);

void showPictures(List<Picture> pictures);

}


  虽然 View? 中只有?PictureView 一个类,但是从这个类可以对 view 要做的事一清二楚。

  P 的实现(只贴重要的代码):

public class PicturePresenterImpl implements PicturePresenter, LoaderListener {

private PictureView mPictureView;
private PictureInteractor mInteractor;

public PicturePresenterImpl(PictureView pictureView) {
    this.mPictureView = pictureView;
    mInteractor = new PictureInteractorImpl();
}

@Override
public void onResume() {
    mPictureView.showProgressBar();
    mInteractor.loadPictures(this);
}

@Override
public void onDestroy() {
    mPictureView = null;
}

@Override
public void onItemClick(int pos) {
    mPictureView.showMsg(String.valueOf(pos));
}

@Override
public void onFinish(List<Picture> pictures) {
    mPictureView.hideProgressBar();
    mPictureView.showPictures(pictures);
}

}


?  可以看出来,P 中其实就是对 M,V 的逻辑进行了封装,统一由其来掌控。

  最后来讲讲 fragment,内部引入了 P 。主要是由于 P 无法控制生命周期,所以需要借用 fragment 的生命周期来对整个过程进行控制。

疑问?
---

  大家看了上面的demo,不觉得在 fragment 中,即夹杂着 V, 又有 P,这样其实不利于维护,尤其是后期当 view 越来越多的时候,那时候,还要把 view 的初始化等等都写在 fragment 中嘛?所以接下去要对 fragment 内容进行瘦身。那怎么瘦身呢?具体请看下文。

改造
--

  改造后的结构,只在 view 中新建了一个?BasePageView?来处理 view 的初始化和控制逻辑。

![](https://s2.51cto.com/images/20210909/1631124899524178.jpg)

其代码具体如下:

public class BasePageView extends FrameLayout implements PictureView {

private RecyclerView mRecyclerView;
private ProgressBar mProgress;

private PictureAdapter mAdapter;
private PicturePresenter mPresenter;
private Context mContext;

/**
 * 构造函数。
 */
public BasePageView(Context context){
    this(context, null);
};

public BasePageView(Context context, AttributeSet attributeSet) {
    this(context, attributeSet, 0);
}

public BasePageView(Context context, AttributeSet attributeSet, int defStyleAttr){
    super(context, attributeSet, defStyleAttr);
    init(context);
}

/**
 * 初始化
 */
public void init(Context context) {
    mContext = context;
    inflate(mContext, R.layout.base_view_layout, this);
    mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    mProgress = (ProgressBar) findViewById(R.id.progress_bar);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
}

@Override
public void showProgressBar() {
    mProgress.setVisibility(View.VISIBLE);
    mRecyclerView.setVisibility(View.INVISIBLE);
}

@Override
public void hideProgressBar() {
    mProgress.setVisibility(View.INVISIBLE);
    mRecyclerView.setVisibility(View.VISIBLE);
}

@Override
public void showMsg(String msg) {
    Toast.makeText(mContext, msg, Toast.LENGTH_LONG).show();
}

@Override
public void showPictures(List<Picture> pictures) {
    mAdapter = new PictureAdapter(pictures);
    mAdapter.setRecyclerItemClickListener(new OnRecyclerItemClickListener() {
        @Override
        public void onItemClick(int pos) {
            mPresenter.onItemClick(pos);
        }
    });
    mRecyclerView.setAdapter(mAdapter);
}

}


?这样当需要对视图进行更改的时候,只需要更改这个类就可以了,不用在跑到 fragment 中去了。

于此同时,fragment 也瘦身成功了:

public class PictureFragment extends Fragment{

private PicturePresenter mPresenter;

public static PictureFragment newInstance() {
    return new PictureFragment();
}

public PictureFragment() {
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_picture, container, false);
   BasePageView basePageView = (BasePageView) view.findViewById(R.id.baseView);
    mPresenter = new PicturePresenterImpl(basePageView);
    return view;
}

@Override
public void onResume() {

总结

其实客户端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

资料领取方式:戳这里免费领取

Android大厂面试真题全套解析

2017-2020字节跳动Android面试真题解析PDF
然而Android架构学习进阶是一条漫长而艰苦的道路,不能靠一时激情,更不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!