diff --git a/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt new file mode 100644 index 0000000..a4855a4 --- /dev/null +++ b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt @@ -0,0 +1,67 @@ +package com.casic.br.adapter + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.casic.br.R +import com.casic.br.model.AddressListModel +import com.pengxh.kt.lite.extensions.dp2px +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeViewHolder + +class AddressListAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater: LayoutInflater = LayoutInflater.from(context) + + private var deleteAction = QMUISwipeAction.ActionBuilder() + .icon(ContextCompat.getDrawable(context, R.drawable.ic_delete_white)) + .textSize(16f.dp2px(context)) + .textColor(Color.WHITE) + .paddingStartEnd(16f.dp2px(context)).text("删除") + .backgroundColor(Color.RED) + .build() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QMUISwipeViewHolder { + val view = layoutInflater.inflate(R.layout.item_address_rv_l, parent, false) + val swipeViewHolder = QMUISwipeViewHolder(view) + swipeViewHolder.addSwipeAction(deleteAction) + return swipeViewHolder + } + + override fun onBindViewHolder(holder: QMUISwipeViewHolder, position: Int) { + //初始化控件 + val userPhoneView: TextView = holder.itemView.findViewById(R.id.userPhoneView) + val detailAddressView: TextView = holder.itemView.findViewById(R.id.detailAddressView) + val updateTimeView: TextView = holder.itemView.findViewById(R.id.updateTimeView) + val editAddressView: ImageView = holder.itemView.findViewById(R.id.editAddressView) + + //绑定数据 + val rowsBean = dataRows[position] + userPhoneView.text = rowsBean.account + detailAddressView.text = rowsBean.detailAddress + updateTimeView.text = rowsBean.updateTime + + editAddressView.setOnClickListener { + clickListener?.onEditButtonClicked(position) + } + } + + override fun getItemCount(): Int = dataRows.size + + private var clickListener: OnItemClickListener? = null + + interface OnItemClickListener { + fun onEditButtonClicked(position: Int) + } + + fun setOnItemClickListener(clickListener: OnItemClickListener?) { + this.clickListener = clickListener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt new file mode 100644 index 0000000..a4855a4 --- /dev/null +++ b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt @@ -0,0 +1,67 @@ +package com.casic.br.adapter + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.casic.br.R +import com.casic.br.model.AddressListModel +import com.pengxh.kt.lite.extensions.dp2px +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeViewHolder + +class AddressListAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater: LayoutInflater = LayoutInflater.from(context) + + private var deleteAction = QMUISwipeAction.ActionBuilder() + .icon(ContextCompat.getDrawable(context, R.drawable.ic_delete_white)) + .textSize(16f.dp2px(context)) + .textColor(Color.WHITE) + .paddingStartEnd(16f.dp2px(context)).text("删除") + .backgroundColor(Color.RED) + .build() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QMUISwipeViewHolder { + val view = layoutInflater.inflate(R.layout.item_address_rv_l, parent, false) + val swipeViewHolder = QMUISwipeViewHolder(view) + swipeViewHolder.addSwipeAction(deleteAction) + return swipeViewHolder + } + + override fun onBindViewHolder(holder: QMUISwipeViewHolder, position: Int) { + //初始化控件 + val userPhoneView: TextView = holder.itemView.findViewById(R.id.userPhoneView) + val detailAddressView: TextView = holder.itemView.findViewById(R.id.detailAddressView) + val updateTimeView: TextView = holder.itemView.findViewById(R.id.updateTimeView) + val editAddressView: ImageView = holder.itemView.findViewById(R.id.editAddressView) + + //绑定数据 + val rowsBean = dataRows[position] + userPhoneView.text = rowsBean.account + detailAddressView.text = rowsBean.detailAddress + updateTimeView.text = rowsBean.updateTime + + editAddressView.setOnClickListener { + clickListener?.onEditButtonClicked(position) + } + } + + override fun getItemCount(): Int = dataRows.size + + private var clickListener: OnItemClickListener? = null + + interface OnItemClickListener { + fun onEditButtonClicked(position: Int) + } + + fun setOnItemClickListener(clickListener: OnItemClickListener?) { + this.clickListener = clickListener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/model/AddressListModel.java b/app/src/main/java/com/casic/br/model/AddressListModel.java new file mode 100644 index 0000000..00251b5 --- /dev/null +++ b/app/src/main/java/com/casic/br/model/AddressListModel.java @@ -0,0 +1,166 @@ +package com.casic.br.model; + +import java.util.List; + +public class AddressListModel { + + private int code; + private DataModel data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String account; + private String area; + private String city; + private String createTime; + private String detailAddress; + private String id; + private String ids; + private String postalCode; + private String province; + private String street; + private String updateTime; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDetailAddress() { + return detailAddress; + } + + public void setDetailAddress(String detailAddress) { + this.detailAddress = detailAddress; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIds() { + return ids; + } + + public void setIds(String ids) { + this.ids = ids; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt new file mode 100644 index 0000000..a4855a4 --- /dev/null +++ b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt @@ -0,0 +1,67 @@ +package com.casic.br.adapter + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.casic.br.R +import com.casic.br.model.AddressListModel +import com.pengxh.kt.lite.extensions.dp2px +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeViewHolder + +class AddressListAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater: LayoutInflater = LayoutInflater.from(context) + + private var deleteAction = QMUISwipeAction.ActionBuilder() + .icon(ContextCompat.getDrawable(context, R.drawable.ic_delete_white)) + .textSize(16f.dp2px(context)) + .textColor(Color.WHITE) + .paddingStartEnd(16f.dp2px(context)).text("删除") + .backgroundColor(Color.RED) + .build() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QMUISwipeViewHolder { + val view = layoutInflater.inflate(R.layout.item_address_rv_l, parent, false) + val swipeViewHolder = QMUISwipeViewHolder(view) + swipeViewHolder.addSwipeAction(deleteAction) + return swipeViewHolder + } + + override fun onBindViewHolder(holder: QMUISwipeViewHolder, position: Int) { + //初始化控件 + val userPhoneView: TextView = holder.itemView.findViewById(R.id.userPhoneView) + val detailAddressView: TextView = holder.itemView.findViewById(R.id.detailAddressView) + val updateTimeView: TextView = holder.itemView.findViewById(R.id.updateTimeView) + val editAddressView: ImageView = holder.itemView.findViewById(R.id.editAddressView) + + //绑定数据 + val rowsBean = dataRows[position] + userPhoneView.text = rowsBean.account + detailAddressView.text = rowsBean.detailAddress + updateTimeView.text = rowsBean.updateTime + + editAddressView.setOnClickListener { + clickListener?.onEditButtonClicked(position) + } + } + + override fun getItemCount(): Int = dataRows.size + + private var clickListener: OnItemClickListener? = null + + interface OnItemClickListener { + fun onEditButtonClicked(position: Int) + } + + fun setOnItemClickListener(clickListener: OnItemClickListener?) { + this.clickListener = clickListener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/model/AddressListModel.java b/app/src/main/java/com/casic/br/model/AddressListModel.java new file mode 100644 index 0000000..00251b5 --- /dev/null +++ b/app/src/main/java/com/casic/br/model/AddressListModel.java @@ -0,0 +1,166 @@ +package com.casic.br.model; + +import java.util.List; + +public class AddressListModel { + + private int code; + private DataModel data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String account; + private String area; + private String city; + private String createTime; + private String detailAddress; + private String id; + private String ids; + private String postalCode; + private String province; + private String street; + private String updateTime; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDetailAddress() { + return detailAddress; + } + + public void setDetailAddress(String detailAddress) { + this.detailAddress = detailAddress; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIds() { + return ids; + } + + public void setIds(String ids) { + this.ids = ids; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt index 83686ce..9f1c93b 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt @@ -43,4 +43,22 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 地址列表 + */ + @POST("/appAddressInfo/listPage") + suspend fun obtainAddressListByPage( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 地址删除 + */ + @POST("/appAddressInfo/delete") + suspend fun deleteAddressById( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt new file mode 100644 index 0000000..a4855a4 --- /dev/null +++ b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt @@ -0,0 +1,67 @@ +package com.casic.br.adapter + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.casic.br.R +import com.casic.br.model.AddressListModel +import com.pengxh.kt.lite.extensions.dp2px +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeViewHolder + +class AddressListAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater: LayoutInflater = LayoutInflater.from(context) + + private var deleteAction = QMUISwipeAction.ActionBuilder() + .icon(ContextCompat.getDrawable(context, R.drawable.ic_delete_white)) + .textSize(16f.dp2px(context)) + .textColor(Color.WHITE) + .paddingStartEnd(16f.dp2px(context)).text("删除") + .backgroundColor(Color.RED) + .build() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QMUISwipeViewHolder { + val view = layoutInflater.inflate(R.layout.item_address_rv_l, parent, false) + val swipeViewHolder = QMUISwipeViewHolder(view) + swipeViewHolder.addSwipeAction(deleteAction) + return swipeViewHolder + } + + override fun onBindViewHolder(holder: QMUISwipeViewHolder, position: Int) { + //初始化控件 + val userPhoneView: TextView = holder.itemView.findViewById(R.id.userPhoneView) + val detailAddressView: TextView = holder.itemView.findViewById(R.id.detailAddressView) + val updateTimeView: TextView = holder.itemView.findViewById(R.id.updateTimeView) + val editAddressView: ImageView = holder.itemView.findViewById(R.id.editAddressView) + + //绑定数据 + val rowsBean = dataRows[position] + userPhoneView.text = rowsBean.account + detailAddressView.text = rowsBean.detailAddress + updateTimeView.text = rowsBean.updateTime + + editAddressView.setOnClickListener { + clickListener?.onEditButtonClicked(position) + } + } + + override fun getItemCount(): Int = dataRows.size + + private var clickListener: OnItemClickListener? = null + + interface OnItemClickListener { + fun onEditButtonClicked(position: Int) + } + + fun setOnItemClickListener(clickListener: OnItemClickListener?) { + this.clickListener = clickListener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/model/AddressListModel.java b/app/src/main/java/com/casic/br/model/AddressListModel.java new file mode 100644 index 0000000..00251b5 --- /dev/null +++ b/app/src/main/java/com/casic/br/model/AddressListModel.java @@ -0,0 +1,166 @@ +package com.casic.br.model; + +import java.util.List; + +public class AddressListModel { + + private int code; + private DataModel data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String account; + private String area; + private String city; + private String createTime; + private String detailAddress; + private String id; + private String ids; + private String postalCode; + private String province; + private String street; + private String updateTime; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDetailAddress() { + return detailAddress; + } + + public void setDetailAddress(String detailAddress) { + this.detailAddress = detailAddress; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIds() { + return ids; + } + + public void setIds(String ids) { + this.ids = ids; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt index 83686ce..9f1c93b 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt @@ -43,4 +43,22 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 地址列表 + */ + @POST("/appAddressInfo/listPage") + suspend fun obtainAddressListByPage( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 地址删除 + */ + @POST("/appAddressInfo/delete") + suspend fun deleteAddressById( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt index 183fb6f..ffb6064 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt @@ -108,4 +108,35 @@ ) return api.addAddress(AuthenticationHelper.token!!, requestBody) } + + /** + * 地址列表 + */ + suspend fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ): String { + val paramObject = JSONObject() + paramObject.put("account", account) + paramObject.put("province", province) + paramObject.put("city", city) + paramObject.put("area", area) + paramObject.put("limit", LocaleConstant.PAGE_LIMIT) + paramObject.put("offset", offset) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.obtainAddressListByPage(AuthenticationHelper.token!!, requestBody) + } + + /** + * 地址删除 + */ + suspend fun deleteAddressById(id: String): String { + val paramObject = JSONObject() + paramObject.put("id", id) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.deleteAddressById(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt new file mode 100644 index 0000000..a4855a4 --- /dev/null +++ b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt @@ -0,0 +1,67 @@ +package com.casic.br.adapter + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.casic.br.R +import com.casic.br.model.AddressListModel +import com.pengxh.kt.lite.extensions.dp2px +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeViewHolder + +class AddressListAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater: LayoutInflater = LayoutInflater.from(context) + + private var deleteAction = QMUISwipeAction.ActionBuilder() + .icon(ContextCompat.getDrawable(context, R.drawable.ic_delete_white)) + .textSize(16f.dp2px(context)) + .textColor(Color.WHITE) + .paddingStartEnd(16f.dp2px(context)).text("删除") + .backgroundColor(Color.RED) + .build() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QMUISwipeViewHolder { + val view = layoutInflater.inflate(R.layout.item_address_rv_l, parent, false) + val swipeViewHolder = QMUISwipeViewHolder(view) + swipeViewHolder.addSwipeAction(deleteAction) + return swipeViewHolder + } + + override fun onBindViewHolder(holder: QMUISwipeViewHolder, position: Int) { + //初始化控件 + val userPhoneView: TextView = holder.itemView.findViewById(R.id.userPhoneView) + val detailAddressView: TextView = holder.itemView.findViewById(R.id.detailAddressView) + val updateTimeView: TextView = holder.itemView.findViewById(R.id.updateTimeView) + val editAddressView: ImageView = holder.itemView.findViewById(R.id.editAddressView) + + //绑定数据 + val rowsBean = dataRows[position] + userPhoneView.text = rowsBean.account + detailAddressView.text = rowsBean.detailAddress + updateTimeView.text = rowsBean.updateTime + + editAddressView.setOnClickListener { + clickListener?.onEditButtonClicked(position) + } + } + + override fun getItemCount(): Int = dataRows.size + + private var clickListener: OnItemClickListener? = null + + interface OnItemClickListener { + fun onEditButtonClicked(position: Int) + } + + fun setOnItemClickListener(clickListener: OnItemClickListener?) { + this.clickListener = clickListener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/model/AddressListModel.java b/app/src/main/java/com/casic/br/model/AddressListModel.java new file mode 100644 index 0000000..00251b5 --- /dev/null +++ b/app/src/main/java/com/casic/br/model/AddressListModel.java @@ -0,0 +1,166 @@ +package com.casic.br.model; + +import java.util.List; + +public class AddressListModel { + + private int code; + private DataModel data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String account; + private String area; + private String city; + private String createTime; + private String detailAddress; + private String id; + private String ids; + private String postalCode; + private String province; + private String street; + private String updateTime; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDetailAddress() { + return detailAddress; + } + + public void setDetailAddress(String detailAddress) { + this.detailAddress = detailAddress; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIds() { + return ids; + } + + public void setIds(String ids) { + this.ids = ids; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt index 83686ce..9f1c93b 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt @@ -43,4 +43,22 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 地址列表 + */ + @POST("/appAddressInfo/listPage") + suspend fun obtainAddressListByPage( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 地址删除 + */ + @POST("/appAddressInfo/delete") + suspend fun deleteAddressById( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt index 183fb6f..ffb6064 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt @@ -108,4 +108,35 @@ ) return api.addAddress(AuthenticationHelper.token!!, requestBody) } + + /** + * 地址列表 + */ + suspend fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ): String { + val paramObject = JSONObject() + paramObject.put("account", account) + paramObject.put("province", province) + paramObject.put("city", city) + paramObject.put("area", area) + paramObject.put("limit", LocaleConstant.PAGE_LIMIT) + paramObject.put("offset", offset) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.obtainAddressListByPage(AuthenticationHelper.token!!, requestBody) + } + + /** + * 地址删除 + */ + suspend fun deleteAddressById(id: String): String { + val paramObject = JSONObject() + paramObject.put("id", id) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.deleteAddressById(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt index 1842b75..ac192c7 100644 --- a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt +++ b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt @@ -1,33 +1,224 @@ package com.casic.br.view +import android.content.Context +import android.os.Handler +import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.casic.br.R +import com.casic.br.adapter.AddressListAdapter +import com.casic.br.model.AddressListModel +import com.casic.br.utils.LoadingDialogHub +import com.casic.br.utils.LocaleConstant +import com.casic.br.vm.AddressViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import kotlinx.android.synthetic.main.activity_manage_address.* import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + class AddressManagerActivity : KotlinBaseActivity() { - override fun initLayoutView(): Int = R.layout.activity_edit_address + private val kTag = "AddressManagerActivity" + private val context: Context = this@AddressManagerActivity + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var addressViewModel: AddressViewModel + private lateinit var addressAdapter: AddressListAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var clickedPosition = 0 + + override fun initLayoutView(): Int = R.layout.activity_manage_address override fun setupTopBarLayout() { ImmersionBar.with(this).statusBarDarkFont(true).init() ImmerseStatusBarUtil.setColor(this, R.color.white.convertColor(this)) leftBackView.setOnClickListener { finish() } - titleView.text = "我的地址" + titleView.text = "地址管理" } override fun initData() { - - } - - override fun observeRequestState() { - + weakReferenceHandler = WeakReferenceHandler(callback) + addressViewModel = ViewModelProvider(this)[AddressViewModel::class.java] } override fun initEvent() { + addressLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + obtainAddressListByPage() + } + addressLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + obtainAddressListByPage() + } + addressViewModel.deleteResult.observe(this, { + if (it.code == 200) { + dataBeans.removeAt(clickedPosition) + addressAdapter.notifyItemRemoved(clickedPosition) + addressAdapter.notifyItemRangeChanged( + clickedPosition, dataBeans.size - clickedPosition + ) + } + }) + + addAddressButton.setOnClickListener { + val isLogin = SaveKeyValues.getValue(LocaleConstant.USER_IS_LOGIN, false) as Boolean + if (isLogin) { + navigatePageTo() + } else { + navigatePageTo() + } + } + } + + override fun onResume() { + super.onResume() + obtainAddressListByPage() + } + + private fun obtainAddressListByPage() { + addressViewModel.obtainAddressListByPage("", "", "", "", pageIndex) + addressViewModel.listModel.observe(this, { + if (it.code == 200) { + val dataRows = it.data?.rows + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows!! + addressLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows?.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows!!) + addressLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows!! + } + } + weakReferenceHandler.sendEmptyMessage(2022100901) + } + }) + } + + private val callback = Handler.Callback { + if (it.what == 2022100901) { + if (isRefresh || isLoadMore) { + addressAdapter.notifyDataSetChanged() + } else { + addressAdapter = AddressListAdapter(this, dataBeans) + //绑定侧滑事件 + swipeAction.attachToRecyclerView(addressRecyclerView) + val linearLayoutManager = object : LinearLayoutManager(this) { + override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams { + return RecyclerView.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + } + } + addressRecyclerView.layoutManager = linearLayoutManager + addressRecyclerView.adapter = addressAdapter + addressAdapter.setOnItemClickListener(object : + AddressListAdapter.OnItemClickListener { + override fun onEditButtonClicked(position: Int) { +// if (dataBeans[position].devcode.isNullOrBlank()) { +// "设备编号为空,无法查看历史数据".show(context) +// return +// } +// navigatePageTo( +// arrayListOf(groupId, dataBeans[position].devcode) +// ) + } + }) + } + } + true + } + + private val swipeAction = + QMUIRVItemSwipeAction(true, object : QMUIRVItemSwipeAction.Callback() { + + //滑动拉出菜单删除 + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + clickedPosition = viewHolder.bindingAdapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + + override fun getSwipeDirection( + recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder + ): Int { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + + //滑动拉出菜单,点击删除 + override fun onClickAction( + swipeAction: QMUIRVItemSwipeAction?, + selected: RecyclerView.ViewHolder?, + action: QMUISwipeAction? + ) { + super.onClickAction(swipeAction, selected, action) + deleteItem(selected!!.bindingAdapterPosition) + } + }) + + private fun deleteItem(adapterPosition: Int) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("删除后将无法恢复,是否继续?") + .setNegativeButton("容我想想") + .setPositiveButton("已经想好") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onCancelClick() { + + } + + override fun onConfirmClick() { + clickedPosition = adapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + }).build().show() + } + + override fun observeRequestState() { + addressViewModel.loadState.observe(this, { + when (it) { + LoadState.Loading -> { + //刷新不显示Loading + if (isRefresh || isLoadMore) { + return@observe + } + LoadingDialogHub.show(this, "数据加载中...") + } + else -> LoadingDialogHub.dismiss() + } + }) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt new file mode 100644 index 0000000..a4855a4 --- /dev/null +++ b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt @@ -0,0 +1,67 @@ +package com.casic.br.adapter + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.casic.br.R +import com.casic.br.model.AddressListModel +import com.pengxh.kt.lite.extensions.dp2px +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeViewHolder + +class AddressListAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater: LayoutInflater = LayoutInflater.from(context) + + private var deleteAction = QMUISwipeAction.ActionBuilder() + .icon(ContextCompat.getDrawable(context, R.drawable.ic_delete_white)) + .textSize(16f.dp2px(context)) + .textColor(Color.WHITE) + .paddingStartEnd(16f.dp2px(context)).text("删除") + .backgroundColor(Color.RED) + .build() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QMUISwipeViewHolder { + val view = layoutInflater.inflate(R.layout.item_address_rv_l, parent, false) + val swipeViewHolder = QMUISwipeViewHolder(view) + swipeViewHolder.addSwipeAction(deleteAction) + return swipeViewHolder + } + + override fun onBindViewHolder(holder: QMUISwipeViewHolder, position: Int) { + //初始化控件 + val userPhoneView: TextView = holder.itemView.findViewById(R.id.userPhoneView) + val detailAddressView: TextView = holder.itemView.findViewById(R.id.detailAddressView) + val updateTimeView: TextView = holder.itemView.findViewById(R.id.updateTimeView) + val editAddressView: ImageView = holder.itemView.findViewById(R.id.editAddressView) + + //绑定数据 + val rowsBean = dataRows[position] + userPhoneView.text = rowsBean.account + detailAddressView.text = rowsBean.detailAddress + updateTimeView.text = rowsBean.updateTime + + editAddressView.setOnClickListener { + clickListener?.onEditButtonClicked(position) + } + } + + override fun getItemCount(): Int = dataRows.size + + private var clickListener: OnItemClickListener? = null + + interface OnItemClickListener { + fun onEditButtonClicked(position: Int) + } + + fun setOnItemClickListener(clickListener: OnItemClickListener?) { + this.clickListener = clickListener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/model/AddressListModel.java b/app/src/main/java/com/casic/br/model/AddressListModel.java new file mode 100644 index 0000000..00251b5 --- /dev/null +++ b/app/src/main/java/com/casic/br/model/AddressListModel.java @@ -0,0 +1,166 @@ +package com.casic.br.model; + +import java.util.List; + +public class AddressListModel { + + private int code; + private DataModel data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String account; + private String area; + private String city; + private String createTime; + private String detailAddress; + private String id; + private String ids; + private String postalCode; + private String province; + private String street; + private String updateTime; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDetailAddress() { + return detailAddress; + } + + public void setDetailAddress(String detailAddress) { + this.detailAddress = detailAddress; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIds() { + return ids; + } + + public void setIds(String ids) { + this.ids = ids; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt index 83686ce..9f1c93b 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt @@ -43,4 +43,22 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 地址列表 + */ + @POST("/appAddressInfo/listPage") + suspend fun obtainAddressListByPage( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 地址删除 + */ + @POST("/appAddressInfo/delete") + suspend fun deleteAddressById( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt index 183fb6f..ffb6064 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt @@ -108,4 +108,35 @@ ) return api.addAddress(AuthenticationHelper.token!!, requestBody) } + + /** + * 地址列表 + */ + suspend fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ): String { + val paramObject = JSONObject() + paramObject.put("account", account) + paramObject.put("province", province) + paramObject.put("city", city) + paramObject.put("area", area) + paramObject.put("limit", LocaleConstant.PAGE_LIMIT) + paramObject.put("offset", offset) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.obtainAddressListByPage(AuthenticationHelper.token!!, requestBody) + } + + /** + * 地址删除 + */ + suspend fun deleteAddressById(id: String): String { + val paramObject = JSONObject() + paramObject.put("id", id) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.deleteAddressById(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt index 1842b75..ac192c7 100644 --- a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt +++ b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt @@ -1,33 +1,224 @@ package com.casic.br.view +import android.content.Context +import android.os.Handler +import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.casic.br.R +import com.casic.br.adapter.AddressListAdapter +import com.casic.br.model.AddressListModel +import com.casic.br.utils.LoadingDialogHub +import com.casic.br.utils.LocaleConstant +import com.casic.br.vm.AddressViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import kotlinx.android.synthetic.main.activity_manage_address.* import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + class AddressManagerActivity : KotlinBaseActivity() { - override fun initLayoutView(): Int = R.layout.activity_edit_address + private val kTag = "AddressManagerActivity" + private val context: Context = this@AddressManagerActivity + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var addressViewModel: AddressViewModel + private lateinit var addressAdapter: AddressListAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var clickedPosition = 0 + + override fun initLayoutView(): Int = R.layout.activity_manage_address override fun setupTopBarLayout() { ImmersionBar.with(this).statusBarDarkFont(true).init() ImmerseStatusBarUtil.setColor(this, R.color.white.convertColor(this)) leftBackView.setOnClickListener { finish() } - titleView.text = "我的地址" + titleView.text = "地址管理" } override fun initData() { - - } - - override fun observeRequestState() { - + weakReferenceHandler = WeakReferenceHandler(callback) + addressViewModel = ViewModelProvider(this)[AddressViewModel::class.java] } override fun initEvent() { + addressLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + obtainAddressListByPage() + } + addressLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + obtainAddressListByPage() + } + addressViewModel.deleteResult.observe(this, { + if (it.code == 200) { + dataBeans.removeAt(clickedPosition) + addressAdapter.notifyItemRemoved(clickedPosition) + addressAdapter.notifyItemRangeChanged( + clickedPosition, dataBeans.size - clickedPosition + ) + } + }) + + addAddressButton.setOnClickListener { + val isLogin = SaveKeyValues.getValue(LocaleConstant.USER_IS_LOGIN, false) as Boolean + if (isLogin) { + navigatePageTo() + } else { + navigatePageTo() + } + } + } + + override fun onResume() { + super.onResume() + obtainAddressListByPage() + } + + private fun obtainAddressListByPage() { + addressViewModel.obtainAddressListByPage("", "", "", "", pageIndex) + addressViewModel.listModel.observe(this, { + if (it.code == 200) { + val dataRows = it.data?.rows + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows!! + addressLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows?.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows!!) + addressLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows!! + } + } + weakReferenceHandler.sendEmptyMessage(2022100901) + } + }) + } + + private val callback = Handler.Callback { + if (it.what == 2022100901) { + if (isRefresh || isLoadMore) { + addressAdapter.notifyDataSetChanged() + } else { + addressAdapter = AddressListAdapter(this, dataBeans) + //绑定侧滑事件 + swipeAction.attachToRecyclerView(addressRecyclerView) + val linearLayoutManager = object : LinearLayoutManager(this) { + override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams { + return RecyclerView.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + } + } + addressRecyclerView.layoutManager = linearLayoutManager + addressRecyclerView.adapter = addressAdapter + addressAdapter.setOnItemClickListener(object : + AddressListAdapter.OnItemClickListener { + override fun onEditButtonClicked(position: Int) { +// if (dataBeans[position].devcode.isNullOrBlank()) { +// "设备编号为空,无法查看历史数据".show(context) +// return +// } +// navigatePageTo( +// arrayListOf(groupId, dataBeans[position].devcode) +// ) + } + }) + } + } + true + } + + private val swipeAction = + QMUIRVItemSwipeAction(true, object : QMUIRVItemSwipeAction.Callback() { + + //滑动拉出菜单删除 + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + clickedPosition = viewHolder.bindingAdapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + + override fun getSwipeDirection( + recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder + ): Int { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + + //滑动拉出菜单,点击删除 + override fun onClickAction( + swipeAction: QMUIRVItemSwipeAction?, + selected: RecyclerView.ViewHolder?, + action: QMUISwipeAction? + ) { + super.onClickAction(swipeAction, selected, action) + deleteItem(selected!!.bindingAdapterPosition) + } + }) + + private fun deleteItem(adapterPosition: Int) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("删除后将无法恢复,是否继续?") + .setNegativeButton("容我想想") + .setPositiveButton("已经想好") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onCancelClick() { + + } + + override fun onConfirmClick() { + clickedPosition = adapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + }).build().show() + } + + override fun observeRequestState() { + addressViewModel.loadState.observe(this, { + when (it) { + LoadState.Loading -> { + //刷新不显示Loading + if (isRefresh || isLoadMore) { + return@observe + } + LoadingDialogHub.show(this, "数据加载中...") + } + else -> LoadingDialogHub.dismiss() + } + }) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt index d86e677..a7aa9ae 100644 --- a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt @@ -1,9 +1,14 @@ package com.casic.br.vm +import androidx.lifecycle.MutableLiveData import com.casic.br.base.BaseApplication import com.casic.br.extensions.separateResponseCode import com.casic.br.extensions.toErrorMessage +import com.casic.br.model.AddressListModel +import com.casic.br.model.CommonResultModel import com.casic.br.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.launch import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.vm.BaseViewModel @@ -11,6 +16,10 @@ class AddressViewModel : BaseViewModel() { + private val gson by lazy { Gson() } + val listModel = MutableLiveData() + val deleteResult = MutableLiveData() + fun addAddress( account: String, province: String, city: String, area: String, street: String, detailAddress: String, @@ -37,4 +46,44 @@ loadState.value = LoadState.Fail it.printStackTrace() }) + + fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.obtainAddressListByPage( + account, province, city, area, offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + listModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) + + fun deleteAddressById(id: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.deleteAddressById(id) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + deleteResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt new file mode 100644 index 0000000..a4855a4 --- /dev/null +++ b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt @@ -0,0 +1,67 @@ +package com.casic.br.adapter + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.casic.br.R +import com.casic.br.model.AddressListModel +import com.pengxh.kt.lite.extensions.dp2px +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeViewHolder + +class AddressListAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater: LayoutInflater = LayoutInflater.from(context) + + private var deleteAction = QMUISwipeAction.ActionBuilder() + .icon(ContextCompat.getDrawable(context, R.drawable.ic_delete_white)) + .textSize(16f.dp2px(context)) + .textColor(Color.WHITE) + .paddingStartEnd(16f.dp2px(context)).text("删除") + .backgroundColor(Color.RED) + .build() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QMUISwipeViewHolder { + val view = layoutInflater.inflate(R.layout.item_address_rv_l, parent, false) + val swipeViewHolder = QMUISwipeViewHolder(view) + swipeViewHolder.addSwipeAction(deleteAction) + return swipeViewHolder + } + + override fun onBindViewHolder(holder: QMUISwipeViewHolder, position: Int) { + //初始化控件 + val userPhoneView: TextView = holder.itemView.findViewById(R.id.userPhoneView) + val detailAddressView: TextView = holder.itemView.findViewById(R.id.detailAddressView) + val updateTimeView: TextView = holder.itemView.findViewById(R.id.updateTimeView) + val editAddressView: ImageView = holder.itemView.findViewById(R.id.editAddressView) + + //绑定数据 + val rowsBean = dataRows[position] + userPhoneView.text = rowsBean.account + detailAddressView.text = rowsBean.detailAddress + updateTimeView.text = rowsBean.updateTime + + editAddressView.setOnClickListener { + clickListener?.onEditButtonClicked(position) + } + } + + override fun getItemCount(): Int = dataRows.size + + private var clickListener: OnItemClickListener? = null + + interface OnItemClickListener { + fun onEditButtonClicked(position: Int) + } + + fun setOnItemClickListener(clickListener: OnItemClickListener?) { + this.clickListener = clickListener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/model/AddressListModel.java b/app/src/main/java/com/casic/br/model/AddressListModel.java new file mode 100644 index 0000000..00251b5 --- /dev/null +++ b/app/src/main/java/com/casic/br/model/AddressListModel.java @@ -0,0 +1,166 @@ +package com.casic.br.model; + +import java.util.List; + +public class AddressListModel { + + private int code; + private DataModel data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String account; + private String area; + private String city; + private String createTime; + private String detailAddress; + private String id; + private String ids; + private String postalCode; + private String province; + private String street; + private String updateTime; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDetailAddress() { + return detailAddress; + } + + public void setDetailAddress(String detailAddress) { + this.detailAddress = detailAddress; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIds() { + return ids; + } + + public void setIds(String ids) { + this.ids = ids; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt index 83686ce..9f1c93b 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt @@ -43,4 +43,22 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 地址列表 + */ + @POST("/appAddressInfo/listPage") + suspend fun obtainAddressListByPage( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 地址删除 + */ + @POST("/appAddressInfo/delete") + suspend fun deleteAddressById( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt index 183fb6f..ffb6064 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt @@ -108,4 +108,35 @@ ) return api.addAddress(AuthenticationHelper.token!!, requestBody) } + + /** + * 地址列表 + */ + suspend fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ): String { + val paramObject = JSONObject() + paramObject.put("account", account) + paramObject.put("province", province) + paramObject.put("city", city) + paramObject.put("area", area) + paramObject.put("limit", LocaleConstant.PAGE_LIMIT) + paramObject.put("offset", offset) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.obtainAddressListByPage(AuthenticationHelper.token!!, requestBody) + } + + /** + * 地址删除 + */ + suspend fun deleteAddressById(id: String): String { + val paramObject = JSONObject() + paramObject.put("id", id) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.deleteAddressById(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt index 1842b75..ac192c7 100644 --- a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt +++ b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt @@ -1,33 +1,224 @@ package com.casic.br.view +import android.content.Context +import android.os.Handler +import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.casic.br.R +import com.casic.br.adapter.AddressListAdapter +import com.casic.br.model.AddressListModel +import com.casic.br.utils.LoadingDialogHub +import com.casic.br.utils.LocaleConstant +import com.casic.br.vm.AddressViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import kotlinx.android.synthetic.main.activity_manage_address.* import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + class AddressManagerActivity : KotlinBaseActivity() { - override fun initLayoutView(): Int = R.layout.activity_edit_address + private val kTag = "AddressManagerActivity" + private val context: Context = this@AddressManagerActivity + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var addressViewModel: AddressViewModel + private lateinit var addressAdapter: AddressListAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var clickedPosition = 0 + + override fun initLayoutView(): Int = R.layout.activity_manage_address override fun setupTopBarLayout() { ImmersionBar.with(this).statusBarDarkFont(true).init() ImmerseStatusBarUtil.setColor(this, R.color.white.convertColor(this)) leftBackView.setOnClickListener { finish() } - titleView.text = "我的地址" + titleView.text = "地址管理" } override fun initData() { - - } - - override fun observeRequestState() { - + weakReferenceHandler = WeakReferenceHandler(callback) + addressViewModel = ViewModelProvider(this)[AddressViewModel::class.java] } override fun initEvent() { + addressLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + obtainAddressListByPage() + } + addressLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + obtainAddressListByPage() + } + addressViewModel.deleteResult.observe(this, { + if (it.code == 200) { + dataBeans.removeAt(clickedPosition) + addressAdapter.notifyItemRemoved(clickedPosition) + addressAdapter.notifyItemRangeChanged( + clickedPosition, dataBeans.size - clickedPosition + ) + } + }) + + addAddressButton.setOnClickListener { + val isLogin = SaveKeyValues.getValue(LocaleConstant.USER_IS_LOGIN, false) as Boolean + if (isLogin) { + navigatePageTo() + } else { + navigatePageTo() + } + } + } + + override fun onResume() { + super.onResume() + obtainAddressListByPage() + } + + private fun obtainAddressListByPage() { + addressViewModel.obtainAddressListByPage("", "", "", "", pageIndex) + addressViewModel.listModel.observe(this, { + if (it.code == 200) { + val dataRows = it.data?.rows + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows!! + addressLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows?.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows!!) + addressLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows!! + } + } + weakReferenceHandler.sendEmptyMessage(2022100901) + } + }) + } + + private val callback = Handler.Callback { + if (it.what == 2022100901) { + if (isRefresh || isLoadMore) { + addressAdapter.notifyDataSetChanged() + } else { + addressAdapter = AddressListAdapter(this, dataBeans) + //绑定侧滑事件 + swipeAction.attachToRecyclerView(addressRecyclerView) + val linearLayoutManager = object : LinearLayoutManager(this) { + override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams { + return RecyclerView.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + } + } + addressRecyclerView.layoutManager = linearLayoutManager + addressRecyclerView.adapter = addressAdapter + addressAdapter.setOnItemClickListener(object : + AddressListAdapter.OnItemClickListener { + override fun onEditButtonClicked(position: Int) { +// if (dataBeans[position].devcode.isNullOrBlank()) { +// "设备编号为空,无法查看历史数据".show(context) +// return +// } +// navigatePageTo( +// arrayListOf(groupId, dataBeans[position].devcode) +// ) + } + }) + } + } + true + } + + private val swipeAction = + QMUIRVItemSwipeAction(true, object : QMUIRVItemSwipeAction.Callback() { + + //滑动拉出菜单删除 + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + clickedPosition = viewHolder.bindingAdapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + + override fun getSwipeDirection( + recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder + ): Int { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + + //滑动拉出菜单,点击删除 + override fun onClickAction( + swipeAction: QMUIRVItemSwipeAction?, + selected: RecyclerView.ViewHolder?, + action: QMUISwipeAction? + ) { + super.onClickAction(swipeAction, selected, action) + deleteItem(selected!!.bindingAdapterPosition) + } + }) + + private fun deleteItem(adapterPosition: Int) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("删除后将无法恢复,是否继续?") + .setNegativeButton("容我想想") + .setPositiveButton("已经想好") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onCancelClick() { + + } + + override fun onConfirmClick() { + clickedPosition = adapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + }).build().show() + } + + override fun observeRequestState() { + addressViewModel.loadState.observe(this, { + when (it) { + LoadState.Loading -> { + //刷新不显示Loading + if (isRefresh || isLoadMore) { + return@observe + } + LoadingDialogHub.show(this, "数据加载中...") + } + else -> LoadingDialogHub.dismiss() + } + }) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt index d86e677..a7aa9ae 100644 --- a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt @@ -1,9 +1,14 @@ package com.casic.br.vm +import androidx.lifecycle.MutableLiveData import com.casic.br.base.BaseApplication import com.casic.br.extensions.separateResponseCode import com.casic.br.extensions.toErrorMessage +import com.casic.br.model.AddressListModel +import com.casic.br.model.CommonResultModel import com.casic.br.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.launch import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.vm.BaseViewModel @@ -11,6 +16,10 @@ class AddressViewModel : BaseViewModel() { + private val gson by lazy { Gson() } + val listModel = MutableLiveData() + val deleteResult = MutableLiveData() + fun addAddress( account: String, province: String, city: String, area: String, street: String, detailAddress: String, @@ -37,4 +46,44 @@ loadState.value = LoadState.Fail it.printStackTrace() }) + + fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.obtainAddressListByPage( + account, province, city, area, offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + listModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) + + fun deleteAddressById(id: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.deleteAddressById(id) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + deleteResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt index 2ecd44e..79316e4 100644 --- a/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt @@ -14,7 +14,7 @@ class AuthenticateViewModel : BaseViewModel() { - private val gson = Gson() + private val gson by lazy { Gson() } val keyModel = MutableLiveData() fun obtainPublicKey() = launch({ diff --git a/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt new file mode 100644 index 0000000..a4855a4 --- /dev/null +++ b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt @@ -0,0 +1,67 @@ +package com.casic.br.adapter + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.casic.br.R +import com.casic.br.model.AddressListModel +import com.pengxh.kt.lite.extensions.dp2px +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeViewHolder + +class AddressListAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater: LayoutInflater = LayoutInflater.from(context) + + private var deleteAction = QMUISwipeAction.ActionBuilder() + .icon(ContextCompat.getDrawable(context, R.drawable.ic_delete_white)) + .textSize(16f.dp2px(context)) + .textColor(Color.WHITE) + .paddingStartEnd(16f.dp2px(context)).text("删除") + .backgroundColor(Color.RED) + .build() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QMUISwipeViewHolder { + val view = layoutInflater.inflate(R.layout.item_address_rv_l, parent, false) + val swipeViewHolder = QMUISwipeViewHolder(view) + swipeViewHolder.addSwipeAction(deleteAction) + return swipeViewHolder + } + + override fun onBindViewHolder(holder: QMUISwipeViewHolder, position: Int) { + //初始化控件 + val userPhoneView: TextView = holder.itemView.findViewById(R.id.userPhoneView) + val detailAddressView: TextView = holder.itemView.findViewById(R.id.detailAddressView) + val updateTimeView: TextView = holder.itemView.findViewById(R.id.updateTimeView) + val editAddressView: ImageView = holder.itemView.findViewById(R.id.editAddressView) + + //绑定数据 + val rowsBean = dataRows[position] + userPhoneView.text = rowsBean.account + detailAddressView.text = rowsBean.detailAddress + updateTimeView.text = rowsBean.updateTime + + editAddressView.setOnClickListener { + clickListener?.onEditButtonClicked(position) + } + } + + override fun getItemCount(): Int = dataRows.size + + private var clickListener: OnItemClickListener? = null + + interface OnItemClickListener { + fun onEditButtonClicked(position: Int) + } + + fun setOnItemClickListener(clickListener: OnItemClickListener?) { + this.clickListener = clickListener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/model/AddressListModel.java b/app/src/main/java/com/casic/br/model/AddressListModel.java new file mode 100644 index 0000000..00251b5 --- /dev/null +++ b/app/src/main/java/com/casic/br/model/AddressListModel.java @@ -0,0 +1,166 @@ +package com.casic.br.model; + +import java.util.List; + +public class AddressListModel { + + private int code; + private DataModel data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String account; + private String area; + private String city; + private String createTime; + private String detailAddress; + private String id; + private String ids; + private String postalCode; + private String province; + private String street; + private String updateTime; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDetailAddress() { + return detailAddress; + } + + public void setDetailAddress(String detailAddress) { + this.detailAddress = detailAddress; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIds() { + return ids; + } + + public void setIds(String ids) { + this.ids = ids; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt index 83686ce..9f1c93b 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt @@ -43,4 +43,22 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 地址列表 + */ + @POST("/appAddressInfo/listPage") + suspend fun obtainAddressListByPage( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 地址删除 + */ + @POST("/appAddressInfo/delete") + suspend fun deleteAddressById( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt index 183fb6f..ffb6064 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt @@ -108,4 +108,35 @@ ) return api.addAddress(AuthenticationHelper.token!!, requestBody) } + + /** + * 地址列表 + */ + suspend fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ): String { + val paramObject = JSONObject() + paramObject.put("account", account) + paramObject.put("province", province) + paramObject.put("city", city) + paramObject.put("area", area) + paramObject.put("limit", LocaleConstant.PAGE_LIMIT) + paramObject.put("offset", offset) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.obtainAddressListByPage(AuthenticationHelper.token!!, requestBody) + } + + /** + * 地址删除 + */ + suspend fun deleteAddressById(id: String): String { + val paramObject = JSONObject() + paramObject.put("id", id) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.deleteAddressById(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt index 1842b75..ac192c7 100644 --- a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt +++ b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt @@ -1,33 +1,224 @@ package com.casic.br.view +import android.content.Context +import android.os.Handler +import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.casic.br.R +import com.casic.br.adapter.AddressListAdapter +import com.casic.br.model.AddressListModel +import com.casic.br.utils.LoadingDialogHub +import com.casic.br.utils.LocaleConstant +import com.casic.br.vm.AddressViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import kotlinx.android.synthetic.main.activity_manage_address.* import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + class AddressManagerActivity : KotlinBaseActivity() { - override fun initLayoutView(): Int = R.layout.activity_edit_address + private val kTag = "AddressManagerActivity" + private val context: Context = this@AddressManagerActivity + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var addressViewModel: AddressViewModel + private lateinit var addressAdapter: AddressListAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var clickedPosition = 0 + + override fun initLayoutView(): Int = R.layout.activity_manage_address override fun setupTopBarLayout() { ImmersionBar.with(this).statusBarDarkFont(true).init() ImmerseStatusBarUtil.setColor(this, R.color.white.convertColor(this)) leftBackView.setOnClickListener { finish() } - titleView.text = "我的地址" + titleView.text = "地址管理" } override fun initData() { - - } - - override fun observeRequestState() { - + weakReferenceHandler = WeakReferenceHandler(callback) + addressViewModel = ViewModelProvider(this)[AddressViewModel::class.java] } override fun initEvent() { + addressLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + obtainAddressListByPage() + } + addressLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + obtainAddressListByPage() + } + addressViewModel.deleteResult.observe(this, { + if (it.code == 200) { + dataBeans.removeAt(clickedPosition) + addressAdapter.notifyItemRemoved(clickedPosition) + addressAdapter.notifyItemRangeChanged( + clickedPosition, dataBeans.size - clickedPosition + ) + } + }) + + addAddressButton.setOnClickListener { + val isLogin = SaveKeyValues.getValue(LocaleConstant.USER_IS_LOGIN, false) as Boolean + if (isLogin) { + navigatePageTo() + } else { + navigatePageTo() + } + } + } + + override fun onResume() { + super.onResume() + obtainAddressListByPage() + } + + private fun obtainAddressListByPage() { + addressViewModel.obtainAddressListByPage("", "", "", "", pageIndex) + addressViewModel.listModel.observe(this, { + if (it.code == 200) { + val dataRows = it.data?.rows + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows!! + addressLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows?.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows!!) + addressLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows!! + } + } + weakReferenceHandler.sendEmptyMessage(2022100901) + } + }) + } + + private val callback = Handler.Callback { + if (it.what == 2022100901) { + if (isRefresh || isLoadMore) { + addressAdapter.notifyDataSetChanged() + } else { + addressAdapter = AddressListAdapter(this, dataBeans) + //绑定侧滑事件 + swipeAction.attachToRecyclerView(addressRecyclerView) + val linearLayoutManager = object : LinearLayoutManager(this) { + override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams { + return RecyclerView.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + } + } + addressRecyclerView.layoutManager = linearLayoutManager + addressRecyclerView.adapter = addressAdapter + addressAdapter.setOnItemClickListener(object : + AddressListAdapter.OnItemClickListener { + override fun onEditButtonClicked(position: Int) { +// if (dataBeans[position].devcode.isNullOrBlank()) { +// "设备编号为空,无法查看历史数据".show(context) +// return +// } +// navigatePageTo( +// arrayListOf(groupId, dataBeans[position].devcode) +// ) + } + }) + } + } + true + } + + private val swipeAction = + QMUIRVItemSwipeAction(true, object : QMUIRVItemSwipeAction.Callback() { + + //滑动拉出菜单删除 + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + clickedPosition = viewHolder.bindingAdapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + + override fun getSwipeDirection( + recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder + ): Int { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + + //滑动拉出菜单,点击删除 + override fun onClickAction( + swipeAction: QMUIRVItemSwipeAction?, + selected: RecyclerView.ViewHolder?, + action: QMUISwipeAction? + ) { + super.onClickAction(swipeAction, selected, action) + deleteItem(selected!!.bindingAdapterPosition) + } + }) + + private fun deleteItem(adapterPosition: Int) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("删除后将无法恢复,是否继续?") + .setNegativeButton("容我想想") + .setPositiveButton("已经想好") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onCancelClick() { + + } + + override fun onConfirmClick() { + clickedPosition = adapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + }).build().show() + } + + override fun observeRequestState() { + addressViewModel.loadState.observe(this, { + when (it) { + LoadState.Loading -> { + //刷新不显示Loading + if (isRefresh || isLoadMore) { + return@observe + } + LoadingDialogHub.show(this, "数据加载中...") + } + else -> LoadingDialogHub.dismiss() + } + }) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt index d86e677..a7aa9ae 100644 --- a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt @@ -1,9 +1,14 @@ package com.casic.br.vm +import androidx.lifecycle.MutableLiveData import com.casic.br.base.BaseApplication import com.casic.br.extensions.separateResponseCode import com.casic.br.extensions.toErrorMessage +import com.casic.br.model.AddressListModel +import com.casic.br.model.CommonResultModel import com.casic.br.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.launch import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.vm.BaseViewModel @@ -11,6 +16,10 @@ class AddressViewModel : BaseViewModel() { + private val gson by lazy { Gson() } + val listModel = MutableLiveData() + val deleteResult = MutableLiveData() + fun addAddress( account: String, province: String, city: String, area: String, street: String, detailAddress: String, @@ -37,4 +46,44 @@ loadState.value = LoadState.Fail it.printStackTrace() }) + + fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.obtainAddressListByPage( + account, province, city, area, offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + listModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) + + fun deleteAddressById(id: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.deleteAddressById(id) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + deleteResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt index 2ecd44e..79316e4 100644 --- a/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt @@ -14,7 +14,7 @@ class AuthenticateViewModel : BaseViewModel() { - private val gson = Gson() + private val gson by lazy { Gson() } val keyModel = MutableLiveData() fun obtainPublicKey() = launch({ diff --git a/app/src/main/java/com/casic/br/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/vm/UserViewModel.kt index 579daaf..feb0db2 100644 --- a/app/src/main/java/com/casic/br/vm/UserViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/UserViewModel.kt @@ -16,7 +16,7 @@ class UserViewModel : BaseViewModel() { - private val gson = Gson() + private val gson by lazy { Gson() } val registerResult = MutableLiveData() val loginResult = MutableLiveData() diff --git a/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt new file mode 100644 index 0000000..a4855a4 --- /dev/null +++ b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt @@ -0,0 +1,67 @@ +package com.casic.br.adapter + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.casic.br.R +import com.casic.br.model.AddressListModel +import com.pengxh.kt.lite.extensions.dp2px +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeViewHolder + +class AddressListAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater: LayoutInflater = LayoutInflater.from(context) + + private var deleteAction = QMUISwipeAction.ActionBuilder() + .icon(ContextCompat.getDrawable(context, R.drawable.ic_delete_white)) + .textSize(16f.dp2px(context)) + .textColor(Color.WHITE) + .paddingStartEnd(16f.dp2px(context)).text("删除") + .backgroundColor(Color.RED) + .build() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QMUISwipeViewHolder { + val view = layoutInflater.inflate(R.layout.item_address_rv_l, parent, false) + val swipeViewHolder = QMUISwipeViewHolder(view) + swipeViewHolder.addSwipeAction(deleteAction) + return swipeViewHolder + } + + override fun onBindViewHolder(holder: QMUISwipeViewHolder, position: Int) { + //初始化控件 + val userPhoneView: TextView = holder.itemView.findViewById(R.id.userPhoneView) + val detailAddressView: TextView = holder.itemView.findViewById(R.id.detailAddressView) + val updateTimeView: TextView = holder.itemView.findViewById(R.id.updateTimeView) + val editAddressView: ImageView = holder.itemView.findViewById(R.id.editAddressView) + + //绑定数据 + val rowsBean = dataRows[position] + userPhoneView.text = rowsBean.account + detailAddressView.text = rowsBean.detailAddress + updateTimeView.text = rowsBean.updateTime + + editAddressView.setOnClickListener { + clickListener?.onEditButtonClicked(position) + } + } + + override fun getItemCount(): Int = dataRows.size + + private var clickListener: OnItemClickListener? = null + + interface OnItemClickListener { + fun onEditButtonClicked(position: Int) + } + + fun setOnItemClickListener(clickListener: OnItemClickListener?) { + this.clickListener = clickListener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/model/AddressListModel.java b/app/src/main/java/com/casic/br/model/AddressListModel.java new file mode 100644 index 0000000..00251b5 --- /dev/null +++ b/app/src/main/java/com/casic/br/model/AddressListModel.java @@ -0,0 +1,166 @@ +package com.casic.br.model; + +import java.util.List; + +public class AddressListModel { + + private int code; + private DataModel data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String account; + private String area; + private String city; + private String createTime; + private String detailAddress; + private String id; + private String ids; + private String postalCode; + private String province; + private String street; + private String updateTime; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDetailAddress() { + return detailAddress; + } + + public void setDetailAddress(String detailAddress) { + this.detailAddress = detailAddress; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIds() { + return ids; + } + + public void setIds(String ids) { + this.ids = ids; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt index 83686ce..9f1c93b 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt @@ -43,4 +43,22 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 地址列表 + */ + @POST("/appAddressInfo/listPage") + suspend fun obtainAddressListByPage( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 地址删除 + */ + @POST("/appAddressInfo/delete") + suspend fun deleteAddressById( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt index 183fb6f..ffb6064 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt @@ -108,4 +108,35 @@ ) return api.addAddress(AuthenticationHelper.token!!, requestBody) } + + /** + * 地址列表 + */ + suspend fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ): String { + val paramObject = JSONObject() + paramObject.put("account", account) + paramObject.put("province", province) + paramObject.put("city", city) + paramObject.put("area", area) + paramObject.put("limit", LocaleConstant.PAGE_LIMIT) + paramObject.put("offset", offset) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.obtainAddressListByPage(AuthenticationHelper.token!!, requestBody) + } + + /** + * 地址删除 + */ + suspend fun deleteAddressById(id: String): String { + val paramObject = JSONObject() + paramObject.put("id", id) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.deleteAddressById(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt index 1842b75..ac192c7 100644 --- a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt +++ b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt @@ -1,33 +1,224 @@ package com.casic.br.view +import android.content.Context +import android.os.Handler +import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.casic.br.R +import com.casic.br.adapter.AddressListAdapter +import com.casic.br.model.AddressListModel +import com.casic.br.utils.LoadingDialogHub +import com.casic.br.utils.LocaleConstant +import com.casic.br.vm.AddressViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import kotlinx.android.synthetic.main.activity_manage_address.* import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + class AddressManagerActivity : KotlinBaseActivity() { - override fun initLayoutView(): Int = R.layout.activity_edit_address + private val kTag = "AddressManagerActivity" + private val context: Context = this@AddressManagerActivity + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var addressViewModel: AddressViewModel + private lateinit var addressAdapter: AddressListAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var clickedPosition = 0 + + override fun initLayoutView(): Int = R.layout.activity_manage_address override fun setupTopBarLayout() { ImmersionBar.with(this).statusBarDarkFont(true).init() ImmerseStatusBarUtil.setColor(this, R.color.white.convertColor(this)) leftBackView.setOnClickListener { finish() } - titleView.text = "我的地址" + titleView.text = "地址管理" } override fun initData() { - - } - - override fun observeRequestState() { - + weakReferenceHandler = WeakReferenceHandler(callback) + addressViewModel = ViewModelProvider(this)[AddressViewModel::class.java] } override fun initEvent() { + addressLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + obtainAddressListByPage() + } + addressLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + obtainAddressListByPage() + } + addressViewModel.deleteResult.observe(this, { + if (it.code == 200) { + dataBeans.removeAt(clickedPosition) + addressAdapter.notifyItemRemoved(clickedPosition) + addressAdapter.notifyItemRangeChanged( + clickedPosition, dataBeans.size - clickedPosition + ) + } + }) + + addAddressButton.setOnClickListener { + val isLogin = SaveKeyValues.getValue(LocaleConstant.USER_IS_LOGIN, false) as Boolean + if (isLogin) { + navigatePageTo() + } else { + navigatePageTo() + } + } + } + + override fun onResume() { + super.onResume() + obtainAddressListByPage() + } + + private fun obtainAddressListByPage() { + addressViewModel.obtainAddressListByPage("", "", "", "", pageIndex) + addressViewModel.listModel.observe(this, { + if (it.code == 200) { + val dataRows = it.data?.rows + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows!! + addressLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows?.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows!!) + addressLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows!! + } + } + weakReferenceHandler.sendEmptyMessage(2022100901) + } + }) + } + + private val callback = Handler.Callback { + if (it.what == 2022100901) { + if (isRefresh || isLoadMore) { + addressAdapter.notifyDataSetChanged() + } else { + addressAdapter = AddressListAdapter(this, dataBeans) + //绑定侧滑事件 + swipeAction.attachToRecyclerView(addressRecyclerView) + val linearLayoutManager = object : LinearLayoutManager(this) { + override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams { + return RecyclerView.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + } + } + addressRecyclerView.layoutManager = linearLayoutManager + addressRecyclerView.adapter = addressAdapter + addressAdapter.setOnItemClickListener(object : + AddressListAdapter.OnItemClickListener { + override fun onEditButtonClicked(position: Int) { +// if (dataBeans[position].devcode.isNullOrBlank()) { +// "设备编号为空,无法查看历史数据".show(context) +// return +// } +// navigatePageTo( +// arrayListOf(groupId, dataBeans[position].devcode) +// ) + } + }) + } + } + true + } + + private val swipeAction = + QMUIRVItemSwipeAction(true, object : QMUIRVItemSwipeAction.Callback() { + + //滑动拉出菜单删除 + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + clickedPosition = viewHolder.bindingAdapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + + override fun getSwipeDirection( + recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder + ): Int { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + + //滑动拉出菜单,点击删除 + override fun onClickAction( + swipeAction: QMUIRVItemSwipeAction?, + selected: RecyclerView.ViewHolder?, + action: QMUISwipeAction? + ) { + super.onClickAction(swipeAction, selected, action) + deleteItem(selected!!.bindingAdapterPosition) + } + }) + + private fun deleteItem(adapterPosition: Int) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("删除后将无法恢复,是否继续?") + .setNegativeButton("容我想想") + .setPositiveButton("已经想好") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onCancelClick() { + + } + + override fun onConfirmClick() { + clickedPosition = adapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + }).build().show() + } + + override fun observeRequestState() { + addressViewModel.loadState.observe(this, { + when (it) { + LoadState.Loading -> { + //刷新不显示Loading + if (isRefresh || isLoadMore) { + return@observe + } + LoadingDialogHub.show(this, "数据加载中...") + } + else -> LoadingDialogHub.dismiss() + } + }) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt index d86e677..a7aa9ae 100644 --- a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt @@ -1,9 +1,14 @@ package com.casic.br.vm +import androidx.lifecycle.MutableLiveData import com.casic.br.base.BaseApplication import com.casic.br.extensions.separateResponseCode import com.casic.br.extensions.toErrorMessage +import com.casic.br.model.AddressListModel +import com.casic.br.model.CommonResultModel import com.casic.br.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.launch import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.vm.BaseViewModel @@ -11,6 +16,10 @@ class AddressViewModel : BaseViewModel() { + private val gson by lazy { Gson() } + val listModel = MutableLiveData() + val deleteResult = MutableLiveData() + fun addAddress( account: String, province: String, city: String, area: String, street: String, detailAddress: String, @@ -37,4 +46,44 @@ loadState.value = LoadState.Fail it.printStackTrace() }) + + fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.obtainAddressListByPage( + account, province, city, area, offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + listModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) + + fun deleteAddressById(id: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.deleteAddressById(id) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + deleteResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt index 2ecd44e..79316e4 100644 --- a/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt @@ -14,7 +14,7 @@ class AuthenticateViewModel : BaseViewModel() { - private val gson = Gson() + private val gson by lazy { Gson() } val keyModel = MutableLiveData() fun obtainPublicKey() = launch({ diff --git a/app/src/main/java/com/casic/br/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/vm/UserViewModel.kt index 579daaf..feb0db2 100644 --- a/app/src/main/java/com/casic/br/vm/UserViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/UserViewModel.kt @@ -16,7 +16,7 @@ class UserViewModel : BaseViewModel() { - private val gson = Gson() + private val gson by lazy { Gson() } val registerResult = MutableLiveData() val loginResult = MutableLiveData() diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_7.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_7.xml new file mode 100644 index 0000000..8c2683e --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_7.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt new file mode 100644 index 0000000..a4855a4 --- /dev/null +++ b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt @@ -0,0 +1,67 @@ +package com.casic.br.adapter + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.casic.br.R +import com.casic.br.model.AddressListModel +import com.pengxh.kt.lite.extensions.dp2px +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeViewHolder + +class AddressListAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater: LayoutInflater = LayoutInflater.from(context) + + private var deleteAction = QMUISwipeAction.ActionBuilder() + .icon(ContextCompat.getDrawable(context, R.drawable.ic_delete_white)) + .textSize(16f.dp2px(context)) + .textColor(Color.WHITE) + .paddingStartEnd(16f.dp2px(context)).text("删除") + .backgroundColor(Color.RED) + .build() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QMUISwipeViewHolder { + val view = layoutInflater.inflate(R.layout.item_address_rv_l, parent, false) + val swipeViewHolder = QMUISwipeViewHolder(view) + swipeViewHolder.addSwipeAction(deleteAction) + return swipeViewHolder + } + + override fun onBindViewHolder(holder: QMUISwipeViewHolder, position: Int) { + //初始化控件 + val userPhoneView: TextView = holder.itemView.findViewById(R.id.userPhoneView) + val detailAddressView: TextView = holder.itemView.findViewById(R.id.detailAddressView) + val updateTimeView: TextView = holder.itemView.findViewById(R.id.updateTimeView) + val editAddressView: ImageView = holder.itemView.findViewById(R.id.editAddressView) + + //绑定数据 + val rowsBean = dataRows[position] + userPhoneView.text = rowsBean.account + detailAddressView.text = rowsBean.detailAddress + updateTimeView.text = rowsBean.updateTime + + editAddressView.setOnClickListener { + clickListener?.onEditButtonClicked(position) + } + } + + override fun getItemCount(): Int = dataRows.size + + private var clickListener: OnItemClickListener? = null + + interface OnItemClickListener { + fun onEditButtonClicked(position: Int) + } + + fun setOnItemClickListener(clickListener: OnItemClickListener?) { + this.clickListener = clickListener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/model/AddressListModel.java b/app/src/main/java/com/casic/br/model/AddressListModel.java new file mode 100644 index 0000000..00251b5 --- /dev/null +++ b/app/src/main/java/com/casic/br/model/AddressListModel.java @@ -0,0 +1,166 @@ +package com.casic.br.model; + +import java.util.List; + +public class AddressListModel { + + private int code; + private DataModel data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String account; + private String area; + private String city; + private String createTime; + private String detailAddress; + private String id; + private String ids; + private String postalCode; + private String province; + private String street; + private String updateTime; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDetailAddress() { + return detailAddress; + } + + public void setDetailAddress(String detailAddress) { + this.detailAddress = detailAddress; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIds() { + return ids; + } + + public void setIds(String ids) { + this.ids = ids; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt index 83686ce..9f1c93b 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt @@ -43,4 +43,22 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 地址列表 + */ + @POST("/appAddressInfo/listPage") + suspend fun obtainAddressListByPage( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 地址删除 + */ + @POST("/appAddressInfo/delete") + suspend fun deleteAddressById( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt index 183fb6f..ffb6064 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt @@ -108,4 +108,35 @@ ) return api.addAddress(AuthenticationHelper.token!!, requestBody) } + + /** + * 地址列表 + */ + suspend fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ): String { + val paramObject = JSONObject() + paramObject.put("account", account) + paramObject.put("province", province) + paramObject.put("city", city) + paramObject.put("area", area) + paramObject.put("limit", LocaleConstant.PAGE_LIMIT) + paramObject.put("offset", offset) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.obtainAddressListByPage(AuthenticationHelper.token!!, requestBody) + } + + /** + * 地址删除 + */ + suspend fun deleteAddressById(id: String): String { + val paramObject = JSONObject() + paramObject.put("id", id) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.deleteAddressById(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt index 1842b75..ac192c7 100644 --- a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt +++ b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt @@ -1,33 +1,224 @@ package com.casic.br.view +import android.content.Context +import android.os.Handler +import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.casic.br.R +import com.casic.br.adapter.AddressListAdapter +import com.casic.br.model.AddressListModel +import com.casic.br.utils.LoadingDialogHub +import com.casic.br.utils.LocaleConstant +import com.casic.br.vm.AddressViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import kotlinx.android.synthetic.main.activity_manage_address.* import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + class AddressManagerActivity : KotlinBaseActivity() { - override fun initLayoutView(): Int = R.layout.activity_edit_address + private val kTag = "AddressManagerActivity" + private val context: Context = this@AddressManagerActivity + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var addressViewModel: AddressViewModel + private lateinit var addressAdapter: AddressListAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var clickedPosition = 0 + + override fun initLayoutView(): Int = R.layout.activity_manage_address override fun setupTopBarLayout() { ImmersionBar.with(this).statusBarDarkFont(true).init() ImmerseStatusBarUtil.setColor(this, R.color.white.convertColor(this)) leftBackView.setOnClickListener { finish() } - titleView.text = "我的地址" + titleView.text = "地址管理" } override fun initData() { - - } - - override fun observeRequestState() { - + weakReferenceHandler = WeakReferenceHandler(callback) + addressViewModel = ViewModelProvider(this)[AddressViewModel::class.java] } override fun initEvent() { + addressLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + obtainAddressListByPage() + } + addressLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + obtainAddressListByPage() + } + addressViewModel.deleteResult.observe(this, { + if (it.code == 200) { + dataBeans.removeAt(clickedPosition) + addressAdapter.notifyItemRemoved(clickedPosition) + addressAdapter.notifyItemRangeChanged( + clickedPosition, dataBeans.size - clickedPosition + ) + } + }) + + addAddressButton.setOnClickListener { + val isLogin = SaveKeyValues.getValue(LocaleConstant.USER_IS_LOGIN, false) as Boolean + if (isLogin) { + navigatePageTo() + } else { + navigatePageTo() + } + } + } + + override fun onResume() { + super.onResume() + obtainAddressListByPage() + } + + private fun obtainAddressListByPage() { + addressViewModel.obtainAddressListByPage("", "", "", "", pageIndex) + addressViewModel.listModel.observe(this, { + if (it.code == 200) { + val dataRows = it.data?.rows + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows!! + addressLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows?.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows!!) + addressLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows!! + } + } + weakReferenceHandler.sendEmptyMessage(2022100901) + } + }) + } + + private val callback = Handler.Callback { + if (it.what == 2022100901) { + if (isRefresh || isLoadMore) { + addressAdapter.notifyDataSetChanged() + } else { + addressAdapter = AddressListAdapter(this, dataBeans) + //绑定侧滑事件 + swipeAction.attachToRecyclerView(addressRecyclerView) + val linearLayoutManager = object : LinearLayoutManager(this) { + override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams { + return RecyclerView.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + } + } + addressRecyclerView.layoutManager = linearLayoutManager + addressRecyclerView.adapter = addressAdapter + addressAdapter.setOnItemClickListener(object : + AddressListAdapter.OnItemClickListener { + override fun onEditButtonClicked(position: Int) { +// if (dataBeans[position].devcode.isNullOrBlank()) { +// "设备编号为空,无法查看历史数据".show(context) +// return +// } +// navigatePageTo( +// arrayListOf(groupId, dataBeans[position].devcode) +// ) + } + }) + } + } + true + } + + private val swipeAction = + QMUIRVItemSwipeAction(true, object : QMUIRVItemSwipeAction.Callback() { + + //滑动拉出菜单删除 + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + clickedPosition = viewHolder.bindingAdapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + + override fun getSwipeDirection( + recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder + ): Int { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + + //滑动拉出菜单,点击删除 + override fun onClickAction( + swipeAction: QMUIRVItemSwipeAction?, + selected: RecyclerView.ViewHolder?, + action: QMUISwipeAction? + ) { + super.onClickAction(swipeAction, selected, action) + deleteItem(selected!!.bindingAdapterPosition) + } + }) + + private fun deleteItem(adapterPosition: Int) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("删除后将无法恢复,是否继续?") + .setNegativeButton("容我想想") + .setPositiveButton("已经想好") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onCancelClick() { + + } + + override fun onConfirmClick() { + clickedPosition = adapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + }).build().show() + } + + override fun observeRequestState() { + addressViewModel.loadState.observe(this, { + when (it) { + LoadState.Loading -> { + //刷新不显示Loading + if (isRefresh || isLoadMore) { + return@observe + } + LoadingDialogHub.show(this, "数据加载中...") + } + else -> LoadingDialogHub.dismiss() + } + }) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt index d86e677..a7aa9ae 100644 --- a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt @@ -1,9 +1,14 @@ package com.casic.br.vm +import androidx.lifecycle.MutableLiveData import com.casic.br.base.BaseApplication import com.casic.br.extensions.separateResponseCode import com.casic.br.extensions.toErrorMessage +import com.casic.br.model.AddressListModel +import com.casic.br.model.CommonResultModel import com.casic.br.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.launch import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.vm.BaseViewModel @@ -11,6 +16,10 @@ class AddressViewModel : BaseViewModel() { + private val gson by lazy { Gson() } + val listModel = MutableLiveData() + val deleteResult = MutableLiveData() + fun addAddress( account: String, province: String, city: String, area: String, street: String, detailAddress: String, @@ -37,4 +46,44 @@ loadState.value = LoadState.Fail it.printStackTrace() }) + + fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.obtainAddressListByPage( + account, province, city, area, offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + listModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) + + fun deleteAddressById(id: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.deleteAddressById(id) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + deleteResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt index 2ecd44e..79316e4 100644 --- a/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt @@ -14,7 +14,7 @@ class AuthenticateViewModel : BaseViewModel() { - private val gson = Gson() + private val gson by lazy { Gson() } val keyModel = MutableLiveData() fun obtainPublicKey() = launch({ diff --git a/app/src/main/java/com/casic/br/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/vm/UserViewModel.kt index 579daaf..feb0db2 100644 --- a/app/src/main/java/com/casic/br/vm/UserViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/UserViewModel.kt @@ -16,7 +16,7 @@ class UserViewModel : BaseViewModel() { - private val gson = Gson() + private val gson by lazy { Gson() } val registerResult = MutableLiveData() val loginResult = MutableLiveData() diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_7.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_7.xml new file mode 100644 index 0000000..8c2683e --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_7.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..a75af6c --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt new file mode 100644 index 0000000..a4855a4 --- /dev/null +++ b/app/src/main/java/com/casic/br/adapter/AddressListAdapter.kt @@ -0,0 +1,67 @@ +package com.casic.br.adapter + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.casic.br.R +import com.casic.br.model.AddressListModel +import com.pengxh.kt.lite.extensions.dp2px +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeViewHolder + +class AddressListAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater: LayoutInflater = LayoutInflater.from(context) + + private var deleteAction = QMUISwipeAction.ActionBuilder() + .icon(ContextCompat.getDrawable(context, R.drawable.ic_delete_white)) + .textSize(16f.dp2px(context)) + .textColor(Color.WHITE) + .paddingStartEnd(16f.dp2px(context)).text("删除") + .backgroundColor(Color.RED) + .build() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QMUISwipeViewHolder { + val view = layoutInflater.inflate(R.layout.item_address_rv_l, parent, false) + val swipeViewHolder = QMUISwipeViewHolder(view) + swipeViewHolder.addSwipeAction(deleteAction) + return swipeViewHolder + } + + override fun onBindViewHolder(holder: QMUISwipeViewHolder, position: Int) { + //初始化控件 + val userPhoneView: TextView = holder.itemView.findViewById(R.id.userPhoneView) + val detailAddressView: TextView = holder.itemView.findViewById(R.id.detailAddressView) + val updateTimeView: TextView = holder.itemView.findViewById(R.id.updateTimeView) + val editAddressView: ImageView = holder.itemView.findViewById(R.id.editAddressView) + + //绑定数据 + val rowsBean = dataRows[position] + userPhoneView.text = rowsBean.account + detailAddressView.text = rowsBean.detailAddress + updateTimeView.text = rowsBean.updateTime + + editAddressView.setOnClickListener { + clickListener?.onEditButtonClicked(position) + } + } + + override fun getItemCount(): Int = dataRows.size + + private var clickListener: OnItemClickListener? = null + + interface OnItemClickListener { + fun onEditButtonClicked(position: Int) + } + + fun setOnItemClickListener(clickListener: OnItemClickListener?) { + this.clickListener = clickListener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/model/AddressListModel.java b/app/src/main/java/com/casic/br/model/AddressListModel.java new file mode 100644 index 0000000..00251b5 --- /dev/null +++ b/app/src/main/java/com/casic/br/model/AddressListModel.java @@ -0,0 +1,166 @@ +package com.casic.br.model; + +import java.util.List; + +public class AddressListModel { + + private int code; + private DataModel data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String account; + private String area; + private String city; + private String createTime; + private String detailAddress; + private String id; + private String ids; + private String postalCode; + private String province; + private String street; + private String updateTime; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDetailAddress() { + return detailAddress; + } + + public void setDetailAddress(String detailAddress) { + this.detailAddress = detailAddress; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIds() { + return ids; + } + + public void setIds(String ids) { + this.ids = ids; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt index 83686ce..9f1c93b 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt @@ -43,4 +43,22 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 地址列表 + */ + @POST("/appAddressInfo/listPage") + suspend fun obtainAddressListByPage( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 地址删除 + */ + @POST("/appAddressInfo/delete") + suspend fun deleteAddressById( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt index 183fb6f..ffb6064 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt @@ -108,4 +108,35 @@ ) return api.addAddress(AuthenticationHelper.token!!, requestBody) } + + /** + * 地址列表 + */ + suspend fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ): String { + val paramObject = JSONObject() + paramObject.put("account", account) + paramObject.put("province", province) + paramObject.put("city", city) + paramObject.put("area", area) + paramObject.put("limit", LocaleConstant.PAGE_LIMIT) + paramObject.put("offset", offset) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.obtainAddressListByPage(AuthenticationHelper.token!!, requestBody) + } + + /** + * 地址删除 + */ + suspend fun deleteAddressById(id: String): String { + val paramObject = JSONObject() + paramObject.put("id", id) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.deleteAddressById(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt index 1842b75..ac192c7 100644 --- a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt +++ b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt @@ -1,33 +1,224 @@ package com.casic.br.view +import android.content.Context +import android.os.Handler +import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.casic.br.R +import com.casic.br.adapter.AddressListAdapter +import com.casic.br.model.AddressListModel +import com.casic.br.utils.LoadingDialogHub +import com.casic.br.utils.LocaleConstant +import com.casic.br.vm.AddressViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import kotlinx.android.synthetic.main.activity_manage_address.* import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + class AddressManagerActivity : KotlinBaseActivity() { - override fun initLayoutView(): Int = R.layout.activity_edit_address + private val kTag = "AddressManagerActivity" + private val context: Context = this@AddressManagerActivity + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var addressViewModel: AddressViewModel + private lateinit var addressAdapter: AddressListAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var clickedPosition = 0 + + override fun initLayoutView(): Int = R.layout.activity_manage_address override fun setupTopBarLayout() { ImmersionBar.with(this).statusBarDarkFont(true).init() ImmerseStatusBarUtil.setColor(this, R.color.white.convertColor(this)) leftBackView.setOnClickListener { finish() } - titleView.text = "我的地址" + titleView.text = "地址管理" } override fun initData() { - - } - - override fun observeRequestState() { - + weakReferenceHandler = WeakReferenceHandler(callback) + addressViewModel = ViewModelProvider(this)[AddressViewModel::class.java] } override fun initEvent() { + addressLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + obtainAddressListByPage() + } + addressLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + obtainAddressListByPage() + } + addressViewModel.deleteResult.observe(this, { + if (it.code == 200) { + dataBeans.removeAt(clickedPosition) + addressAdapter.notifyItemRemoved(clickedPosition) + addressAdapter.notifyItemRangeChanged( + clickedPosition, dataBeans.size - clickedPosition + ) + } + }) + + addAddressButton.setOnClickListener { + val isLogin = SaveKeyValues.getValue(LocaleConstant.USER_IS_LOGIN, false) as Boolean + if (isLogin) { + navigatePageTo() + } else { + navigatePageTo() + } + } + } + + override fun onResume() { + super.onResume() + obtainAddressListByPage() + } + + private fun obtainAddressListByPage() { + addressViewModel.obtainAddressListByPage("", "", "", "", pageIndex) + addressViewModel.listModel.observe(this, { + if (it.code == 200) { + val dataRows = it.data?.rows + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows!! + addressLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows?.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows!!) + addressLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows!! + } + } + weakReferenceHandler.sendEmptyMessage(2022100901) + } + }) + } + + private val callback = Handler.Callback { + if (it.what == 2022100901) { + if (isRefresh || isLoadMore) { + addressAdapter.notifyDataSetChanged() + } else { + addressAdapter = AddressListAdapter(this, dataBeans) + //绑定侧滑事件 + swipeAction.attachToRecyclerView(addressRecyclerView) + val linearLayoutManager = object : LinearLayoutManager(this) { + override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams { + return RecyclerView.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + } + } + addressRecyclerView.layoutManager = linearLayoutManager + addressRecyclerView.adapter = addressAdapter + addressAdapter.setOnItemClickListener(object : + AddressListAdapter.OnItemClickListener { + override fun onEditButtonClicked(position: Int) { +// if (dataBeans[position].devcode.isNullOrBlank()) { +// "设备编号为空,无法查看历史数据".show(context) +// return +// } +// navigatePageTo( +// arrayListOf(groupId, dataBeans[position].devcode) +// ) + } + }) + } + } + true + } + + private val swipeAction = + QMUIRVItemSwipeAction(true, object : QMUIRVItemSwipeAction.Callback() { + + //滑动拉出菜单删除 + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + clickedPosition = viewHolder.bindingAdapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + + override fun getSwipeDirection( + recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder + ): Int { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + + //滑动拉出菜单,点击删除 + override fun onClickAction( + swipeAction: QMUIRVItemSwipeAction?, + selected: RecyclerView.ViewHolder?, + action: QMUISwipeAction? + ) { + super.onClickAction(swipeAction, selected, action) + deleteItem(selected!!.bindingAdapterPosition) + } + }) + + private fun deleteItem(adapterPosition: Int) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("删除后将无法恢复,是否继续?") + .setNegativeButton("容我想想") + .setPositiveButton("已经想好") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onCancelClick() { + + } + + override fun onConfirmClick() { + clickedPosition = adapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + }).build().show() + } + + override fun observeRequestState() { + addressViewModel.loadState.observe(this, { + when (it) { + LoadState.Loading -> { + //刷新不显示Loading + if (isRefresh || isLoadMore) { + return@observe + } + LoadingDialogHub.show(this, "数据加载中...") + } + else -> LoadingDialogHub.dismiss() + } + }) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt index d86e677..a7aa9ae 100644 --- a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt @@ -1,9 +1,14 @@ package com.casic.br.vm +import androidx.lifecycle.MutableLiveData import com.casic.br.base.BaseApplication import com.casic.br.extensions.separateResponseCode import com.casic.br.extensions.toErrorMessage +import com.casic.br.model.AddressListModel +import com.casic.br.model.CommonResultModel import com.casic.br.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.launch import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.vm.BaseViewModel @@ -11,6 +16,10 @@ class AddressViewModel : BaseViewModel() { + private val gson by lazy { Gson() } + val listModel = MutableLiveData() + val deleteResult = MutableLiveData() + fun addAddress( account: String, province: String, city: String, area: String, street: String, detailAddress: String, @@ -37,4 +46,44 @@ loadState.value = LoadState.Fail it.printStackTrace() }) + + fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.obtainAddressListByPage( + account, province, city, area, offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + listModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) + + fun deleteAddressById(id: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.deleteAddressById(id) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + deleteResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt index 2ecd44e..79316e4 100644 --- a/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt @@ -14,7 +14,7 @@ class AuthenticateViewModel : BaseViewModel() { - private val gson = Gson() + private val gson by lazy { Gson() } val keyModel = MutableLiveData() fun obtainPublicKey() = launch({ diff --git a/app/src/main/java/com/casic/br/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/vm/UserViewModel.kt index 579daaf..feb0db2 100644 --- a/app/src/main/java/com/casic/br/vm/UserViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/UserViewModel.kt @@ -16,7 +16,7 @@ class UserViewModel : BaseViewModel() { - private val gson = Gson() + private val gson by lazy { Gson() } val registerResult = MutableLiveData() val loginResult = MutableLiveData() diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_7.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_7.xml new file mode 100644 index 0000000..8c2683e --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_7.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..a75af6c --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/layout/activity_add_address.xml b/app/src/main/res/layout/activity_add_address.xml index fae2694..e47f3f9 100644 --- a/app/src/main/res/layout/activity_add_address.xml +++ b/app/src/main/res/layout/activity_add_address.xml @@ -20,7 +20,7 @@ +) : RecyclerView.Adapter() { + + private var layoutInflater: LayoutInflater = LayoutInflater.from(context) + + private var deleteAction = QMUISwipeAction.ActionBuilder() + .icon(ContextCompat.getDrawable(context, R.drawable.ic_delete_white)) + .textSize(16f.dp2px(context)) + .textColor(Color.WHITE) + .paddingStartEnd(16f.dp2px(context)).text("删除") + .backgroundColor(Color.RED) + .build() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QMUISwipeViewHolder { + val view = layoutInflater.inflate(R.layout.item_address_rv_l, parent, false) + val swipeViewHolder = QMUISwipeViewHolder(view) + swipeViewHolder.addSwipeAction(deleteAction) + return swipeViewHolder + } + + override fun onBindViewHolder(holder: QMUISwipeViewHolder, position: Int) { + //初始化控件 + val userPhoneView: TextView = holder.itemView.findViewById(R.id.userPhoneView) + val detailAddressView: TextView = holder.itemView.findViewById(R.id.detailAddressView) + val updateTimeView: TextView = holder.itemView.findViewById(R.id.updateTimeView) + val editAddressView: ImageView = holder.itemView.findViewById(R.id.editAddressView) + + //绑定数据 + val rowsBean = dataRows[position] + userPhoneView.text = rowsBean.account + detailAddressView.text = rowsBean.detailAddress + updateTimeView.text = rowsBean.updateTime + + editAddressView.setOnClickListener { + clickListener?.onEditButtonClicked(position) + } + } + + override fun getItemCount(): Int = dataRows.size + + private var clickListener: OnItemClickListener? = null + + interface OnItemClickListener { + fun onEditButtonClicked(position: Int) + } + + fun setOnItemClickListener(clickListener: OnItemClickListener?) { + this.clickListener = clickListener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/model/AddressListModel.java b/app/src/main/java/com/casic/br/model/AddressListModel.java new file mode 100644 index 0000000..00251b5 --- /dev/null +++ b/app/src/main/java/com/casic/br/model/AddressListModel.java @@ -0,0 +1,166 @@ +package com.casic.br.model; + +import java.util.List; + +public class AddressListModel { + + private int code; + private DataModel data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String account; + private String area; + private String city; + private String createTime; + private String detailAddress; + private String id; + private String ids; + private String postalCode; + private String province; + private String street; + private String updateTime; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDetailAddress() { + return detailAddress; + } + + public void setDetailAddress(String detailAddress) { + this.detailAddress = detailAddress; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIds() { + return ids; + } + + public void setIds(String ids) { + this.ids = ids; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt index 83686ce..9f1c93b 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitService.kt @@ -43,4 +43,22 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 地址列表 + */ + @POST("/appAddressInfo/listPage") + suspend fun obtainAddressListByPage( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 地址删除 + */ + @POST("/appAddressInfo/delete") + suspend fun deleteAddressById( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt index 183fb6f..ffb6064 100644 --- a/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/utils/retrofit/RetrofitServiceManager.kt @@ -108,4 +108,35 @@ ) return api.addAddress(AuthenticationHelper.token!!, requestBody) } + + /** + * 地址列表 + */ + suspend fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ): String { + val paramObject = JSONObject() + paramObject.put("account", account) + paramObject.put("province", province) + paramObject.put("city", city) + paramObject.put("area", area) + paramObject.put("limit", LocaleConstant.PAGE_LIMIT) + paramObject.put("offset", offset) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.obtainAddressListByPage(AuthenticationHelper.token!!, requestBody) + } + + /** + * 地址删除 + */ + suspend fun deleteAddressById(id: String): String { + val paramObject = JSONObject() + paramObject.put("id", id) + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.deleteAddressById(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt index 1842b75..ac192c7 100644 --- a/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt +++ b/app/src/main/java/com/casic/br/view/AddressManagerActivity.kt @@ -1,33 +1,224 @@ package com.casic.br.view +import android.content.Context +import android.os.Handler +import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.casic.br.R +import com.casic.br.adapter.AddressListAdapter +import com.casic.br.model.AddressListModel +import com.casic.br.utils.LoadingDialogHub +import com.casic.br.utils.LocaleConstant +import com.casic.br.vm.AddressViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction +import com.qmuiteam.qmui.recyclerView.QMUISwipeAction +import kotlinx.android.synthetic.main.activity_manage_address.* import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + class AddressManagerActivity : KotlinBaseActivity() { - override fun initLayoutView(): Int = R.layout.activity_edit_address + private val kTag = "AddressManagerActivity" + private val context: Context = this@AddressManagerActivity + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var addressViewModel: AddressViewModel + private lateinit var addressAdapter: AddressListAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var clickedPosition = 0 + + override fun initLayoutView(): Int = R.layout.activity_manage_address override fun setupTopBarLayout() { ImmersionBar.with(this).statusBarDarkFont(true).init() ImmerseStatusBarUtil.setColor(this, R.color.white.convertColor(this)) leftBackView.setOnClickListener { finish() } - titleView.text = "我的地址" + titleView.text = "地址管理" } override fun initData() { - - } - - override fun observeRequestState() { - + weakReferenceHandler = WeakReferenceHandler(callback) + addressViewModel = ViewModelProvider(this)[AddressViewModel::class.java] } override fun initEvent() { + addressLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + obtainAddressListByPage() + } + addressLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + obtainAddressListByPage() + } + addressViewModel.deleteResult.observe(this, { + if (it.code == 200) { + dataBeans.removeAt(clickedPosition) + addressAdapter.notifyItemRemoved(clickedPosition) + addressAdapter.notifyItemRangeChanged( + clickedPosition, dataBeans.size - clickedPosition + ) + } + }) + + addAddressButton.setOnClickListener { + val isLogin = SaveKeyValues.getValue(LocaleConstant.USER_IS_LOGIN, false) as Boolean + if (isLogin) { + navigatePageTo() + } else { + navigatePageTo() + } + } + } + + override fun onResume() { + super.onResume() + obtainAddressListByPage() + } + + private fun obtainAddressListByPage() { + addressViewModel.obtainAddressListByPage("", "", "", "", pageIndex) + addressViewModel.listModel.observe(this, { + if (it.code == 200) { + val dataRows = it.data?.rows + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows!! + addressLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows?.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows!!) + addressLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows!! + } + } + weakReferenceHandler.sendEmptyMessage(2022100901) + } + }) + } + + private val callback = Handler.Callback { + if (it.what == 2022100901) { + if (isRefresh || isLoadMore) { + addressAdapter.notifyDataSetChanged() + } else { + addressAdapter = AddressListAdapter(this, dataBeans) + //绑定侧滑事件 + swipeAction.attachToRecyclerView(addressRecyclerView) + val linearLayoutManager = object : LinearLayoutManager(this) { + override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams { + return RecyclerView.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + } + } + addressRecyclerView.layoutManager = linearLayoutManager + addressRecyclerView.adapter = addressAdapter + addressAdapter.setOnItemClickListener(object : + AddressListAdapter.OnItemClickListener { + override fun onEditButtonClicked(position: Int) { +// if (dataBeans[position].devcode.isNullOrBlank()) { +// "设备编号为空,无法查看历史数据".show(context) +// return +// } +// navigatePageTo( +// arrayListOf(groupId, dataBeans[position].devcode) +// ) + } + }) + } + } + true + } + + private val swipeAction = + QMUIRVItemSwipeAction(true, object : QMUIRVItemSwipeAction.Callback() { + + //滑动拉出菜单删除 + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + clickedPosition = viewHolder.bindingAdapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + + override fun getSwipeDirection( + recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder + ): Int { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + + //滑动拉出菜单,点击删除 + override fun onClickAction( + swipeAction: QMUIRVItemSwipeAction?, + selected: RecyclerView.ViewHolder?, + action: QMUISwipeAction? + ) { + super.onClickAction(swipeAction, selected, action) + deleteItem(selected!!.bindingAdapterPosition) + } + }) + + private fun deleteItem(adapterPosition: Int) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("删除后将无法恢复,是否继续?") + .setNegativeButton("容我想想") + .setPositiveButton("已经想好") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onCancelClick() { + + } + + override fun onConfirmClick() { + clickedPosition = adapterPosition + //删除数据库里对应的数据 + addressViewModel.deleteAddressById(dataBeans[clickedPosition].id) + } + }).build().show() + } + + override fun observeRequestState() { + addressViewModel.loadState.observe(this, { + when (it) { + LoadState.Loading -> { + //刷新不显示Loading + if (isRefresh || isLoadMore) { + return@observe + } + LoadingDialogHub.show(this, "数据加载中...") + } + else -> LoadingDialogHub.dismiss() + } + }) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt index d86e677..a7aa9ae 100644 --- a/app/src/main/java/com/casic/br/vm/AddressViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AddressViewModel.kt @@ -1,9 +1,14 @@ package com.casic.br.vm +import androidx.lifecycle.MutableLiveData import com.casic.br.base.BaseApplication import com.casic.br.extensions.separateResponseCode import com.casic.br.extensions.toErrorMessage +import com.casic.br.model.AddressListModel +import com.casic.br.model.CommonResultModel import com.casic.br.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.launch import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.vm.BaseViewModel @@ -11,6 +16,10 @@ class AddressViewModel : BaseViewModel() { + private val gson by lazy { Gson() } + val listModel = MutableLiveData() + val deleteResult = MutableLiveData() + fun addAddress( account: String, province: String, city: String, area: String, street: String, detailAddress: String, @@ -37,4 +46,44 @@ loadState.value = LoadState.Fail it.printStackTrace() }) + + fun obtainAddressListByPage( + account: String, province: String, city: String, area: String, offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.obtainAddressListByPage( + account, province, city, area, offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + listModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) + + fun deleteAddressById(id: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.deleteAddressById(id) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + deleteResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt index 2ecd44e..79316e4 100644 --- a/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/AuthenticateViewModel.kt @@ -14,7 +14,7 @@ class AuthenticateViewModel : BaseViewModel() { - private val gson = Gson() + private val gson by lazy { Gson() } val keyModel = MutableLiveData() fun obtainPublicKey() = launch({ diff --git a/app/src/main/java/com/casic/br/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/vm/UserViewModel.kt index 579daaf..feb0db2 100644 --- a/app/src/main/java/com/casic/br/vm/UserViewModel.kt +++ b/app/src/main/java/com/casic/br/vm/UserViewModel.kt @@ -16,7 +16,7 @@ class UserViewModel : BaseViewModel() { - private val gson = Gson() + private val gson by lazy { Gson() } val registerResult = MutableLiveData() val loginResult = MutableLiveData() diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_7.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_7.xml new file mode 100644 index 0000000..8c2683e --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_7.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..a75af6c --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/layout/activity_add_address.xml b/app/src/main/res/layout/activity_add_address.xml index fae2694..e47f3f9 100644 --- a/app/src/main/res/layout/activity_add_address.xml +++ b/app/src/main/res/layout/activity_add_address.xml @@ -20,7 +20,7 @@ - - - - - - - - -