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;
}