布局:
需要三个自定义: 1.2为的是解决滑动冲突 3.为自定义的加减框
1. ExpandableListView--自定义二级列表
public class MyExpandableListView extends ExpandableListView {
public MyExpandableListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
2.ScrollView--自定义滑动组件
public class MyScrollView extends ScrollView {
private int downX, downY;
private int mTouchSlop;
public MyScrollView(Context context) {
this(context, null);
}
public MyScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
downX = (int) ev.getRawX();
downY = (int) ev.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int moveY = (int) ev.getRawY();
// 判断是否滑动,若滑动就拦截事件
if (Math.abs(moveY - downY) > mTouchSlop) {
return true;
}
break;
default:
break;
}
return super.onInterceptTouchEvent(ev);
}
}
3.MyNumLayout--继承自LinearLayout 一个自定义的加减控件
public class MyNumLayout extends LinearLayout implements View.OnClickListener {
private TextView numLost;
private TextView numShow;
private TextView numAdd;
public MyNumLayout(Context context) {
this(context, null);
}
public MyNumLayout(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MyNumLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//加载视图
View view = View.inflate(context, R.layout.number_layout, this);
numLost = view.findViewById(R.id.num_lost);
numShow = view.findViewById(R.id.num_show);
numAdd = view.findViewById(R.id.num_add);
//加监听
numLost.setOnClickListener(this);
numAdd.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.num_lost:
String s = numShow.getText().toString();
int i = Integer.parseInt(s);
i--;
if(i >= 0){
setNumShow(i+"");
listener.changeTransaction(s);
}
break;
case R.id.num_add:
String s2 = numShow.getText().toString();
int i2 = Integer.parseInt(s2);
i2++;
setNumShow(i2+"");
listener.changeTransaction(s2);
break;
}
}
//暴露的设置和改变的num值方法
public void setNumShow(String s) {
numShow.setText(s);
}
public String getNumShow() {
return numShow.getText().toString();
}
//搞一个加减的监听,数量也随之改变的回调接口
private ChangeNumListener listener;
public interface ChangeNumListener{
void changeTransaction(String tnum);
}
public void setListener(ChangeNumListener listener) {
this.listener = listener;
}
}
适配器:
二级列表的适配器
public class MyExListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<CartBean.DataBean> list;
public MyExListAdapter(Context context, List<CartBean.DataBean> list) {
this.context = context;
this.list = list;
}
@Override
public int getGroupCount() {
return list.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return list.get(groupPosition).getList().size();
}
@Override
public Object getGroup(int groupPosition) {
return list.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return list.get(groupPosition).getList().get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
//容器
static class GroupHolder{
public TextView textName;
}
static class ChildHolder{
public TextView TextTitle;
public TextView TextPrice;
public ImageView imageInfo;
public CheckBox checkInfo;
public MyNumLayout numLayout;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupHolder holder = null;
if(convertView == null){
convertView = View.inflate(context,R.layout.group_item,null);
holder = new GroupHolder();
holder.textName = convertView.findViewById(R.id.text_name);
convertView.setTag(holder);
}else{
holder = (GroupHolder) convertView.getTag();
}
holder.textName.setText(list.get(groupPosition).getSellerName());
return convertView;
}
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ChildHolder holder = null;
if(convertView == null){
convertView = View.inflate(context,R.layout.child_item,null);
holder = new ChildHolder();
holder.TextTitle = convertView.findViewById(R.id.text_title);
holder.TextPrice = convertView.findViewById(R.id.text_price);
holder.imageInfo = convertView.findViewById(R.id.image_info);
holder.numLayout = convertView.findViewById(R.id.num_layout);//加减控件
holder.checkInfo = convertView.findViewById(R.id.check_info);//多选框
convertView.setTag(holder);
}else{
holder = (ChildHolder) convertView.getTag();
}
final String num = list.get(groupPosition).getList().get(childPosition).getNum();
final String price = list.get(groupPosition).getList().get(childPosition).getPrice();
boolean checkState = list.get(groupPosition).getList().get(childPosition).isCheckState();
holder.TextPrice.setText("$"+ price);
holder.numLayout.setNumShow(num);
holder.TextTitle.setText(list.get(groupPosition).getList().get(childPosition).getTitle());
Glide.with(context).load(list.get(groupPosition).getList().get(childPosition).getImages().split("\\|")[0]).into(holder.imageInfo);
holder.checkInfo.setChecked(checkState);
//判断起始状态
boolean firstFlag = false;
if(checkState){
sumPrice(price,num,checkState);
firstFlag = true;
}else if(firstFlag){
sumPrice(price,num,checkState);
firstFlag = false;
}
//选中条目进算总价
final ChildHolder finalHolder = holder;
holder.checkInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkedState = finalHolder.checkInfo.isChecked();
sumPrice(price,num,checkedState);
}
});
//点击加减的监听
final ChildHolder finalHolder1 = holder;
holder.numLayout.setListener(new MyNumLayout.ChangeNumListener() {
@Override
public void changeTransaction(String tnum) {
String numShow = finalHolder1.numLayout.getNumShow();
if(checkedState) {
sumPrice(price, tnum, checkedState);
}
}
});
return convertView;
}
private double sum = 0 ;//记录总价
private int count = 0 ; //记录选中多选框的数量
private boolean checkedState = false;//记录选中状态
//计算总价
public void sumPrice(String num, String price, boolean checked) {
if (checked){
sum += Double.parseDouble(num) * Double.parseDouble(price);
}else{
sum -= Double.parseDouble(num) * Double.parseDouble(price);
}
onSumListener.takeSumPrice(sum);
}
//回调总价接口
private OnSumListener onSumListener;
public interface OnSumListener{
void takeSumPrice(double sum);
}
public void setOnSumListener(OnSumListener onSumListener) {
this.onSumListener = onSumListener;
}
}//end
本文介绍了一种自定义UI组件的方法,包括解决滑动冲突的ScrollView、自定义的加减控件MyNumLayout及自定义的ExpandableListView,并实现了一个用于购物车展示的二级列表适配器。
7568

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



