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