设备相关
This commit is contained in:
@@ -66,4 +66,8 @@ dependencies {
|
|||||||
androidTestImplementation libs.androidx.junit
|
androidTestImplementation libs.androidx.junit
|
||||||
//屏幕适配
|
//屏幕适配
|
||||||
implementation 'me.jessyan:autosize:1.2.1'
|
implementation 'me.jessyan:autosize:1.2.1'
|
||||||
|
//下拉刷新,上拉加载
|
||||||
|
implementation 'io.github.scwang90:refresh-layout-kernel:2.1.1'
|
||||||
|
implementation 'io.github.scwang90:refresh-header-classics:2.1.1'
|
||||||
|
implementation 'io.github.scwang90:refresh-footer-classics:2.1.1'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,10 @@
|
|||||||
android:name=".login.ForgetPsdActivity"
|
android:name=".login.ForgetPsdActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".device.BindDeviceActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
|
|||||||
@@ -0,0 +1,178 @@
|
|||||||
|
package com.juhabi.birds.custom;
|
||||||
|
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
|
||||||
|
import androidx.annotation.ColorInt;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.juhabi.birds.R;
|
||||||
|
import com.scwang.smart.refresh.layout.api.RefreshHeader;
|
||||||
|
import com.scwang.smart.refresh.layout.api.RefreshKernel;
|
||||||
|
import com.scwang.smart.refresh.layout.api.RefreshLayout;
|
||||||
|
import com.scwang.smart.refresh.layout.constant.RefreshState;
|
||||||
|
import com.scwang.smart.refresh.layout.constant.SpinnerStyle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author fengxiaoyang
|
||||||
|
* @date 2025/7/11
|
||||||
|
* @description TODO: 描述该类的作用
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CustomRefreshHeader extends RelativeLayout implements RefreshHeader {
|
||||||
|
|
||||||
|
private ImageView ivRefresh;
|
||||||
|
private ObjectAnimator rotateAnimator;
|
||||||
|
// 用于 onMoving 中的动态效果
|
||||||
|
private float mLastPercent = 0f;
|
||||||
|
// 记录当前缩放值,避免重复设置
|
||||||
|
private float mCurrentScale = 1f;
|
||||||
|
|
||||||
|
public CustomRefreshHeader(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomRefreshHeader(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context) {
|
||||||
|
LayoutInflater.from(context).inflate(R.layout.view_refresh_header, this);
|
||||||
|
ivRefresh = findViewById(R.id.ivRefresh);
|
||||||
|
|
||||||
|
// 开启硬件加速,提升动画性能
|
||||||
|
setLayerType(LAYER_TYPE_HARDWARE, null);
|
||||||
|
|
||||||
|
// 初始化 ObjectAnimator
|
||||||
|
rotateAnimator = ObjectAnimator.ofFloat(ivRefresh, "rotation", 0f, 360f);
|
||||||
|
rotateAnimator.setDuration(1500);
|
||||||
|
rotateAnimator.setRepeatCount(ValueAnimator.INFINITE);
|
||||||
|
rotateAnimator.setInterpolator(new LinearInterpolator());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public View getView() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
@Override
|
||||||
|
public void onStartAnimator(@NonNull RefreshLayout layout, int height, int maxDragHeight) {
|
||||||
|
if (rotateAnimator != null && !rotateAnimator.isRunning()) {
|
||||||
|
rotateAnimator.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
@Override
|
||||||
|
public int onFinish(@NonNull RefreshLayout layout, boolean success) {
|
||||||
|
if (rotateAnimator != null && rotateAnimator.isRunning()) {
|
||||||
|
rotateAnimator.setInterpolator(new DecelerateInterpolator());
|
||||||
|
postDelayed(() -> {
|
||||||
|
if (rotateAnimator != null) {
|
||||||
|
rotateAnimator.cancel();
|
||||||
|
rotateAnimator.setInterpolator(new LinearInterpolator());
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
// 动画过渡回正常大小
|
||||||
|
animateToNormalScale();
|
||||||
|
return 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平滑动画过渡回正常大小
|
||||||
|
*/
|
||||||
|
private void animateToNormalScale() {
|
||||||
|
if (ivRefresh == null) return;
|
||||||
|
|
||||||
|
float startScale = mCurrentScale;
|
||||||
|
ValueAnimator scaleAnimator = ValueAnimator.ofFloat(startScale, 1f);
|
||||||
|
scaleAnimator.setDuration(300);
|
||||||
|
scaleAnimator.setInterpolator(new DecelerateInterpolator());
|
||||||
|
scaleAnimator.addUpdateListener(animation -> {
|
||||||
|
float value = (float) animation.getAnimatedValue();
|
||||||
|
ivRefresh.setScaleX(value);
|
||||||
|
ivRefresh.setScaleY(value);
|
||||||
|
mCurrentScale = value;
|
||||||
|
});
|
||||||
|
scaleAnimator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 必须实现的方法 ---
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public SpinnerStyle getSpinnerStyle() {
|
||||||
|
return SpinnerStyle.Translate; // Header 跟随内容滑动
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSupportHorizontalDrag() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
@Override
|
||||||
|
public void setPrimaryColors(@ColorInt int... colors) {}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
@Override
|
||||||
|
public void onInitialized(@NonNull RefreshKernel kernel, int height, int maxDragHeight) {}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
@Override
|
||||||
|
public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) {
|
||||||
|
// 只在拖动过程中处理,避免过度计算
|
||||||
|
if (percent != mLastPercent) {
|
||||||
|
mLastPercent = percent;
|
||||||
|
|
||||||
|
// 1. 动态缩放效果:从 0.5 放大到 1.2
|
||||||
|
// 使用 clamp 限制范围:percent 0~1 -> scale 0.5~1.2
|
||||||
|
float targetScale = 0.5f + (0.7f * Math.min(percent, 1.0f));
|
||||||
|
if (Math.abs(targetScale - mCurrentScale) > 0.01f) {
|
||||||
|
mCurrentScale = targetScale;
|
||||||
|
ivRefresh.setScaleX(targetScale);
|
||||||
|
ivRefresh.setScaleY(targetScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 透明度渐变效果(可选)
|
||||||
|
// ivRefresh.setAlpha(Math.min(percent * 1.5f, 1.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
@Override
|
||||||
|
public void onReleased(@NonNull RefreshLayout layout, int height, int maxDragHeight) {}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
@Override
|
||||||
|
public void onHorizontalDrag(float percentX, int offsetX, int offsetMax) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean autoOpen(int duration, float dragRate, boolean animationOnly) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
@Override
|
||||||
|
public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) {
|
||||||
|
// 状态切换时平滑恢复
|
||||||
|
if (newState == RefreshState.PullDownCanceled) {
|
||||||
|
// 用户取消下拉,恢复到初始状态
|
||||||
|
animateToNormalScale();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package com.juhabi.birds.device
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import com.juhabi.birds.R
|
||||||
|
import com.juhabi.birds.base.BaseActivity
|
||||||
|
import com.juhabi.birds.databinding.BindDeviceLayoutBinding
|
||||||
|
import com.juhabi.birds.device.entity.DeviceEntity
|
||||||
|
import com.juhabi.birds.device.mvp.DeviceContract
|
||||||
|
import com.juhabi.birds.device.mvp.DeviceImpl
|
||||||
|
import com.juhabi.birds.device.mvp.DevicePresenter
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定设备
|
||||||
|
*/
|
||||||
|
class BindDeviceActivity: BaseActivity<BindDeviceLayoutBinding, DevicePresenter>() , DeviceContract.DeviceView,
|
||||||
|
View.OnClickListener {
|
||||||
|
override fun createBinding(inflater: LayoutInflater): BindDeviceLayoutBinding {
|
||||||
|
return BindDeviceLayoutBinding.inflate(inflater)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createPresenter(): DevicePresenter? {
|
||||||
|
return DevicePresenter(DeviceImpl())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initWindows() {
|
||||||
|
ImmersionBar.with(this)
|
||||||
|
.statusBarView(binding.statusBarView)
|
||||||
|
.statusBarDarkFont(true)
|
||||||
|
.navigationBarColor(R.color.color_zhu)
|
||||||
|
.navigationBarDarkIcon(true)
|
||||||
|
.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initView(savedInstanceState: Bundle?) {
|
||||||
|
binding.includedTitle.tvTitle.setText(R.string.bind_device)
|
||||||
|
listOf(
|
||||||
|
binding.tvBind,
|
||||||
|
binding.includedTitle.imgBack,
|
||||||
|
).forEach { button ->
|
||||||
|
button.setOnClickListener(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(view: View) {
|
||||||
|
when (view.id) {
|
||||||
|
R.id.img_back ->{
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.tv_bind ->{//绑定设备
|
||||||
|
// val imei = "${System.currentTimeMillis()}${Random.nextInt(100).toString().padStart(2, '0')}"
|
||||||
|
// val name = "device001"
|
||||||
|
val imei = "860000000000005"
|
||||||
|
val name = "BM202609160005"
|
||||||
|
presenter?.bindDevice(imei, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showError(message: String) {
|
||||||
|
showMessage(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBindDeviceListSuccess(devices: List<DeviceEntity>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 绑定设备成功后提示用户并关闭当前页面。 */
|
||||||
|
override fun bindDeviceSuccess(message: String) {
|
||||||
|
showMessage(message)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.juhabi.birds.device
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import com.juhabi.birds.base.BaseActivity
|
||||||
|
import com.juhabi.birds.databinding.BindDeviceLayoutBinding
|
||||||
|
import com.juhabi.birds.device.entity.DeviceEntity
|
||||||
|
import com.juhabi.birds.device.mvp.DeviceContract
|
||||||
|
import com.juhabi.birds.device.mvp.DeviceImpl
|
||||||
|
import com.juhabi.birds.device.mvp.DevicePresenter
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备详情
|
||||||
|
*/
|
||||||
|
class DeviceDetailActivity: BaseActivity<BindDeviceLayoutBinding, DevicePresenter>() , DeviceContract.DeviceView,
|
||||||
|
View.OnClickListener {
|
||||||
|
override fun createBinding(inflater: LayoutInflater): BindDeviceLayoutBinding {
|
||||||
|
return BindDeviceLayoutBinding.inflate(inflater)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createPresenter(): DevicePresenter? {
|
||||||
|
return DevicePresenter(DeviceImpl())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initView(savedInstanceState: Bundle?) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showError(message: String) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBindDeviceListSuccess(devices: List<DeviceEntity>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun bindDeviceSuccess(message: String) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(view: View) {
|
||||||
|
}
|
||||||
|
}
|
||||||
184
app/src/main/java/com/juhabi/birds/device/IndexFragment.kt
Normal file
184
app/src/main/java/com/juhabi/birds/device/IndexFragment.kt
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
package com.juhabi.birds.device
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.juhabi.birds.R
|
||||||
|
import com.juhabi.birds.base.BaseActivity
|
||||||
|
import com.juhabi.birds.base.BaseFragment
|
||||||
|
import com.juhabi.birds.custom.DeviceActionPopupWindow
|
||||||
|
import com.juhabi.birds.custom.CustomRefreshHeader
|
||||||
|
import com.juhabi.birds.databinding.FragmentHomeBinding
|
||||||
|
import com.juhabi.birds.device.entity.DeviceEntity
|
||||||
|
import com.juhabi.birds.device.mvp.DeviceContract
|
||||||
|
import com.juhabi.birds.device.mvp.DeviceImpl
|
||||||
|
import com.juhabi.birds.device.mvp.DevicePresenter
|
||||||
|
import com.juhabi.birds.main.fragment.home.mvp.HomeContract
|
||||||
|
import com.juhabi.birds.main.fragment.home.mvp.HomeImpl
|
||||||
|
import com.juhabi.birds.main.fragment.home.mvp.HomePresenter
|
||||||
|
import com.scwang.smart.refresh.footer.ClassicsFooter
|
||||||
|
|
||||||
|
class IndexFragment : BaseFragment<FragmentHomeBinding, DevicePresenter>(),
|
||||||
|
DeviceContract.DeviceView, View.OnClickListener {
|
||||||
|
|
||||||
|
private val deviceAdapter = DeviceAdapter()
|
||||||
|
private var currentPage = FIRST_PAGE
|
||||||
|
private var pendingUnbindPosition: Int? = null
|
||||||
|
|
||||||
|
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentHomeBinding {
|
||||||
|
return FragmentHomeBinding.inflate(inflater, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createPresenter(): DevicePresenter {
|
||||||
|
return DevicePresenter(DeviceImpl())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initView(savedInstanceState: Bundle?) {
|
||||||
|
listOf(
|
||||||
|
binding.tvIndex,
|
||||||
|
).forEach { button ->
|
||||||
|
button.setOnClickListener(this)
|
||||||
|
}
|
||||||
|
binding.rvDevices.adapter = deviceAdapter
|
||||||
|
deviceAdapter.setOnItemChildClickListener { adapter, view, position ->
|
||||||
|
when (view.id) {
|
||||||
|
R.id.img_tips -> {
|
||||||
|
val device = deviceAdapter.data[position]
|
||||||
|
DeviceActionPopupWindow(requireContext()).show(
|
||||||
|
view,
|
||||||
|
onRename = {//重命名
|
||||||
|
showEditDialog(
|
||||||
|
"设备重命名", device.name, click = object : OnDialogClick {
|
||||||
|
|
||||||
|
override fun onCancelClick() {}
|
||||||
|
override fun onConfirmClick(content: String) {
|
||||||
|
presenter?.renameDevice(device.deviceNo, content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onUnbind = {//解绑设备
|
||||||
|
showDialogtext(
|
||||||
|
"提示",
|
||||||
|
"确定要解绑该设备?",
|
||||||
|
"确定",
|
||||||
|
"取消",
|
||||||
|
object : OnDialogClick {
|
||||||
|
override fun onCancelClick() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onConfirmClick() {
|
||||||
|
// 用户确认后,按设备编号请求解绑
|
||||||
|
pendingUnbindPosition = position
|
||||||
|
presenter?.unbindDevice(device.deviceNo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initData(savedInstanceState: Bundle?) {
|
||||||
|
super.initData(savedInstanceState)
|
||||||
|
binding.refresh.setRefreshHeader(CustomRefreshHeader(requireContext()))
|
||||||
|
binding.refresh.setRefreshFooter(ClassicsFooter(requireContext()))
|
||||||
|
binding.refresh.setOnRefreshListener {
|
||||||
|
currentPage = FIRST_PAGE
|
||||||
|
requestDeviceList()
|
||||||
|
}
|
||||||
|
binding.refresh.setOnLoadMoreListener {
|
||||||
|
currentPage++
|
||||||
|
requestDeviceList()
|
||||||
|
}
|
||||||
|
requestDeviceList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(view: View) {
|
||||||
|
when(view.id){
|
||||||
|
R.id.tv_index ->{
|
||||||
|
goTo(BindDeviceActivity::class.java,null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBindDeviceListSuccess(devices: List<DeviceEntity>) {
|
||||||
|
if (currentPage == FIRST_PAGE) {
|
||||||
|
deviceAdapter.setList(devices)
|
||||||
|
} else {
|
||||||
|
deviceAdapter.addData(devices)
|
||||||
|
}
|
||||||
|
binding.refresh.finishRefresh()
|
||||||
|
binding.refresh.finishLoadMore()
|
||||||
|
binding.refresh.setNoMoreData(devices.size < PAGE_SIZE)
|
||||||
|
binding.relNoMore.visibility =
|
||||||
|
if (deviceAdapter.data.isEmpty()) View.VISIBLE else View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun bindDeviceSuccess(message: String) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 设备重命名成功后提示用户并重新加载第一页数据。 */
|
||||||
|
override fun renameDeviceSuccess(message: String) {
|
||||||
|
showMessage(message)
|
||||||
|
currentPage = FIRST_PAGE
|
||||||
|
requestDeviceList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 设备解绑成功后先播放删除动画,再延迟刷新第一页数据。 */
|
||||||
|
override fun unbindDeviceSuccess(message: String) {
|
||||||
|
showMessage(message)
|
||||||
|
val removedPosition = pendingUnbindPosition
|
||||||
|
pendingUnbindPosition = null
|
||||||
|
if (removedPosition != null && removedPosition in deviceAdapter.data.indices) {
|
||||||
|
deviceAdapter.data.removeAt(removedPosition)
|
||||||
|
deviceAdapter.notifyItemRemoved(removedPosition)
|
||||||
|
binding.relNoMore.visibility =
|
||||||
|
if (deviceAdapter.data.isEmpty()) View.VISIBLE else View.GONE
|
||||||
|
}
|
||||||
|
// 等待 RecyclerView 删除动画完成后再刷新,避免刷新结果立即覆盖动画。
|
||||||
|
binding.root.postDelayed({
|
||||||
|
if (!isAdded) return@postDelayed
|
||||||
|
currentPage = FIRST_PAGE
|
||||||
|
requestDeviceList()
|
||||||
|
}, REMOVE_ANIMATION_DELAY_MS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 请求指定页的设备列表。 */
|
||||||
|
private fun requestDeviceList() {
|
||||||
|
presenter?.getBindDeviceList(
|
||||||
|
mapOf(
|
||||||
|
"pageNum" to currentPage.toString(),
|
||||||
|
"pageSize" to PAGE_SIZE.toString()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 请求失败时结束刷新状态并恢复上一次有效页码。 */
|
||||||
|
override fun showError(message: String) {
|
||||||
|
binding.refresh.finishRefresh(false)
|
||||||
|
binding.refresh.finishLoadMore(false)
|
||||||
|
if (currentPage > FIRST_PAGE) {
|
||||||
|
currentPage--
|
||||||
|
}
|
||||||
|
super.showError(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 接口暂无数据时提供临时设备,方便先验收列表布局。 */
|
||||||
|
private fun temporaryDevices(): List<DeviceEntity> = listOf(
|
||||||
|
DeviceEntity("暂无地址", "BM202609160005", null, "0", "已断开", "860000000000005", null, null, null, "BM202609160005", null, 0, "离线", "1"),
|
||||||
|
DeviceEntity("暂无地址", "BM202609160006", null, "0", "已断开", "860000000000006", null, null, null, "BM202609160006", null, 0, "离线", "1"),
|
||||||
|
DeviceEntity("暂无地址", "BM202609160007", null, "0", "已断开", "860000000000007", null, null, null, "BM202609160007", null, 0, "离线", "1")
|
||||||
|
)
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val FIRST_PAGE = 1
|
||||||
|
const val PAGE_SIZE = 10
|
||||||
|
const val REMOVE_ANIMATION_DELAY_MS = 300L
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.juhabi.birds.device.entity
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
data class DeviceEntity(
|
||||||
|
val address: String,
|
||||||
|
val deviceNo: String,
|
||||||
|
val hoodBattery: Int?,
|
||||||
|
val hoodConnected: String,
|
||||||
|
val hoodConnectedText: String,
|
||||||
|
val imei: String,
|
||||||
|
val lat: Double?,
|
||||||
|
val lng: Double?,
|
||||||
|
val model: String?,
|
||||||
|
val name: String,
|
||||||
|
val ringBattery: Int?,
|
||||||
|
val signalLevel: Int,
|
||||||
|
val signalText: String,
|
||||||
|
val status: String
|
||||||
|
) : Serializable
|
||||||
@@ -15,6 +15,7 @@ import com.juhabi.birds.login.model.UserEntity
|
|||||||
import com.juhabi.birds.login.mvp.LoginContract
|
import com.juhabi.birds.login.mvp.LoginContract
|
||||||
import com.juhabi.birds.login.mvp.LoginImpl
|
import com.juhabi.birds.login.mvp.LoginImpl
|
||||||
import com.juhabi.birds.login.mvp.LoginPresenter
|
import com.juhabi.birds.login.mvp.LoginPresenter
|
||||||
|
import com.juhabi.birds.main.MainActivity
|
||||||
import com.juhabi.birds.mine.MineCenterActivity
|
import com.juhabi.birds.mine.MineCenterActivity
|
||||||
import com.juhabi.birds.network.TokenManager
|
import com.juhabi.birds.network.TokenManager
|
||||||
import com.juhabi.birds.util.SharedPreferencesUtil
|
import com.juhabi.birds.util.SharedPreferencesUtil
|
||||||
@@ -191,7 +192,7 @@ class LoginActivity : BaseActivity<ActivityLoginBinding, LoginPresenter>(),
|
|||||||
SharedPreferencesUtil.putBoolean(this, KEY_USER_LOGIN, AppConfig.USER_LOGIN)
|
SharedPreferencesUtil.putBoolean(this, KEY_USER_LOGIN, AppConfig.USER_LOGIN)
|
||||||
|
|
||||||
ToastUtil.showShort(mContext, "登录成功")
|
ToastUtil.showShort(mContext, "登录成功")
|
||||||
startActivity(Intent(this, MineCenterActivity::class.java))
|
startActivity(Intent(this, MainActivity::class.java))
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
package com.juhabi.birds.login.model
|
package com.juhabi.birds.login.model
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
data class UserEntity(
|
data class UserEntity(
|
||||||
val scope: Any? = null,
|
val token: String
|
||||||
val openid: Any? = null,
|
) : Serializable
|
||||||
@SerializedName("access_token")
|
|
||||||
val token: String = "",
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import com.juhabi.birds.base.BaseActivity
|
|||||||
import com.juhabi.birds.databinding.ActivityMainBinding
|
import com.juhabi.birds.databinding.ActivityMainBinding
|
||||||
import com.juhabi.birds.main.adapter.MainPagerAdapter
|
import com.juhabi.birds.main.adapter.MainPagerAdapter
|
||||||
import com.juhabi.birds.main.fragment.HistoryFragment
|
import com.juhabi.birds.main.fragment.HistoryFragment
|
||||||
import com.juhabi.birds.main.fragment.HomeFragment
|
import com.juhabi.birds.device.IndexFragment
|
||||||
import com.juhabi.birds.main.fragment.MineFragment
|
import com.juhabi.birds.mine.MineFragment
|
||||||
import com.juhabi.birds.main.fragment.PlanFragment
|
import com.juhabi.birds.main.fragment.PlanFragment
|
||||||
import com.juhabi.birds.main.model.AppVersionInfo
|
import com.juhabi.birds.main.model.AppVersionInfo
|
||||||
import com.juhabi.birds.main.mvp.MainContract
|
import com.juhabi.birds.main.mvp.MainContract
|
||||||
@@ -42,7 +42,7 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainPresenter>(),
|
|||||||
override fun initView(savedInstanceState: Bundle?) {
|
override fun initView(savedInstanceState: Bundle?) {
|
||||||
binding.viewPager.adapter = MainPagerAdapter(
|
binding.viewPager.adapter = MainPagerAdapter(
|
||||||
this,
|
this,
|
||||||
listOf(HomeFragment(), PlanFragment(), HistoryFragment(), MineFragment())
|
listOf(IndexFragment(), PlanFragment(), HistoryFragment(), MineFragment())
|
||||||
)
|
)
|
||||||
binding.viewPager.offscreenPageLimit = 1
|
binding.viewPager.offscreenPageLimit = 1
|
||||||
binding.viewPager.registerOnPageChangeCallback(object : androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback() {
|
binding.viewPager.registerOnPageChangeCallback(object : androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback() {
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
package com.juhabi.birds.main.fragment
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import com.juhabi.birds.base.BaseFragment
|
|
||||||
import com.juhabi.birds.databinding.FragmentHomeBinding
|
|
||||||
import com.juhabi.birds.main.fragment.home.mvp.HomeContract
|
|
||||||
import com.juhabi.birds.main.fragment.home.mvp.HomeImpl
|
|
||||||
import com.juhabi.birds.main.fragment.home.mvp.HomePresenter
|
|
||||||
|
|
||||||
class HomeFragment : BaseFragment<FragmentHomeBinding, HomePresenter>(),
|
|
||||||
HomeContract.HomeView {
|
|
||||||
|
|
||||||
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentHomeBinding {
|
|
||||||
return FragmentHomeBinding.inflate(inflater, container, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createPresenter(): HomePresenter {
|
|
||||||
return HomePresenter(HomeImpl())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun initView(savedInstanceState: Bundle?) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package com.juhabi.birds.main.fragment
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import com.juhabi.birds.base.BaseFragment
|
|
||||||
import com.juhabi.birds.databinding.FragmentMineBinding
|
|
||||||
import com.juhabi.birds.main.fragment.mine.mvp.MineFragmentContract
|
|
||||||
import com.juhabi.birds.main.fragment.mine.mvp.MineFragmentImpl
|
|
||||||
import com.juhabi.birds.main.fragment.mine.mvp.MineFragmentPresenter
|
|
||||||
import com.juhabi.birds.mine.MineCenterActivity
|
|
||||||
|
|
||||||
class MineFragment : BaseFragment<FragmentMineBinding, MineFragmentPresenter>(),
|
|
||||||
MineFragmentContract.MineView {
|
|
||||||
|
|
||||||
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentMineBinding {
|
|
||||||
return FragmentMineBinding.inflate(inflater, container, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createPresenter(): MineFragmentPresenter {
|
|
||||||
return MineFragmentPresenter(MineFragmentImpl())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun initView(savedInstanceState: Bundle?) {
|
|
||||||
binding.openComponentCenterButton.setOnClickListener {
|
|
||||||
startActivity(Intent(requireContext(), MineCenterActivity::class.java))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
50
app/src/main/java/com/juhabi/birds/mine/MineFragment.kt
Normal file
50
app/src/main/java/com/juhabi/birds/mine/MineFragment.kt
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package com.juhabi.birds.mine
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.juhabi.birds.base.BaseFragment
|
||||||
|
import com.juhabi.birds.databinding.FragmentMineBinding
|
||||||
|
import com.juhabi.birds.mine.model.MineUserInfo
|
||||||
|
import com.juhabi.birds.main.model.AppVersionInfo
|
||||||
|
import com.juhabi.birds.mine.mvp.MineContract
|
||||||
|
import com.juhabi.birds.mine.mvp.MineImpl
|
||||||
|
import com.juhabi.birds.mine.mvp.MinePresenter
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 个人中心
|
||||||
|
*/
|
||||||
|
class MineFragment : BaseFragment<FragmentMineBinding, MinePresenter>(),
|
||||||
|
MineContract.MineView {
|
||||||
|
|
||||||
|
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentMineBinding {
|
||||||
|
return FragmentMineBinding.inflate(inflater, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createPresenter(): MinePresenter {
|
||||||
|
return MinePresenter(MineImpl())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
/** 页面恢复显示时重新请求当前用户的个人信息。 */
|
||||||
|
presenter?.getUserInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initView(savedInstanceState: Bundle?) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 将个人信息请求结果更新到个人中心页面。 */
|
||||||
|
override fun getUserInfoSuccess(userInfo: MineUserInfo) {
|
||||||
|
showMessage("个人信息获取成功")
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 版本检测回调,个人中心暂不处理版本信息。 */
|
||||||
|
override fun onVersionChecked(versionInfo: AppVersionInfo) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 显示获取个人信息失败的原因。 */
|
||||||
|
override fun showError(message: String) {
|
||||||
|
showMessage(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.juhabi.birds.mine.model
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
|
||||||
|
data class UserInfoEntity(
|
||||||
|
val createTime: String,
|
||||||
|
val email: String,
|
||||||
|
val nickName: String,
|
||||||
|
val phoneBound: Boolean,
|
||||||
|
val phoneNumber: String,
|
||||||
|
val userName: String,
|
||||||
|
val userType: String
|
||||||
|
): Serializable
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.juhabi.birds.network
|
package com.juhabi.birds.network
|
||||||
|
|
||||||
|
import com.juhabi.birds.device.entity.DeviceEntity
|
||||||
import com.juhabi.birds.login.model.UserEntity
|
import com.juhabi.birds.login.model.UserEntity
|
||||||
import com.juhabi.birds.login.model.SendCodeEntity
|
import com.juhabi.birds.login.model.SendCodeEntity
|
||||||
import com.juhabi.birds.main.model.AppVersionInfo
|
import com.juhabi.birds.main.model.AppVersionInfo
|
||||||
@@ -7,10 +8,13 @@ import com.juhabi.birds.mine.model.MineUserInfo
|
|||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
|
import retrofit2.http.DELETE
|
||||||
import retrofit2.http.HeaderMap
|
import retrofit2.http.HeaderMap
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
import retrofit2.http.QueryMap
|
import retrofit2.http.QueryMap
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
|
import retrofit2.http.PUT
|
||||||
|
import retrofit2.http.Path
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 项目统一接口定义。所有业务接口地址集中维护在这里。
|
* 项目统一接口定义。所有业务接口地址集中维护在这里。
|
||||||
@@ -115,8 +119,57 @@ interface ApiService {
|
|||||||
fun forgetPsdByEmail(@HeaderMap headers: Map<String, String>, @Body requestBody: RequestBody): Call<BaseBean<UserEntity>>
|
fun forgetPsdByEmail(@HeaderMap headers: Map<String, String>, @Body requestBody: RequestBody): Call<BaseBean<UserEntity>>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*查询设备列表
|
||||||
|
*/
|
||||||
|
@GET("app/device/list")
|
||||||
|
fun getBindDeviceList(@HeaderMap headers: Map<String, String>, @QueryMap params: Map<String, String>): Call<BaseBean<List<DeviceEntity>>>
|
||||||
|
|
||||||
@GET("app/v1/getUserInfo")
|
|
||||||
|
/**
|
||||||
|
* 绑定设备
|
||||||
|
{
|
||||||
|
"imei": "860000000000007",
|
||||||
|
"name": "001设备"
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@POST("app/device/bind")
|
||||||
|
fun bindDevice(@HeaderMap headers: Map<String, String>, @Body requestBody: RequestBody): Call<BaseBean<Any>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备重新命名
|
||||||
|
{
|
||||||
|
"deviceNo": "BM202609160007",
|
||||||
|
"name": "改名001"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@PUT("app/device/{deviceNo}/name")
|
||||||
|
fun deviceRename(@HeaderMap headers: Map<String, String>, @Path("deviceNo") deviceNo: String, @Body requestBody: RequestBody): Call<BaseBean<Any>>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 眼罩控制
|
||||||
|
{
|
||||||
|
"deviceNo": "BM202609160007",
|
||||||
|
"coverOn": true
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@PUT("app/device/{deviceNo}/hood")
|
||||||
|
fun controlEye(@HeaderMap headers: Map<String, String>, @Path("deviceNo") deviceNo: String, @Body requestBody: RequestBody): Call<BaseBean<Any>>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解绑设备
|
||||||
|
*/
|
||||||
|
@DELETE("app/device/{deviceNo}")
|
||||||
|
fun unbindDevice(@HeaderMap headers: Map<String, String>, @Path("deviceNo") deviceNo: String): Call<BaseBean<Any>>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取个人信息
|
||||||
|
*/
|
||||||
|
@GET("app/user/profile")
|
||||||
fun getMineUserInfo(@HeaderMap headers: Map<String, String>, @QueryMap params: Map<String, String>): Call<BaseBean<MineUserInfo>>
|
fun getMineUserInfo(@HeaderMap headers: Map<String, String>, @QueryMap params: Map<String, String>): Call<BaseBean<MineUserInfo>>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
28
app/src/main/res/layout/bind_device_layout.xml
Normal file
28
app/src/main/res/layout/bind_device_layout.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<View
|
||||||
|
android:id="@+id/statusBarView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:background="@color/color_zhu" />
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/rl_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/included_title"
|
||||||
|
layout="@layout/include_activity_back_gray_layout" />
|
||||||
|
</RelativeLayout>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_bind"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:text="绑定"
|
||||||
|
android:background="@color/color_zhu"/>
|
||||||
|
</LinearLayout>
|
||||||
80
app/src/main/res/layout/device_item.xml
Normal file
80
app/src/main/res/layout/device_item.xml
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:background="#FFFFFF"
|
||||||
|
android:elevation="2dp"
|
||||||
|
android:padding="14dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="end">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/img_tips"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:src="@mipmap/ic_launcher"
|
||||||
|
android:layout_gravity="end"/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/control_eye"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:src="@mipmap/icon_login_show"
|
||||||
|
android:layout_gravity="end"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_device_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#222222"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_device_status"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:textColor="#2E8B57"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_device_no"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:textColor="#555555"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_device_imei"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:textColor="#777777"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_device_detail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:textColor="#777777"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_device_location"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:textColor="#777777"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/page_background">
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:background="@color/page_background"
|
||||||
|
android:orientation="vertical">
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/rl_title"
|
android:id="@+id/rl_title"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -12,10 +15,39 @@
|
|||||||
layout="@layout/include_title_home_layout" />
|
layout="@layout/include_title_home_layout" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/tv_index"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
|
||||||
android:text="@string/home_page_title"
|
android:text="@string/home_page_title"
|
||||||
android:textColor="@color/black"
|
android:textColor="@color/black"
|
||||||
android:textSize="24sp" />
|
android:textSize="24sp" />
|
||||||
</FrameLayout>
|
<com.scwang.smart.refresh.layout.SmartRefreshLayout
|
||||||
|
android:id="@+id/refresh"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<!-- 设备列表区域 -->
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rv_devices"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingHorizontal="15dp"
|
||||||
|
tools:itemCount="5"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/rel_no_more"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone" >
|
||||||
|
<include
|
||||||
|
android:id="@+id/lay_no_more"
|
||||||
|
layout="@layout/layout_no_more"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|||||||
41
app/src/main/res/layout/layout_no_more.xml
Normal file
41
app/src/main/res/layout/layout_no_more.xml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/layout_no_more"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@color/color_zhu" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="1dp"
|
||||||
|
android:text="@string/no_more_data"
|
||||||
|
android:textColor="@color/color_zhu"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@color/color_zhu" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
11
app/src/main/res/layout/view_refresh_header.xml
Normal file
11
app/src/main/res/layout/view_refresh_header.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="80dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="@color/transparent">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivRefresh"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:src="@mipmap/icon_water_head_refresh" />
|
||||||
|
</RelativeLayout>
|
||||||
@@ -7,11 +7,13 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/navigation_plan"
|
android:id="@+id/navigation_plan"
|
||||||
android:icon="@drawable/ic_nav_plan"
|
android:icon="@drawable/ic_nav_plan"
|
||||||
android:title="@string/tab_plan" />
|
android:title="@string/tab_plan"
|
||||||
|
android:visible="false"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/navigation_history"
|
android:id="@+id/navigation_history"
|
||||||
android:icon="@drawable/ic_nav_history"
|
android:icon="@drawable/ic_nav_history"
|
||||||
android:title="@string/tab_history" />
|
android:title="@string/tab_history"
|
||||||
|
android:visible="false"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/navigation_mine"
|
android:id="@+id/navigation_mine"
|
||||||
android:icon="@drawable/ic_nav_mine"
|
android:icon="@drawable/ic_nav_mine"
|
||||||
|
|||||||
BIN
app/src/main/res/mipmap-hdpi/icon_water_head_refresh.png
Normal file
BIN
app/src/main/res/mipmap-hdpi/icon_water_head_refresh.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/icon_water_head_refresh.png
Normal file
BIN
app/src/main/res/mipmap-xxhdpi/icon_water_head_refresh.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/icon_water_head_refresh.png
Normal file
BIN
app/src/main/res/mipmap-xxxhdpi/icon_water_head_refresh.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.1 KiB |
@@ -7,6 +7,7 @@
|
|||||||
<string name="login_password">密码</string>
|
<string name="login_password">密码</string>
|
||||||
<string name="login_button">登录</string>
|
<string name="login_button">登录</string>
|
||||||
<string name="login_register">手机注册</string>
|
<string name="login_register">手机注册</string>
|
||||||
|
<string name="bind_device">绑定设备</string>
|
||||||
<string name="register_account_hint">请输入账号</string>
|
<string name="register_account_hint">请输入账号</string>
|
||||||
<string name="register_password_hint">请输入密码</string>
|
<string name="register_password_hint">请输入密码</string>
|
||||||
<string name="register_show_password">显示密码</string>
|
<string name="register_show_password">显示密码</string>
|
||||||
@@ -18,6 +19,7 @@
|
|||||||
<string name="register_prompt">没有账号?立即注册</string>
|
<string name="register_prompt">没有账号?立即注册</string>
|
||||||
<string name="register_get_code">获取验证码</string>
|
<string name="register_get_code">获取验证码</string>
|
||||||
<string name="register_code_countdown">%1$d秒后重新获取</string>
|
<string name="register_code_countdown">%1$d秒后重新获取</string>
|
||||||
|
<string name="no_more_data">已经到底了</string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -63,6 +65,8 @@
|
|||||||
<string name="tab_history">历史</string>
|
<string name="tab_history">历史</string>
|
||||||
<string name="tab_mine">我的</string>
|
<string name="tab_mine">我的</string>
|
||||||
<string name="home_page_title">首页</string>
|
<string name="home_page_title">首页</string>
|
||||||
|
<string name="device_action_rename">重命名</string>
|
||||||
|
<string name="device_action_unbind">解绑设备</string>
|
||||||
<string name="plan_page_title">计划</string>
|
<string name="plan_page_title">计划</string>
|
||||||
<string name="history_page_title">历史</string>
|
<string name="history_page_title">历史</string>
|
||||||
<string name="mine_page_title">我的</string>
|
<string name="mine_page_title">我的</string>
|
||||||
|
|||||||
@@ -14,3 +14,4 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
|||||||
# Kotlin code style for this project: "official" or "obsolete":
|
# Kotlin code style for this project: "official" or "obsolete":
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
|
android.enableJetifier=true
|
||||||
|
|||||||
Reference in New Issue
Block a user