diff --git a/app/build.gradle b/app/build.gradle index 2707a18..e009301 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,4 +66,8 @@ dependencies { androidTestImplementation libs.androidx.junit //屏幕适配 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' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8404ea2..9e1cb4d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -65,6 +65,10 @@ android:name=".login.ForgetPsdActivity" android:exported="false" /> + + { + 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(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/juhabi/birds/device/BindDeviceActivity.kt b/app/src/main/java/com/juhabi/birds/device/BindDeviceActivity.kt new file mode 100644 index 0000000..bf5af59 --- /dev/null +++ b/app/src/main/java/com/juhabi/birds/device/BindDeviceActivity.kt @@ -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() , 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) { + } + + /** 绑定设备成功后提示用户并关闭当前页面。 */ + override fun bindDeviceSuccess(message: String) { + showMessage(message) + finish() + } + + +} diff --git a/app/src/main/java/com/juhabi/birds/device/DeviceDetailActivity.kt b/app/src/main/java/com/juhabi/birds/device/DeviceDetailActivity.kt new file mode 100644 index 0000000..758de85 --- /dev/null +++ b/app/src/main/java/com/juhabi/birds/device/DeviceDetailActivity.kt @@ -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() , 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) { + } + + override fun bindDeviceSuccess(message: String) { + } + + override fun onClick(view: View) { + } +} \ No newline at end of file diff --git a/app/src/main/java/com/juhabi/birds/device/IndexFragment.kt b/app/src/main/java/com/juhabi/birds/device/IndexFragment.kt new file mode 100644 index 0000000..795e720 --- /dev/null +++ b/app/src/main/java/com/juhabi/birds/device/IndexFragment.kt @@ -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(), + 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) { + 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 = 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 + } + +} diff --git a/app/src/main/java/com/juhabi/birds/device/entity/DeviceEntity.kt b/app/src/main/java/com/juhabi/birds/device/entity/DeviceEntity.kt new file mode 100644 index 0000000..a6ccb1e --- /dev/null +++ b/app/src/main/java/com/juhabi/birds/device/entity/DeviceEntity.kt @@ -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 diff --git a/app/src/main/java/com/juhabi/birds/login/LoginActivity.kt b/app/src/main/java/com/juhabi/birds/login/LoginActivity.kt index 2ba6768..f2ea6af 100644 --- a/app/src/main/java/com/juhabi/birds/login/LoginActivity.kt +++ b/app/src/main/java/com/juhabi/birds/login/LoginActivity.kt @@ -15,6 +15,7 @@ import com.juhabi.birds.login.model.UserEntity import com.juhabi.birds.login.mvp.LoginContract import com.juhabi.birds.login.mvp.LoginImpl import com.juhabi.birds.login.mvp.LoginPresenter +import com.juhabi.birds.main.MainActivity import com.juhabi.birds.mine.MineCenterActivity import com.juhabi.birds.network.TokenManager import com.juhabi.birds.util.SharedPreferencesUtil @@ -191,7 +192,7 @@ class LoginActivity : BaseActivity(), SharedPreferencesUtil.putBoolean(this, KEY_USER_LOGIN, AppConfig.USER_LOGIN) ToastUtil.showShort(mContext, "登录成功") - startActivity(Intent(this, MineCenterActivity::class.java)) + startActivity(Intent(this, MainActivity::class.java)) finish() } diff --git a/app/src/main/java/com/juhabi/birds/login/model/UserEntity.kt b/app/src/main/java/com/juhabi/birds/login/model/UserEntity.kt index d8c9ce8..1cf6534 100644 --- a/app/src/main/java/com/juhabi/birds/login/model/UserEntity.kt +++ b/app/src/main/java/com/juhabi/birds/login/model/UserEntity.kt @@ -1,11 +1,8 @@ package com.juhabi.birds.login.model import com.google.gson.annotations.SerializedName +import java.io.Serializable data class UserEntity( - val scope: Any? = null, - val openid: Any? = null, - @SerializedName("access_token") - val token: String = "", - -) + val token: String +) : Serializable diff --git a/app/src/main/java/com/juhabi/birds/main/MainActivity.kt b/app/src/main/java/com/juhabi/birds/main/MainActivity.kt index a31f7ad..3d6d159 100644 --- a/app/src/main/java/com/juhabi/birds/main/MainActivity.kt +++ b/app/src/main/java/com/juhabi/birds/main/MainActivity.kt @@ -10,8 +10,8 @@ import com.juhabi.birds.base.BaseActivity import com.juhabi.birds.databinding.ActivityMainBinding import com.juhabi.birds.main.adapter.MainPagerAdapter import com.juhabi.birds.main.fragment.HistoryFragment -import com.juhabi.birds.main.fragment.HomeFragment -import com.juhabi.birds.main.fragment.MineFragment +import com.juhabi.birds.device.IndexFragment +import com.juhabi.birds.mine.MineFragment import com.juhabi.birds.main.fragment.PlanFragment import com.juhabi.birds.main.model.AppVersionInfo import com.juhabi.birds.main.mvp.MainContract @@ -42,7 +42,7 @@ class MainActivity : BaseActivity(), override fun initView(savedInstanceState: Bundle?) { binding.viewPager.adapter = MainPagerAdapter( this, - listOf(HomeFragment(), PlanFragment(), HistoryFragment(), MineFragment()) + listOf(IndexFragment(), PlanFragment(), HistoryFragment(), MineFragment()) ) binding.viewPager.offscreenPageLimit = 1 binding.viewPager.registerOnPageChangeCallback(object : androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback() { diff --git a/app/src/main/java/com/juhabi/birds/main/fragment/HomeFragment.kt b/app/src/main/java/com/juhabi/birds/main/fragment/HomeFragment.kt deleted file mode 100644 index 2be01ab..0000000 --- a/app/src/main/java/com/juhabi/birds/main/fragment/HomeFragment.kt +++ /dev/null @@ -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(), - 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?) { - } -} diff --git a/app/src/main/java/com/juhabi/birds/main/fragment/MineFragment.kt b/app/src/main/java/com/juhabi/birds/main/fragment/MineFragment.kt deleted file mode 100644 index 4359d79..0000000 --- a/app/src/main/java/com/juhabi/birds/main/fragment/MineFragment.kt +++ /dev/null @@ -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(), - 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)) - } - } -} diff --git a/app/src/main/java/com/juhabi/birds/mine/MineFragment.kt b/app/src/main/java/com/juhabi/birds/mine/MineFragment.kt new file mode 100644 index 0000000..89b19aa --- /dev/null +++ b/app/src/main/java/com/juhabi/birds/mine/MineFragment.kt @@ -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(), + 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) + } +} diff --git a/app/src/main/java/com/juhabi/birds/mine/model/UserInfoEntity.kt b/app/src/main/java/com/juhabi/birds/mine/model/UserInfoEntity.kt new file mode 100644 index 0000000..94fa4fd --- /dev/null +++ b/app/src/main/java/com/juhabi/birds/mine/model/UserInfoEntity.kt @@ -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 \ No newline at end of file diff --git a/app/src/main/java/com/juhabi/birds/network/ApiService.kt b/app/src/main/java/com/juhabi/birds/network/ApiService.kt index 2a50e12..b4d88c2 100644 --- a/app/src/main/java/com/juhabi/birds/network/ApiService.kt +++ b/app/src/main/java/com/juhabi/birds/network/ApiService.kt @@ -1,5 +1,6 @@ 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.SendCodeEntity import com.juhabi.birds.main.model.AppVersionInfo @@ -7,10 +8,13 @@ import com.juhabi.birds.mine.model.MineUserInfo import okhttp3.RequestBody import retrofit2.Call import retrofit2.http.Body +import retrofit2.http.DELETE import retrofit2.http.HeaderMap import retrofit2.http.GET import retrofit2.http.QueryMap import retrofit2.http.POST +import retrofit2.http.PUT +import retrofit2.http.Path /** * 项目统一接口定义。所有业务接口地址集中维护在这里。 @@ -115,8 +119,57 @@ interface ApiService { fun forgetPsdByEmail(@HeaderMap headers: Map, @Body requestBody: RequestBody): Call> + /** + *查询设备列表 + */ + @GET("app/device/list") + fun getBindDeviceList(@HeaderMap headers: Map, @QueryMap params: Map): Call>> - @GET("app/v1/getUserInfo") + + /** + * 绑定设备 + { + "imei": "860000000000007", + "name": "001设备" + } + */ + @POST("app/device/bind") + fun bindDevice(@HeaderMap headers: Map, @Body requestBody: RequestBody): Call> + + /** + * 设备重新命名 + { + "deviceNo": "BM202609160007", + "name": "改名001" + } + } + */ + @PUT("app/device/{deviceNo}/name") + fun deviceRename(@HeaderMap headers: Map, @Path("deviceNo") deviceNo: String, @Body requestBody: RequestBody): Call> + + + /** + * 眼罩控制 + { + "deviceNo": "BM202609160007", + "coverOn": true + } + */ + @PUT("app/device/{deviceNo}/hood") + fun controlEye(@HeaderMap headers: Map, @Path("deviceNo") deviceNo: String, @Body requestBody: RequestBody): Call> + + + /** + * 解绑设备 + */ + @DELETE("app/device/{deviceNo}") + fun unbindDevice(@HeaderMap headers: Map, @Path("deviceNo") deviceNo: String): Call> + + + /** + * 获取个人信息 + */ + @GET("app/user/profile") fun getMineUserInfo(@HeaderMap headers: Map, @QueryMap params: Map): Call> diff --git a/app/src/main/res/layout/bind_device_layout.xml b/app/src/main/res/layout/bind_device_layout.xml new file mode 100644 index 0000000..5c0d0b5 --- /dev/null +++ b/app/src/main/res/layout/bind_device_layout.xml @@ -0,0 +1,28 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/device_item.xml b/app/src/main/res/layout/device_item.xml new file mode 100644 index 0000000..bc63ddf --- /dev/null +++ b/app/src/main/res/layout/device_item.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 7450be1..b04312b 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -1,8 +1,11 @@ - + xmlns:tools="http://schemas.android.com/tools" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:background="@color/page_background" + android:orientation="vertical"> - + + + + + + + + + + + diff --git a/app/src/main/res/layout/layout_no_more.xml b/app/src/main/res/layout/layout_no_more.xml new file mode 100644 index 0000000..d637a24 --- /dev/null +++ b/app/src/main/res/layout/layout_no_more.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_refresh_header.xml b/app/src/main/res/layout/view_refresh_header.xml new file mode 100644 index 0000000..f8763fa --- /dev/null +++ b/app/src/main/res/layout/view_refresh_header.xml @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_navigation_menu.xml b/app/src/main/res/menu/bottom_navigation_menu.xml index 2ebdc84..f146994 100644 --- a/app/src/main/res/menu/bottom_navigation_menu.xml +++ b/app/src/main/res/menu/bottom_navigation_menu.xml @@ -7,11 +7,13 @@ + android:title="@string/tab_plan" + android:visible="false"/> + android:title="@string/tab_history" + android:visible="false"/> 密码 登录 手机注册 + 绑定设备 请输入账号 请输入密码 显示密码 @@ -18,6 +19,7 @@ 没有账号?立即注册 获取验证码 %1$d秒后重新获取 + 已经到底了 @@ -63,6 +65,8 @@ 历史 我的 首页 + 重命名 + 解绑设备 计划 历史 我的 diff --git a/gradle.properties b/gradle.properties index d621849..837592e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,3 +14,4 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official android.useAndroidX=true +android.enableJetifier=true