写功能之前需要先查看bean包是否有checked,如果没有就自己添加一下,有几层数据就添加几个
private boolean checked;
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
我们先写一个自定义View一个控件,自定义View一定要继承RelativeLayout ,布局也要使用RelativeLayout ,我们在自定义View中获取控件,设置加减的方法,并且用接口回调把加减的方法,回传到内部适配器里面,从内部适配器获取数量,用文本框进行展示
public class ShopCarView extends RelativeLayout implements View.OnClickListener {
private EditText editText;
public ShopCarView(Context context) {
super(context);
init(context);
}
public ShopCarView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private Context mContext;
private void init(Context context) {
this.mContext = context;
View view = View.inflate(context,R.layout.shop_car_view,null);
editText = view.findViewById(R.id.ed_text);
view.findViewById(R.id.tv_jia).setOnClickListener(this);
view.findViewById(R.id.tv_jian).setOnClickListener(this);
//这是在输入框内部写内容的代码
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(!TextUtils.isEmpty(s.toString())){
if(s.toString().startsWith("0")){
Toast.makeText(mContext, "不能输入为0", Toast.LENGTH_LONG).show();
}
int num = Integer.parseInt(s.toString());
if(num<1){
num=1;
}
if(mChangeNumListener!=null){
mChangeNumListener.num(num);
}
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
addView(view);
}
public void setNum(int num) {
editText.setText(num+"");
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.tv_jia:
String num = editText.getText().toString().trim();
int n = Integer.parseInt(num);
n++;
mChangeNumListener.num(n);
editText.setText(n+"");
break;
case R.id.tv_jian:
String numjian = editText.getText().toString().trim();
int njian = Integer.parseInt(numjian);
if(njian==1){
Toast.makeText(mContext, "至少得有一个商品哦~", Toast.LENGTH_LONG).show();
return;
}
njian--;
mChangeNumListener.num(njian);
editText.setText(njian+"");
break;
}
}
private ChangeNumListener mChangeNumListener;
public void setChangeNumListener(ChangeNumListener mChangeNumListener){
this.mChangeNumListener=mChangeNumListener;
}
public interface ChangeNumListener{
void num(int num);
}
}
接着我们就需要完善二级列表的适配器,二级列表不需要setList,首先如果我们要想连动,我们就需要先进行改变商品的状态,接着我们就设置一个状态,接着我们就调用一下自定义View的接口回调,设置一下数量,最后我们还是以接口回调的方式,把数据回传给外部适配器
//拿到商品个数
int num = list.get(i).getNum();
shopCarChildViewHolder.shopview.setNum(num);
//改变商品的状态
shopCarChildViewHolder.mcheckbox.setChecked(list.get(i).isChecked());
shopCarChildViewHolder.mcheckbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean isChecket = shopCarChildViewHolder.mcheckbox.isChecked();
//更改商品的状态
list.get(i).setChecked(isChecket);
//把发生状态之后的集合回传给使用的页面
mChannerListListener.changeList(list);
}
});
shopCarChildViewHolder.shopview.setChangeNumListener(new ShopCarView.ChangeNumListener() {
@Override
public void num(int num) {
list.get(i).setNum(num);
//把发生状态之后的集合回传给使用的页面
mChannerListListener.changeList(list);
}
});
private ChannerListListener mChannerListListener;
public void setChannerListListener(ChannerListListener mChannerListListener){
this.mChannerListListener=mChannerListListener;
}
public interface ChannerListListener{
void changeList(List<UserBean.DataBean.ListBean> list);
}
依次再完善一级列表,外部适配器进行连动,和内部的适配器有些相似之处,首先我们我们还是一样先设置商家的状态,接着设置CheckBox的点击事件,在点击事件里得到商家的选中状态,接着我们更改一下商家的状态,然后我们获取内部适配器的集合,接着我们使用for循环遍历数据,接着我们更改一下商家下商品的状态,接着我们就该调用内部适配器的接口回调,在这个接口创建一个初始值,然后用for循环遍历一下商家下的商品,接着我们判断一下是否选中,如果选中的话,我们进行初始值加加,遍历完数据之后,紧接着我们就该判断一下是否全选了,判断是否全选,我们只需要判断初始值是否等于总长度,如果等于总长度的话我们给每一条数据设置选中,相反就是不选中,最后我们需要创建一个接口回调,把集合传给展示页面,还有最重要的一点,千万不要忘记,刷新页面,因为我们再改动选中效果的时候,需要不断的刷新页面,来改变展示的效果
//设置商家选中状态
shopCarViewHolder.mcheckBox.setChecked(list.get(i).isChecked());
shopCarChildAdapter.setChannerListListener(new ShopCarChildAdapter.ChannerListListener() {
@Override
public void changeList(List<UserBean.DataBean.ListBean> listChild) {
int num=0;
//遍历商家下的商品
for (int j = 0; j < listChild.size(); j++) {
if(listChild.get(j).isChecked()){
num++;
}
}
//是全选
if(num==listChild.size()){
list.get(i).setChecked(true);
}else{//非选中
list.get(i).setChecked(false);
}
//刷新当前条目
notifyItemChanged(i);
//把发生变化之后的集合回传给使用页面
mChannerListListener.changeList(list);
}
});
shopCarViewHolder.mcheckBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//得到商家的选中的状态
boolean ischecked = shopCarViewHolder.mcheckBox.isChecked();
//更改商家的状态
list.get(i).setChecked(ischecked);
List<UserBean.DataBean.ListBean> listChild = list.get(i).getList();
for (int j = 0; j <listChild.size() ; j++) {
//更改指定商家下的商品状态
listChild.get(j).setChecked(ischecked);
}
//刷新当前条目
notifyItemChanged(i);
//把发生变化之后的集合回传给使用页面
mChannerListListener.changeList(list);
}
});
private ChannerListListener mChannerListListener;
public void setChannerListListener(ChannerListListener mChannerListListener) {
this.mChannerListListener = mChannerListListener;
}
public interface ChannerListListener {
void changeList(List<UserBean.DataBean> list);
}
最后就需要在我们的展示页面完善一下操作就可以了,一定要注意Adapter记得初始化,这就是展示页面的代码,首先我们先进行调用外部适配器的接口回调,因为我们需要在这个适配器里面进行,价格和数量的连动,所以我们需要先定义总价、总数量、还有一个初始值,接着我们遍历一下数据,当每一条数据为选中的状态时,我们就可以初始数量的控制,紧接着我们要拿到内部适配器的集合,遍历集合里面的数据,当然也必须让数据为选中状态,因为是选中状态我们才可以进行价格的连动,接着我们在for循环里面获取到价格和数量,接着我们赋值总价和总数量,然后我们再以初始化来判断是否为全选,接着我们把总价和总数量,用TextView进行展示,接着我们完善一下页面的点击事件,这个点击事件里面我们只需要定义两个数就行了,一个是总价,另一个是总数量,接着我们获取CheckBox的状态,接着我们用for循环遍历本层的数据,在for循环里面改变商家的状态,然后我们获取内部适配器的集合,然后我们遍历集合,改变商品的状态,接着获取集合的价格和数量,然后还是进行赋值总价和总数量,接着我们需要创建一个非选中的状态,让总价,和总数量都为零,最后我们让总价和总数量用TextView进行展示,当然数量发生了改变就意味着我们需要改变,接着我们只需要重新设置一下适配器即可
shopCarAdapter.setChannerListListener(new ShopCarAdapter.ChannerListListener() {
@Override
public void changeList(List<UserBean.DataBean> list) {//接收发生变化之后的集合
float price = 0;
int allNum = 0;
int shopCarNum = 0;
for (int i = 0; i <list.size() ; i++) {
if(list.get(i).isChecked()){
shopCarNum++;
}
//得到商家下的商品集合
List<UserBean.DataBean.ListBean> childList = list.get(i).getList();
for (int j = 0; j < childList.size(); j++) {
if(childList.get(j).isChecked()){//必须为选中
float p = childList.get(j).getPrice();//取价格
int n = childList.get(j).getNum();//取个数
allNum=allNum+n;//计算选中的商品个数
price=price+(p*n);//计算选中的商品总价
}
}
}
if(shopCarNum==list.size()){//所有的商家选中
mCheckbox.setChecked(true);
}else{
mCheckbox.setChecked(false);
}
//设置
mTvPrice.setText(price+"");
mTvNum.setText("去结算("+allNum+")");
}
});
@Override
public void onClick(View v) {
float price = 0;
int allNum = 0;
//获取状态
boolean ischecked = mCheckbox.isChecked();
for (int i = 0; i <data.size() ; i++) {
//改变商家状态
data.get(i).setChecked(ischecked);
//商家下所有的商品
List<UserBean.DataBean.ListBean> childList = data.get(i).getList();
for (int j = 0; j <childList.size() ; j++) {
//改变商品的状态
childList.get(j).setChecked(ischecked);
//拿到每一个商品的价格
float p = childList.get(j).getPrice();
//商品的个数
int n = childList.get(j).getNum();
//计算总价
price=price+(p*n);
//计算个数
allNum = allNum+n;
}
}
//非选中
if(!ischecked){
price=0.0f;
allNum=0;
}
mTvPrice.setText(price+"");
mTvNum.setText("去结算("+allNum+")");
//刷新
shopCarAdapter.setList(data);
}