購物車第二個版本
1.購物車外部佈局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="9" android:id="@+id/rece_shopp" />
<RelativeLayout android:layout_width="match_parent" android:layout_height="50dp" android:layout_gravity="center_vertical" >
<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="全選/反選" android:id="@+id/check_shopp" />
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="總價:" android:textColor="#f00" android:layout_toRightOf="@id/check_shopp" android:layout_marginLeft="15dp" android:textSize="20sp" android:layout_marginTop="5dp" android:id="@+id/text_zongjiashopp" />
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="結算" android:background="#f00" android:layout_alignParentRight="true" android:id="@+id/btn_shoppjiesuan" android:textColor="#ffffff" />
</RelativeLayout>
</LinearLayout>
2.購物車主頁面
public class ShoppingFragment extends BaseFragment<ShoppingPresenter> implements ShoppingContract.View {
@BindView(R.id.rece_shopp) RecyclerView receShopp; @BindView(R.id.check_shopp) CheckBox checkShopp; @BindView(R.id.text_zongjiashopp) TextView textZongjiashopp; @BindView(R.id.btn_shoppjiesuan) Button btnShoppjiesuan; Unbinder unbinder; private NewsShopp newsShopp; private MyShoppAdapter myShoppAdapter;
public static ShoppingFragment newInstance() { ShoppingFragment fragment = new ShoppingFragment(); return fragment; }
@Override public void setupFragmentComponent(@NonNull AppComponent appComponent) { DaggerShoppingComponent //如找不到該類,請編譯一下專案 .builder() .appComponent(appComponent) .shoppingModule(new ShoppingModule(this)) .build() .inject(this); }
@Override public View initView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_shopping, container, false); }
@Override public void initData(@Nullable Bundle savedInstanceState) {
}
/** * 通過此方法可以使 Fragment 能夠與外界做一些互動和通訊, 比如說外部的 Activity 想讓自己持有的某個 Fragment 物件執行一些方法, * 建議在有多個需要與外界互動的方法時, 統一傳 {@link Message}, 通過 what 欄位來區分不同的方法, 在 {@link #setData(Object)} * 方法中就可以 {@code switch} 做不同的操作, 這樣就可以用統一的入口方法做多個不同的操作, 可以起到分發的作用 * <p> * 呼叫此方法時請注意呼叫時 Fragment 的生命週期, 如果呼叫 {@link #setData(Object)} 方法時 {@link Fragment#onCreate(Bundle)} 還沒執行 * 但在 {@link #setData(Object)} 裡卻呼叫了 Presenter 的方法, 是會報空的, 因為 Dagger 注入是在 {@link Fragment#onCreate(Bundle)} 方法中執行的 * 然後才建立的 Presenter, 如果要做一些初始化操作,可以不必讓外部呼叫 {@link #setData(Object)}, 在 {@link #initData(Bundle)} 中初始化就可以了 * <p> * Example usage: * <pre> * public void setData(@Nullable Object data) { * if (data != null && data instanceof Message) { * switch (((Message) data).what) { * case 0: * loadData(((Message) data).arg1); * break; * case 1: * refreshUI(); * break; * default: * //do something * break; * } * } * } * * // call setData(Object): * Message data = new Message(); * data.what = 0; * data.arg1 = 1; * fragment.setData(data); * </pre> * * @param data 當不需要引數時 {@code data} 可以為 {@code null} */ @Override public void setData(@Nullable Object data) {
}
@Override public void showLoading() {
}
@Override public void hideLoading() {
}
@Override public void showMessage(@NonNull String message) { checkNotNull(message); ArmsUtils.snackbarText(message); }
@Override public void launchActivity(@NonNull Intent intent) { checkNotNull(intent); ArmsUtils.startActivity(intent); }
@Override public void killMyself() {
}
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO: inflate a fragment view View rootView = super.onCreateView(inflater, container, savedInstanceState); unbinder = ButterKnife.bind(this, rootView); mPresenter.getshopping(); return rootView; }
@Override public void onDestroyView() { super.onDestroyView(); unbinder.unbind(); }
@Override public void showData(String js) {
Gson gson = new Gson(); newsShopp = gson.fromJson(js, NewsShopp.class); List<NewsShopp.DataBean> data = newsShopp.getData(); LinearLayoutManager manager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false); receShopp.setLayoutManager(manager); myShoppAdapter = new MyShoppAdapter(R.layout.wai_item, data); receShopp.setAdapter(myShoppAdapter);
myShoppAdapter.setOnCheckedChangeListener(new MyShoppAdapter.onCheckedChangeListener() { @Override public void onChecked(int layoutPosition, boolean isChecked) { boolean isAllChecked = true;
for (int i = 0; i < newsShopp.getData().size(); i++) { boolean checked = newsShopp.getData().get(i).getChecked(); for (int j = 0; j < newsShopp.getData().get(i).getList().size(); j++) { boolean innerChecked = newsShopp.getData().get(i).getList().get(j).getInnerChecked(); isAllChecked = (isAllChecked & checked & innerChecked); } }
checkShopp.setChecked(isAllChecked);
myShoppAdapter.notifyDataSetChanged(); }
public void onOutterIntemChecked(int layoutPosition, boolean checked) { newsShopp.getData().get(layoutPosition).setChecked(checked);
boolean isAllChecked = true; for (int i = 0; i < newsShopp.getData().size(); i++) { boolean checked1 = newsShopp.getData().get(i).getChecked(); for (int j = 0; j < newsShopp.getData().get(i).getList().size(); j++) { boolean innerChecked1 = newsShopp.getData().get(i).getList().get(j).getInnerChecked(); isAllChecked = (isAllChecked & checked1 & innerChecked1); } }
checkShopp.setChecked(isAllChecked);
myShoppAdapter.notifyDataSetChanged(); } }); }
@OnClick(R.id.check_shopp) public void onViewClicked(View view) { switch (view.getId()) { case R.id.check_shopp: if(checkShopp.isChecked()) { for (int i = 0; i < newsShopp.getData().size(); i++) { newsShopp.getData().get(i).setChecked(true); for (int j = 0; j < newsShopp.getData().get(i).getList().size(); j++) { newsShopp.getData().get(i).getList().get(j).setInnerChecked(true); } }
} else { for (int i = 0; i < newsShopp.getData().size(); i++) { newsShopp.getData().get(i).setChecked(false); for (int j = 0; j < newsShopp.getData().get(i).getList().size(); j++) { newsShopp.getData().get(i).getList().get(j).setInnerChecked(false); } } } initeview(); myShoppAdapter.notifyDataSetChanged(); break; } }
private void initeview() { int zong = 0; for (int i = 0; i < newsShopp.getData().size(); i++) { for (int j = 0; j < newsShopp.getData().get(i).getList().size(); j++) { if(newsShopp.getData().get(i).getList().get(j).getInnerChecked()) { zong+=newsShopp.getData().get(i).getList().get(j).getPrice()*newsShopp.getData().get(i).getList().get(j).getNum(); } } }
textZongjiashopp.setText("總價是:"+zong); myShoppAdapter.notifyDataSetChanged(); }
@Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(User1 user1) { /* Do something */ initeview(); }; @Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); }
@Override public void onStop() { super.onStop(); EventBus.getDefault().unregister(this); } }
3.購物車外部介面卡
public class MyShoppAdapter extends BaseQuickAdapter<NewsShopp.DataBean,BaseViewHolder> {
private List<NewsShopp.DataBean.ListBean> listBeans; private int layoutPosition;
onCheckedChangeListener onCheckedChangeListener; private List<NewsShopp.DataBean.ListBean> itemList;
public interface onCheckedChangeListener { void onChecked(int layoutPosition,boolean isChecked); }
public void setOnCheckedChangeListener(onCheckedChangeListener onCheckedChangeListener) { this.onCheckedChangeListener = onCheckedChangeListener; }
public MyShoppAdapter(int layoutResId, @Nullable List<NewsShopp.DataBean> data) { super(layoutResId, data); }
@Override protected void convert(BaseViewHolder helper, NewsShopp.DataBean item) {
layoutPosition = helper.getLayoutPosition();
helper.setText(R.id.check_waishang,item.getSellerName());
CheckBox check_waishang = helper.getView(R.id.check_waishang);
check_waishang.setOnCheckedChangeListener(null); check_waishang.setChecked(item.getChecked()); check_waishang.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { boolean checked = check_waishang.isChecked(); item.setChecked(checked); if(checked) { for (int i = 0; i < item.getList().size(); i++) { item.getList().get(i).setInnerChecked(true); } } else { for (int i = 0; i < item.getList().size(); i++) { item.getList().get(i).setInnerChecked(false); } }
onCheckedChangeListener.onChecked(layoutPosition,check_waishang.isChecked()); notifyDataSetChanged(); } });
RecyclerView rece_waiview = helper.getView(R.id.rece_waiview); itemList = item.getList(); MyNeiAdapter myNeiAdapter = new MyNeiAdapter(R.layout.nei_item, itemList); LinearLayoutManager manager = new LinearLayoutManager(App.getInstance(), LinearLayoutManager.VERTICAL, false); rece_waiview.setLayoutManager(manager); rece_waiview.setAdapter(myNeiAdapter); myNeiAdapter.setOnCheckedChangeListener(new MyNeiAdapter.onCheckedChangeListener() { @Override public void onChecked(int layoutPosition, boolean isChecked) { boolean isAllChecked = true; for (int i = 0; i < item.getList().size(); i++) { boolean innerChecked = item.getList().get(i).getInnerChecked(); isAllChecked = (isAllChecked & innerChecked); } check_waishang.setChecked(isAllChecked);
item.setChecked(isAllChecked);
onCheckedChangeListener.onChecked(layoutPosition,isChecked); } }); } }
4.外部介面卡佈局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:focusable="true" android:focusableInTouchMode="true" >
<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="商家" android:id="@+id/check_waishang" />
<android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/rece_waiview" />
</LinearLayout>
5.內部介面卡
public class MyNeiAdapter extends BaseQuickAdapter<NewsShopp.DataBean.ListBean,BaseViewHolder> { private int shangjiage;
public MyNeiAdapter(int layoutResId, @Nullable List<NewsShopp.DataBean.ListBean> data) { super(layoutResId, data); }
@Override protected void convert(BaseViewHolder helper, NewsShopp.DataBean.ListBean item) {
helper.setText(R.id.text_neiname2,item.getTitle()); helper.setText(R.id.text_neiprice2,"總價是:"+item.getPrice()+""); SimpleDraweeView simp_nei = helper.getView(R.id.simp_nei); String[] splitIms = item.getImages().split("\\|"); Uri parse = Uri.parse(splitIms[0]); simp_nei.setImageURI(parse);
helper.setChecked(R.id.check_nei,item.getInnerChecked()); CheckBox check_nei = helper.getView(R.id.check_nei); check_nei.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { item.setInnerChecked(check_nei.isChecked());
onCheckedChangeListener.onChecked(helper.getLayoutPosition(),check_nei.isChecked()); } });
Jiajian jiajian_jia = helper.getView(R.id.jiajian_jia); jiajian_jia.setOnNumClak(new Jiajian.OnNumClak() { @Override public void onShowNum(int number) { shangjiage = number; Toast.makeText(mContext, "number"+number, Toast.LENGTH_SHORT).show(); }
@Override public void add() {
item.setNum(item.getNum()+1); User1 user1 = new User1(); EventBus.getDefault().postSticky(user1);
}
@Override public void jian() { item.setNum(item.getNum()-1); User1 user1 = new User1(); EventBus.getDefault().postSticky(user1);
} });
Jiajian view1 = helper.getView(R.id.jiajian_jia); TextView text_number = view1.findViewById(R.id.text_number); text_number.setText(item.getNum()+""); }
onCheckedChangeListener onCheckedChangeListener;
public interface onCheckedChangeListener { void onChecked(int layoutPosition,boolean isChecked); }
public void setOnCheckedChangeListener(onCheckedChangeListener onCheckedChangeListener) { this.onCheckedChangeListener = onCheckedChangeListener; } }
6.內部介面卡佈局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="80dp" android:orientation="horizontal" >
<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/check_nei" />
<com.facebook.drawee.view.SimpleDraweeView android:layout_width="80dp" android:layout_height="80dp" android:id="@+id/simp_nei" android:layout_marginLeft="@dimen/dp_40" />
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="展示資料" android:id="@+id/text_neiname2" android:layout_marginLeft="125dp" />
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="價格" android:layout_marginLeft="125dp" android:layout_marginTop="55dp" android:textColor="#f00" android:id="@+id/text_neiprice2" />
<com.bwie.jid.mvp.ui.Jiajian android:layout_width="100dp" android:layout_height="30dp" android:layout_alignParentTop="true" android:id="@+id/jiajian_jia" android:layout_alignParentRight="true" android:layout_marginTop="42dp" android:layout_marginRight="0dp" />
</RelativeLayout>
7.加減器按鈕
public class Jiajian extends LinearLayout implements View.OnClickListener { private Button btn_jia; private TextView text_number; private Button btn_jian;
public Jiajian(Context context) { super(context); }
public Jiajian(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context); }
private void init(Context context) { LayoutInflater.from(context).inflate(R.layout.jiajian_item,this); btn_jia = (Button)findViewById(R.id.btn_jia); text_number = (TextView)findViewById(R.id.text_number); btn_jian = (Button)findViewById(R.id.btn_jian); btn_jia.setOnClickListener(this); btn_jian.setOnClickListener(this); }
@Override public void onClick(View v) {
String s = text_number.getText().toString(); int number = Integer.parseInt(s); switch (v.getId()) { case R.id.btn_jia: number+=1; text_number.setText(String.valueOf(number)); if(onNumClak!=null) { onNumClak.add(); } break; case R.id.btn_jian: if(number<1) { Toast.makeText(getContext(), "最小不能小於1", Toast.LENGTH_SHORT).show(); return; } number=1; text_number.setText(String.valueOf(number)); if(onNumClak!=null) { onNumClak.jian(); } break; } }
OnNumClak onNumClak;
public interface OnNumClak { void onShowNum(int number);
void add();
void jian(); }
public void setOnNumClak(OnNumClak onNumClak) { this.onNumClak = onNumClak; } }
8.購物車介面文件
//購物車 @GET("product/getCarts?uid=71") Observable<ResponseBody> getShopping();
9.購物車C層
public interface ShoppingContract { //對於經常使用的關於UI的方法可以定義到IView中,如顯示隱藏進度條,和顯示文字訊息 interface View extends IView {
void showData(String js); }
//Model層定義介面,外部只需關心Model返回的資料,無需關心內部細節,即是否使用快取 interface Model extends IModel {
Observable<ResponseBody> responseMsg(); } }
10.購物車M層
@Override public Observable<ResponseBody> responseMsg() { MService mService = mRepositoryManager.obtainRetrofitService(MService.class); Observable<ResponseBody> shopping = mService.getShopping(); return shopping; }
11.購物車P層
@SuppressLint("CheckResult") public void getshopping() { Observable<ResponseBody> responseBodyObservable = mModel.responseMsg(); responseBodyObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<ResponseBody>() { @Override public void accept(ResponseBody responseBody) throws Exception {
String js = responseBody.string(); mRootView.showData(js); } }); }
12.bean類的資料請求
public static class DataBean { /** * list : [{"bargainPrice":99,"createtime":"2017-10-14T21:38:26","detailUrl":"https://item.m.jd.com/product/4345173.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t6037/35/2944615848/95178/6cd6cff0/594a3a10Na4ec7f39.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6607/258/1025744923/75738/da120a2d/594a3a12Ne3e6bc56.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6370/292/1057025420/64655/f87644e3/594a3a12N5b900606.jpg!q70.jpg","num":4,"pid":45,"price":2999,"pscid":39,"selected":0,"sellerid":1,"subhead":"高清雙攝,就是清晰!2000+1600萬高清攝像頭,6GB大記憶體+高通驍龍835處理器,效能怪獸!","title":"一加手機5 (A5000) 6GB+64GB 月岩灰 全網通 雙卡雙待 移動聯通電信4G手機"},{"bargainPrice":11800,"createtime":"2017-10-10T17:33:37","detailUrl":"https://item.m.jd.com/product/4338107.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t6700/155/2098998076/156185/6cf95035/595dd5a5Nc3a7dab5.jpg!q70.jpg","num":28,"pid":57,"price":5199,"pscid":40,"selected":0,"sellerid":1,"subhead":"【i5 MX150 2G視訊記憶體】全高清窄邊框 8G記憶體 256固態硬碟 支援指紋識別 預裝WIN10系統","title":"小米(MI)Air 13.3英寸全金屬輕薄筆記本(i5-7200U 8G 256G PCle SSD MX150 2G獨顯 FHD 指紋識別 Win10)銀\r\n"},{"bargainPrice":111.99,"createtime":"2017-10-03T23:53:28","detailUrl":"https://item.m.jd.com/product/4719303.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t9004/210/1160833155/647627/ad6be059/59b4f4e1N9a2b1532.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t7504/338/63721388/491286/f5957f53/598e95f1N7f2adb87.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t7441/10/64242474/419246/adb30a7d/598e95fbNd989ba0a.jpg!q70.jpg","num":1,"pid":8,"price":324,"pscid":1,"selected":0,"sellerid":1,"subhead":"每個中秋都不能簡單,無論身在何處,你總需要一塊餅讓生活更圓滿,京東月餅讓愛更圓滿京東自營,閃電配送,更多驚喜,快用手指戳一下","title":"北京稻香村 稻香村中秋節月餅 老北京月餅禮盒655g"}] * sellerName : 商家1 * sellerid : 1 */
private String sellerName; private String sellerid; private List<ListBean> list; private boolean isChecked;
public boolean getChecked() { return isChecked; }
public void setChecked(boolean isChecked) { this.isChecked = isChecked; }
13.bean類的資料請求二
public static class ListBean { /** * bargainPrice : 99.0 * createtime : 2017-10-14T21:38:26 * detailUrl : https://item.m.jd.com/product/4345173.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends * images : https://m.360buyimg.com/n0/jfs/t6037/35/2944615848/95178/6cd6cff0/594a3a10Na4ec7f39.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6607/258/1025744923/75738/da120a2d/594a3a12Ne3e6bc56.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6370/292/1057025420/64655/f87644e3/594a3a12N5b900606.jpg!q70.jpg * num : 4 * pid : 45 * price : 2999.0 * pscid : 39 * selected : 0 * sellerid : 1 * subhead : 高清雙攝,就是清晰!2000+1600萬高清攝像頭,6GB大記憶體+高通驍龍835處理器,效能怪獸! * title : 一加手機5 (A5000) 6GB+64GB 月岩灰 全網通 雙卡雙待 移動聯通電信4G手機 */
private double bargainPrice; private String createtime; private String detailUrl; private String images; private int num; private int pid; private double price; private int pscid; private int selected; private int sellerid; private String subhead; private String title; private boolean innerChecked;
public boolean getInnerChecked() { return innerChecked; }
public void setInnerChecked(boolean innerChecked) { this.innerChecked = innerChecked; }