MyCallBack
public interface MyCallBack {
void setData(Data data);
void setError(String error);
}
Model
public interface Model {
void getData(String url, MyCallBack callBack);
}
public class ModelImp implements Model{
private MyCallBack callBack;
private Handler mp = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==0){
String s= (String) msg.obj;
Gson gson=new Gson();
Data data = gson.fromJson(s, Data.class);
callBack.setData(data);
}
}
};
@Override
public void getData(final String url, final MyCallBack callBack) {
this.callBack = callBack;
new Thread(new Runnable() {
@Override
public void run() {
try {
String jsonStr = OkHttpUtils.getInctance().get(url);
mp.sendMessage(mp.obtainMessage(0,jsonStr));
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
Presenter
public interface IPresenter {
void startRequest(String url);
}
public class IPresenterImp implements IPresenter{
private ModelImp modelImp;
private IView iView;
public IPresenterImp(IView iView) {
this.iView = iView;
modelImp = new ModelImp();
}
@Override
public void startRequest(String url) {
modelImp.getData(url, new MyCallBack() {
@Override
public void setData(Data data) {
iView.getSuccess(data);
}
@Override
public void setError(String error) {
iView.getError(error);
}
});
}
}
IView
public interface IView {
void getSuccess(Data data);
void getError(String error);
}
自定义控件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:background="#99000000"
android:gravity="center_vertical"
android:padding="2dp">
<TextView
android:id="@+id/delete_tv"
android:layout_width="20dp"
android:layout_height="50dp"
android:background="#ffffff"
android:gravity="center"
android:text="-"
android:textSize="16sp" />
<TextView
android:id="@+id/product_number_tv"
android:layout_width="30dp"
android:layout_height="50dp"
android:layout_marginLeft="2dp"
android:layout_weight="1"
android:background="#ffffff"
android:gravity="center"
android:text="1" />
<TextView
android:id="@+id/add_tv"
android:layout_width="20dp"
android:layout_height="50dp"
android:layout_marginLeft="2dp"
android:background="#ffffff"
android:gravity="center"
android:text="+"
android:textSize="16sp" />
</LinearLayout>
public class ZiDingYiActivity extends LinearLayout implements View.OnClickListener {
private TextView mAdd;
private TextView mDelete;
private TextView mNumber;
//商品数量
private int mCount;
public ZiDingYiActivity(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.zidingyi, this);
initViews();
}
private void initViews() {
mAdd = findViewById(R.id.add_tv);
mDelete = findViewById(R.id.delete_tv);
mNumber = findViewById(R.id.product_number_tv);
mAdd.setOnClickListener(this);
mDelete.setOnClickListener(this);
}
//先给初始值赋值
public void setNumber(int number) {
this.mCount = number;
mNumber.setText(number + "");
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.delete_tv:
if (mCount > 0) {
mCount--;
mNumber.setText(mCount + "");
if (mCountChange!=null){
mCountChange.setCount(mCount);
}
}else {
Toast.makeText(getContext(), "商品已售空", Toast.LENGTH_SHORT).show();
}
break;
case R.id.add_tv:
mCount++;
mNumber.setText(mCount + "");
if (mCountChange!=null){
mCountChange.setCount(mCount);
}
break;
}
}
public interface OnCountChange {
void setCount(int count);
}
private OnCountChange mCountChange;
public void setOnChange(OnCountChange countChange) {
this.mCountChange = countChange;
}
}
Activity
public class Main2Activity extends AppCompatActivity implements IView2 {
private String mUrl = "http://www.wanandroid.com/tools/mockapi/6523/restaurant-list";
private ArrayList<User.DataBean> lists = new ArrayList<>();
private ExpandableListView expand_view;
private TextView go_to_js;
private TextView all_price;
private CheckBox check_all;
private IPresenterImp2 iPresenterImp2;
private ErJiAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initView();
try {
iPresenterImp2 = new IPresenterImp2(this);
iPresenterImp2.startRequest(mUrl);
} catch (IOException e) {
e.printStackTrace();
}
adapter = new ErJiAdapter(lists,this);
expand_view.setAdapter(adapter);
adapter.setCallBack(new ErJiAdapter.AdapterCallback() {
@Override
public void setCroupCheck(int groupPosition) {
boolean childAllCheck = adapter.isChildAllCheck(groupPosition);
adapter.childAllCheck(groupPosition, !childAllCheck);
adapter.notifyDataSetChanged();
diaoyong();
}
@Override
public void setChildCheck(int groupPosition, int childPosition) {
boolean childChecked = adapter.isChildChecked(groupPosition, childPosition);
adapter.setChildChecked(groupPosition,childPosition,!childChecked);
adapter.notifyDataSetChanged();
diaoyong();
}
@Override
public void setNumber(int groupPosition, int childPosition, int number) {
adapter.setShangPingNumber(groupPosition,childPosition,number);
adapter.notifyDataSetChanged();
diaoyong();
}
});
check_all.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean allGoods = adapter.isAllGoods();
adapter.setAllGoodsIsChecked(!allGoods);
adapter.notifyDataSetChanged();
diaoyong();
}
});
}
private void initView() {
check_all = findViewById(R.id.Check_All);
all_price = findViewById(R.id.All_Price);
go_to_js = findViewById(R.id.Go_To_JS);
expand_view = findViewById(R.id.Expand_View);
expand_view.setGroupIndicator(null);
}
@Override
public void getSuccess(User data) {
lists.addAll(data.getData());
adapter.notifyDataSetChanged();
}
@Override
public void getError(String error) {
Toast.makeText(this, "失败", Toast.LENGTH_SHORT).show();
}
private void diaoyong(){
boolean allGoods = adapter.isAllGoods();
check_all.setChecked(allGoods);
int allGoodsNumber = adapter.getAllGoodsNumber();
float allGoodsPrice = adapter.getAllGoodsPrice();
all_price.setText("价格:" + allGoodsPrice);
go_to_js.setText("去结算(" + allGoodsNumber + ")");
}
}
Adapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener{
private ArrayList<Data.DataBean> lists;
private Context context;
public MyAdapter(ArrayList<Data.DataBean> lista, FragmentActivity contexta) {
this.lists = lista;
this.context = contexta;
}
@NonNull
@Override
public MyAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(context).inflate(R.layout.item,viewGroup,false);
ViewHolder viewHolder = new ViewHolder(v);
v.setOnClickListener(this);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull MyAdapter.ViewHolder viewHolder, int i) {
ViewGroup.LayoutParams params = viewHolder.itemView.getLayoutParams();
Random random = new Random();
int gao = random.nextInt(100)+200;
params.height = gao;
viewHolder.itemView.setLayoutParams(params);
Glide.with(context).load(lists.get(i).getPic_url()).into(viewHolder.img);
viewHolder.text1.setText(lists.get(i).getName()+"");
viewHolder.text2.setText(lists.get(i).getBulletin()+"");
viewHolder.text3.setText(lists.get(i).getAverage_price_tip()+"");
viewHolder.itemView.setTag(i);
}
@Override
public int getItemCount() {
return lists.size();
}
public interface ItemClick {
void setOnItemClick(View view, int position);
}
private ItemClick mItemClick;
public void setOnClickListener(ItemClick itemClick) {
this.mItemClick = itemClick;
}
@Override
public void onClick(View v) {
if (mItemClick != null) {
mItemClick.setOnItemClick(v, (int) v.getTag());
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView img;
private TextView text1;
private TextView text2;
private TextView text3;
public ViewHolder(@NonNull View itemView) {
super(itemView);
img = itemView.findViewById(R.id.img);
text1 = itemView.findViewById(R.id.text1);
text2 = itemView.findViewById(R.id.text2);
text3 = itemView.findViewById(R.id.text3);
}
}
}
erjiAdapter
public class ErJiAdapter extends BaseExpandableListAdapter {
private ArrayList<User.DataBean> lists= new ArrayList<>();
private Context context;
public ErJiAdapter(ArrayList<User.DataBean> listsa, Context contexta) {
this.lists = listsa;
this.context = contexta;
}
@Override
public int getGroupCount() {
return lists.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return lists.get(groupPosition).getSpus().size();
}
@Override
public Object getGroup(int groupPosition) {
return null;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return null;
}
@Override
public long getGroupId(int groupPosition) {
return 0;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupHolder groupHolder = null;
if (convertView == null){
groupHolder = new GroupHolder();
convertView = View.inflate(context,R.layout.item2,null);
groupHolder.GroupCheckBox = convertView.findViewById(R.id.group_cb);
groupHolder.GroupTextView = convertView.findViewById(R.id.group_tv);
convertView.setTag(groupHolder);
}else{
groupHolder = (GroupHolder) convertView.getTag();
}
User.DataBean dataBean = lists.get(groupPosition);
groupHolder.GroupTextView.setText(dataBean.getName()+"");
boolean childAllCheck = isChildAllCheck(groupPosition);
groupHolder.GroupCheckBox.setChecked(childAllCheck);
groupHolder.GroupCheckBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (adapterCallback!=null){
adapterCallback.setCroupCheck(groupPosition);
}
}
});
return convertView;
}
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ChildHolder childHolder = null;
if (convertView == null){
childHolder = new ChildHolder();
convertView = View.inflate(context,R.layout.item3,null);
childHolder.ChildCheckBox = convertView.findViewById(R.id.child_cb);
childHolder.ChildImage = convertView.findViewById(R.id.child_img);
childHolder.ChildTextView1 = convertView.findViewById(R.id.child_tv1);
childHolder.ChildTextView2 = convertView.findViewById(R.id.child_tv2);
//查找自定义控件
childHolder.ZiDingYi = convertView.findViewById(R.id.zidingyi);
convertView.setTag(childHolder);
}else{
childHolder = (ChildHolder) convertView.getTag();
}
User.DataBean.SpusBean spusBean = lists.get(groupPosition).getSpus().get(childPosition);
Glide.with(context).load(spusBean.getPic_url()).into(childHolder.ChildImage);
childHolder.ChildTextView1.setText(spusBean.getName()+"");
childHolder.ChildTextView2.setText("¥"+spusBean.getSkus().get(0).getPrice());
childHolder.ChildCheckBox.setChecked(spusBean.isChildChecked());
//自定义控件赋值
childHolder.ZiDingYi.setNumber(spusBean.getPraise_num());
childHolder.ChildCheckBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (adapterCallback!=null){
adapterCallback.setChildCheck(groupPosition,childPosition);
}
}
});
childHolder.ZiDingYi.setOnChange(new ZiDingYiActivity.OnCountChange() {
@Override
public void setCount(int count) {
if (adapterCallback!=null){
adapterCallback.setNumber(groupPosition,childPosition,count);
}
}
});
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
class GroupHolder{
CheckBox GroupCheckBox;
TextView GroupTextView;
}
class ChildHolder{
CheckBox ChildCheckBox;
ImageView ChildImage;
TextView ChildTextView1;
TextView ChildTextView2;
ZiDingYiActivity ZiDingYi;
}
//111111111111111111111111点击group的CheckBox让所有child选中
public void childAllCheck(int groupPosition, boolean isCheck) {
User.DataBean dataBean = lists.get(groupPosition);
List<User.DataBean.SpusBean> spus = dataBean.getSpus();
for (int i = 0; i < spus.size(); i++) {
User.DataBean.SpusBean bean = spus.get(i);
bean.setChildChecked(isCheck);
}
}
//11111111111111111111111用来判断小组是否全被选中
public boolean isChildAllCheck(int groupPosition) {
boolean boo = true;
User.DataBean dataBean = lists.get(groupPosition);
List<User.DataBean.SpusBean> spus = dataBean.getSpus();
for (int i = 0; i < spus.size(); i++) {
User.DataBean.SpusBean bean = spus.get(i);
//只要有一个没有被选中 点这个CheckBox就是全选的功能
if (!bean.isChildChecked()) {
return false;
}
}
return boo;
}
//2222222222222222222222因为咱们底部视图有个一全选和反选
public boolean isAllGoods() {
boolean boo = true;
for (int i = 0; i < lists.size(); i++) {
User.DataBean dataBean = lists.get(i);
for (int j = 0; j < dataBean.getSpus().size(); j++) {
User.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
if (!spusBean.isChildChecked()) {
boo = false;
}
}
}
return boo;
}
//222222222222222222222全选反选功能
public void setAllGoodsIsChecked(boolean isAllCheck) {
for (int i = 0; i < lists.size(); i++) {
User.DataBean dataBean = lists.get(i);
for (int j = 0; j < dataBean.getSpus().size(); j++) {
User.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
spusBean.setChildChecked(isAllCheck);
}
}
}
//22222222222222222222点击child给他进行赋值
public void setChildChecked(int groupPositon, int childPositon, boolean isCheckBox) {
User.DataBean.SpusBean spusBean = lists.get(groupPositon).getSpus().get(childPositon);
spusBean.setChildChecked(isCheckBox);
}
//22222222222222222222查看当前这个商品有没有被选中
public boolean isChildChecked(int groupPositon, int childPositon) {
User.DataBean.SpusBean spusBean = lists.get(groupPositon).getSpus().get(childPositon);
if (spusBean.isChildChecked()) {
return true;
}
return false;
}
//333333333333333333333333333计算所有商品的价格
public float getAllGoodsPrice() {
float allPrice = 0;
for (int i = 0; i < lists.size(); i++) {
User.DataBean dataBean = lists.get(i);
for (int j = 0; j < dataBean.getSpus().size(); j++) {
User.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
if (spusBean.isChildChecked()){
allPrice = allPrice + spusBean.getPraise_num() * Float.parseFloat(spusBean.getSkus().get(0).getPrice());
}
}
}
return allPrice;
}
//333333333333333333333333333计算所有商品的数量
public int getAllGoodsNumber() {
int allNumber = 0;
for (int i = 0; i < lists.size(); i++) {
User.DataBean dataBean = lists.get(i);
for (int j = 0; j < dataBean.getSpus().size(); j++) {
User.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
if (spusBean.isChildChecked()){
allNumber = allNumber + spusBean.getPraise_num();
}
}
}
return allNumber;
}
//333333333333333333333333333给商品数量进行赋值
public void setShangPingNumber(int groupPosition, int childPosition, int number) {
User.DataBean.SpusBean spusBean = lists.get(groupPosition).getSpus().get(childPosition);
spusBean.setPraise_num(number);
}
//自定义一个接口
public interface AdapterCallback{
void setCroupCheck(int groupPosition);
void setChildCheck(int groupPosition,int childPosition);
void setNumber(int groupPosition,int childPosition,int number);
}
private AdapterCallback adapterCallback;
public void setCallBack(AdapterCallback adapterCallback){
this.adapterCallback = adapterCallback;
}
}
OkHttp
public class OkHttpUtils {
public static OkHttpClient okHttpClient;
private OkHttpUtils() {
HttpLoggingInterceptor interceptor=new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(10,TimeUnit.SECONDS)
.writeTimeout(10,TimeUnit.SECONDS)
.readTimeout(10,TimeUnit.SECONDS)
.addInterceptor(interceptor)
.build();
}
public static OkHttpUtils getInctance(){
return OkViewHolder.UTIL;
}
static class OkViewHolder{
public static OkHttpUtils UTIL = new OkHttpUtils();
}
public static String get(String mPath) throws IOException {
Request request = new Request.Builder().url(mPath).build();
Response response = okHttpClient.newCall(request).execute();
return response.body().string();
}
}
防止内存泄漏
//防止内存泄漏
public void onDetatch() {
if (modelImp2 != null) {
modelImp2 = null;
}
if (iView2 != null) {
iView2 = null;
}
}