MVP模式
Presender 作为 View 与逻辑逻辑的桥梁
Android 模式中 Activity 实际上就是这个角色
ViewDelegate :view的代理。调用实例的view :xml,Linearlayout,自定view
如何使Activity 和 Fragment 成为优秀的 Presender
我定义了一下基类
Presender 基类,fragment与activity使用方法。
e.g
public abstract class BaseViewDelegateFragment<T extends BaseViewDelegate> extends Fragment {
protected T mViewDelegate;
public T getmViewDelegate() {
return mViewDelegate;
}
@Override
public final void onCreate(Bundle savedInstanceState) {
//因为没有使用框架,在此处初始化View.使用泛型,调用View的方法,给view赋予生命周期
createViewDelegate();
//给view设置逻辑调用
mViewDelegate.setFragment(this);
super.onCreate(savedInstanceState);
}
/**
* 创建viewdelegate,并绑定到fragment
*/
protected abstract void createViewDelegate();
@Override
public View onCreateView(LayoutInflater inflater
, ViewGroup container, Bundle savedInstanceState) {
//创建view并,给view赋值
mViewDelegate.create(inflater, null, savedInstanceState);
return mViewDelegate.create(inflater, null, savedInstanceState);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(view, savedInstanceState);
mViewDelegate.initWidget();//初始化组件
mViewDelegate.initListener();//初始化组件监听
}
/*****************
*presender 给view赋值生命周期
*其实很少会用到。
*一般都是presender 生命周期调用 view的方法
**********************/
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
mViewDelegate.onPause();
}
public void popBack() {
mViewDelegate.hideSoftInputMethod();
FragmentUtil.popBackImmediate(getActivity());
}
}
通用的View基类,适用与用户交互时候用
public abstract class BaseViewDelegate <P extends BaseViewDelegateFragment> implements IViewDelegate {
/*************** INPUT METHOD **************************/
InputMethodManager imm;
/***************** 组件view ********************************************/
protected final SparseArray<View> mViews = new SparseArray<View>();//保存view的容器类
protected View rootView;//最外层的view
public abstract int getRootLayoutId();
/********** PRESENDER *************/
protected P mFragment;
public void setFragment(P mFragment) {
this.mFragment = mFragment;
}
@Override
public void create(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
int rootLayoutId = getRootLayoutId();
rootView = inflater.inflate(rootLayoutId, container, false);
}
@Override
public int getOptionsMenuId() {
return 0;
}
//一些presender生命周期,不建议使用,但是用暂停handler很有效,
//建议直接在presender生命周期,调用一些view的功能
public void onCreate() {
}
public void onResume() {
}
@Override
public View getRootView() {
return rootView;
}
public void setRootView(View rootView) {
this.rootView = rootView;
}
@Override
public void initWidget() {
//查找控件
}
@Override
public void initListener() {
//给控件设置监听
}
//查找控件
public <T extends View> T findView(int id) {
T view = (T) mViews.get(id);
if (view == null) {
view = (T) rootView.findViewById(id);
mViews.put(id, view);
}
return view;
}
public <T extends View> T findView(String tag) {
return this.rootView != null ? (T) this.rootView.findViewWithTag(tag) : null;
}
使用的demo
fragment
public class SearchIndex extends BaseViewDelegateFragment<SearchIndexViewDelegate> {
// 逻辑类
protected Biz mBiz;//逻辑可以多个,presender里面初始化
protected ShopBiz mShopBiz;//放一些对view数据的操作
//主要是让view与数据交互.校验数据
protected ShopDao mDao;
public SearchIndex() {
}
/***获取逻辑****/
public SupplierStoreItemViewDecorate getStoreBiz() {
return mShopbiz;
}
@Override
protected void createViewDelegate() {
// TODO Auto-generated method stub
mViewDelegate = new SearchIndexViewDelegate();//初始化view
mStoreBiz = new ShopBiz();//初始化View逻辑
mDao = new ShopDao;//数据库操作
}
@Override
public void initData(Bundle savedInstanceState, View... view) {
// TODO Auto-generated method stub
super.initData(savedInstanceState, view);
initHotSearchData();
//请求网络操作,属于逻辑,由于网络通常需要异步回调,回调建议直接纺织到presender里面
}
/** 初始化热门搜索 */
public void initHotSearchData() {
//网络请求回调
JsonUtil.request(this, URLS.supplyHotProductList, "", new HttpModelJsonCallBack() {
@Override
public void onSuccess(HttpModel model) {
// view 刷新
mViewDelegate.reflashHotSearchView(model.genPageList(SupplierCommodityModel.class));
}
});
}
/** 添加历史 */
public void addHistotry(SupplierCommodityModel model) {
mDao.addHistory(model);
}
/***
* 清空历史记录
**/
public void clearHistory() {
mDao.clearHistory(new OnBackUpdateData() {
@Override
public void updata(Object... obj) {
// TODO Auto-generated method stub
mViewDelegate.reflashClearHistoryView();
}
});
}
/** 跳转到商品详情 */
public void toCommodity(SupplierCommodityModel item) {
// TODO Auto-generated method stu
mViewDelegate.hideSoftInputMethod();
FragmentUtil.switchFragment(getActivity(), this, new SearchCommodityResult(item, mtype));
}
}
view 部分
public class SearchIndexViewDelegate extends BaseViewDelegate<SearchIndex> implements OnClickListener {
/********** DECLARES *************/
protected LinearLayout sl_hot_search_parent_ll; // 热门搜索父view
protected android.support.v7.widget.RecyclerView sl_hot_search_rv; // 热搜view
protected TextView sl_hint_text_tv; // 历史数据标题
protected ListView sl_content_lv; // 历史数据显示
protected EditText sil_search_text_et; // titlebar搜索栏
protected TextView sil_right_tv; // titlebar右边按钮
protected TextView sil_search_selector_tv; // 搜索项选择
/********** ADAPTER *************/
protected BaseAdapter<SupplierCommodityModel> mSearchCommodityAdapter;
protected BaseAdapter<SupplyStoreInfo> mSearchShopAdapter;
protected BaseAdapter<SupplierCommodityModel> mHistoryAdapter;
protected BaseRecycleViewAdapter<SupplierCommodityModel> mHotSearchAdapter;
protected BaseAdapter<DropDownSelectModel> mSearchTypeAdapter;
/*************** POPWIN **********************/
protected PopupWindow mSearchTypePopWin; // 搜索项选择Popwin
@Override
public int getRootLayoutId() {
// TODO Auto-generated method stub
return R.layout.search_indext_layout;
}
@Override
public void initWidget() {
// TODO Auto-generated method stub
super.initWidget();
sl_hot_search_parent_ll = findView(R.id.sl_hot_search_parent_ll);
sl_hot_search_rv = findView(R.id.sl_hot_search_rv);
sl_hint_text_tv = findView(R.id.sl_hint_text_tv);
sl_content_lv = findView(R.id.sl_content_lv);
sil_search_text_et = findView(R.id.sil_search_text_et);
sil_right_tv = findView(R.id.sil_right_tv);
sil_search_selector_tv = findView(R.id.sil_search_selector_tv);
// 初始化页面适配
initAdapter();
}
protected void initAdapter() {
initSearchTypeAdapter(); // 搜索项适配器
initSearchCommodityAdapter(); // 搜索商品适配器
initSearchShopAdapter(); // 搜索商品适配器
initHotSearchAdapter(); // 热搜适配器
initHistoryAdapter();// 历史适配器
}
/*************** 搜索索引初始化 **************************/
protected void initSearchTypeAdapter() {
mSearchTypeAdapter = new BaseAdapter<DropDownSelectModel>(getActivity(), mFragment.getSearchTypeData(),
R.layout.drop_down_black_popwin_item) {
@Override
public void showViewData(View convertView, DropDownSelectModel item, int position) {
// TODO Auto-generated method stub
super.showViewData(convertView, item, position);
ViewHolder.setImage(convertView, R.id.icon_iv,
item.drawableId == 0 ? R.drawable.vegetable_dropdown_select : item.drawableId);
ViewHolder.setText(convertView, R.id.name_tv, item.name);
}
};
DropDownSelectModel model = mSearchTypeAdapter.getItem(0);
sil_search_selector_tv.setText(model.name);
mFragment.setSearchTypeModel(model);
}
/********* 初始化搜索商品 *************/
protected void initSearchCommodityAdapter() {
mSearchCommodityAdapter = new BaseAdapter<SupplierCommodityModel>(getActivity(), null,
R.layout.search_history_list_item) {
@Override
public void showViewData(View convertView, SupplierCommodityModel item, int pos) {
// TODO Auto-generated method stub
TextView textView = ViewHolder.setText(convertView, R.id.shli_history_tv, item.name);
textView.setCompoundDrawables(null, null, null, null);
}
};
}
/*********** 初始化搜索店铺 **************/
protected void initSearchShopAdapter() {
// TODO Auto-generated method stub
mSearchShopAdapter = new BaseAdapter<SupplyStoreInfo>(getActivity(), null,
R.layout.search_store_reslut_list_item) {
@Override
public void showViewData(View convertView, SupplyStoreInfo item, int position) {
// TODO Auto-generated method stub
super.showViewData(convertView, item, position);
mFragment.getStoreBiz().setmModel(item);
mFragment.getStoreBiz().showState(ViewHolder.getText(convertView, R.id.ssri_state_tv));
mFragment.getStoreBiz().showHead(ViewHolder.getImg(convertView, R.id.ssri_icon_iv));
mFragment.getStoreBiz().showStoreName(ViewHolder.getText(convertView, R.id.ssri_name_tv));
}
};
}
/** 初始化历史 ***/
protected void initHistoryAdapter() {
mHistoryAdapter = new BaseAdapter<SupplierCommodityModel>(getActivity(), null,
R.layout.search_history_list_item) {
@Override
public void showViewData(View convertView, SupplierCommodityModel item, int pos) {
// TODO Auto-generated method stub
TextView textView = ViewHolder.setText(convertView, R.id.shli_history_tv, item.name);
int lastpos = mHistoryAdapter.getCount() - 1;
if (pos == lastpos) {
textView.setGravity(Gravity.CENTER);
textView.setCompoundDrawables(null, null, null, null);
} else {
textView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.time_tag, 0, 0, 0);
}
}
};
sl_content_lv.setAdapter(mHistoryAdapter);
}
/************* 初始化热搜 ***************/
protected void initHotSearchAdapter() {
mHotSearchAdapter = new BaseRecycleViewAdapter<SupplierCommodityModel>(getActivity(), null,
R.layout.search_hot_list_item) {
@Override
public void showViewData(RecycleViewHolder rvHolder, final int pos) {
super.showViewData(rvHolder, pos);
// TODO Auto-generated method stub
rvHolder.setText(R.id.shli_hot_tv, mHotSearchAdapter.getItem(pos).productName);
rvHolder.setOnItemClickListner(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mFragment.toCommodity(mHotSearchAdapter.getItem(pos));
}
});
}
};
// recycleview设置横向滚动
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
sl_hot_search_rv.setLayoutManager(mLayoutManager);
sl_hot_search_rv.setHasFixedSize(true);
sl_hot_search_rv.setAdapter(mHotSearchAdapter);
}
@Override
public void initListener() {
// TODO Auto-generated method stub
super.initListener();
TextWatcher textWatcher = new BaseTextWatch() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
super.onTextChanged(s, start, before, count);
if (s.length() == 0) { // 根据输入,自动显示历史记录
mFragment.initHistoryData();
}
}
};
OnItemClickListener onItemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ListAdapter ladapter = sl_content_lv.getAdapter();
if (ladapter == mHistoryAdapter && position == ladapter.getCount() - 1) {
// 历史记录点击
mFragment.clearHistory();
} else {
// 其他搜索记录点击
Object obj = ladapter.getItem(position);
if (ladapter == mSearchCommodityAdapter) {
// 商品记录搜索点击
mFragment.addHistotry((SupplierCommodityModel) obj);// 添加历史
mFragment.toCommodity((SupplierCommodityModel) obj);// 跳转到搜索商品结果页面
} else if (ladapter == mSearchShopAdapter) {
// 店铺记录搜索点击
mFragment.toShopResult((SupplyStoreInfo) obj);// 跳转到店铺详情
} else {// 历史记录
mFragment.toCommodity((SupplierCommodityModel) obj);// 跳转到搜索商品结果页面
}
}
}
};
OnKeyListener onKeyListener = new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_ENTER) {
// 修改回车键功能,立刻搜索
mFragment.search(sil_search_text_et.getText().toString());
// 先隐藏键盘
hideSoftInputMethod();
return true;
}
return false;
}
};
sil_right_tv.setOnClickListener(this);
sil_search_text_et.addTextChangedListener(textWatcher);
sl_content_lv.setOnItemClickListener(onItemClickListener);
sil_search_text_et.setOnKeyListener(onKeyListener);
sil_search_selector_tv.setOnClickListener(this);
// 设置搜索栏状态
initSearchState();
}
protected void initSearchState() {
// TODO Auto-generated method stub
sil_search_text_et.requestFocus();
toggleSoftInputMethod();
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.sil_right_tv:// titlebar右边按钮
mFragment.popBack();
break;
case R.id.sil_search_selector_tv:// titlebar 左边下拉框
showDropDownPopWindow(); // 显示下拉的选择框框
break;
default:
break;
}
}
/********* 初始化下拉选项 ***********************/
protected void showDropDownPopWindow() {
// TODO Auto-generated method stub
if (null == mSearchTypePopWin) {
mSearchTypePopWin = PopWindowBuilder.dropDownBlackPopWindowBuilder(getActivity(), mSearchTypeAdapter,
new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DropDownSelectModel model = mSearchTypeAdapter.getItem(position);
mFragment.setSearchTypeModel(model); // 逻辑配置
sil_search_selector_tv.setText(model.name);// 显示选中搜索项
mSearchTypePopWin.dismiss();// 隐藏dialog
}
});
}
mSearchTypePopWin.showAsDropDown(sil_search_selector_tv);
}
/***************** reflash view **********************/
/*********** 刷新商品名称结果记录 ***********************/
public void reflashSearchCommodityResultView(List<SupplierCommodityModel> list) {
sl_hot_search_parent_ll.setVisibility(View.GONE); // 隐藏热搜
sl_hint_text_tv.setText(NullUtils.isEmptyList(list) ? "没有搜索结果" : "搜索结果");
// 设置为搜索适配
sl_content_lv.setAdapter(mSearchCommodityAdapter);
mSearchCommodityAdapter.setLists(list);
mSearchCommodityAdapter.notifyDataSetChanged();
}
/*********** 刷新店铺结果记录 ***********************/
public void reflashSearchShopResultView(List<SupplyStoreInfo> list) {
sl_hot_search_parent_ll.setVisibility(View.GONE); // 隐藏热搜
sl_hint_text_tv.setText(NullUtils.isEmptyList(list) ? "没有搜索结果" : "搜索结果");
// 设置为搜索适配
sl_content_lv.setAdapter(mSearchShopAdapter);
mSearchShopAdapter.setLists(list);
mSearchShopAdapter.notifyDataSetChanged();
}
/*********** 刷新历史记录 ***********************/
public void reflashHistoryView(List<SupplierCommodityModel> list) {
sl_hot_search_parent_ll.setVisibility(View.VISIBLE); // 显示热搜
sl_hint_text_tv.setVisibility(View.VISIBLE); // 显示历史搜索标题
// 设置为历史适配
mHistoryAdapter.setLists(list); // 重设历史记录
sl_content_lv.setAdapter(mHistoryAdapter);
mHistoryAdapter.notifyDataSetChanged();
mHotSearchAdapter.notifyDataSetChanged();
}
/************ 清空历史 ****************/
public void reflashClearHistoryView() {
mHistoryAdapter.clearLists(); // 清除历史view数据
mHistoryAdapter.notifyDataSetChanged();
}
/************* 刷新热搜 *************************/
public void reflashHotSearchView(List<SupplierCommodityModel> list) {
mHotSearchAdapter.setLists(list);
mHotSearchAdapter.notifyDataSetChanged();
}
/************* 生命周期调用 *******************/
@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
if (null == mSearchTypePopWin) {
PopupWindowUtil.dismiss(mSearchTypePopWin);
}
}
}
写到此处。我想总结一些一下为何,使用mvp模式
用户操作页面经常需要根据业务不断改变。
作为程序员,又不想做重复造轮子的工作。
mvp模式,使具体业务逻辑与具体view分离。
方便了程序员优化代码。
业务逻辑,与view可以分别抽取代码。以便复用。
有些同志问,为何不一开始写一个自定义view来使用了。
时常做前端开发的程序员,或许更明白。具体业务view更多的是组合使用。
自定义view更多的是抽象抽取的组件。
多个自定义view组件=》具体业务
本文探讨了在Android中如何通过MVP模式实现Activity和Fragment的优化,介绍了一个Presenter基类和通用View基类的使用,强调了MVP模式在应对业务变化和代码复用方面的优势。通过将逻辑与视图分离,MVP模式使得程序员能够更高效地管理和维护代码。
266

被折叠的 条评论
为什么被折叠?



