首页
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
android:required="true" />
|
||||
|
||||
<application
|
||||
android:name=".MyApplication"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.example.defenseapplication
|
||||
|
||||
import android.app.Application
|
||||
import com.blankj.utilcode.util.Utils;
|
||||
class MyApplication : Application(){
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
Utils.init(this) // 初始化 AndroidUtilCode
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.example.defenseapplication.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.example.defenseapplication.R
|
||||
import com.example.defenseapplication.databinding.ItemFamilyBinding
|
||||
|
||||
class FamilyAdapter(
|
||||
private val onItemClick: (String) -> Unit
|
||||
) : RecyclerView.Adapter<FamilyAdapter.FamilyViewHolder>() {
|
||||
|
||||
private val items = mutableListOf<String>()
|
||||
private var selectedFamily: String? = null
|
||||
|
||||
fun submitList(familyList: List<String>, currentFamily: String) {
|
||||
items.clear()
|
||||
items.addAll(familyList)
|
||||
selectedFamily = currentFamily
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FamilyViewHolder {
|
||||
val binding = ItemFamilyBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return FamilyViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: FamilyViewHolder, position: Int) {
|
||||
holder.bind(items[position])
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = items.size
|
||||
|
||||
inner class FamilyViewHolder(private val binding: ItemFamilyBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun bind(item: String) {
|
||||
binding.tvFamilyName.text = item
|
||||
val textColor = if (item == selectedFamily) R.color.green else R.color.black
|
||||
binding.tvFamilyName.setTextColor(binding.root.context.getColor(textColor))
|
||||
binding.root.setOnClickListener { onItemClick(item) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.example.defenseapplication.bean
|
||||
|
||||
data class GetCodeBean<T> (
|
||||
val code:Int,
|
||||
val msg:String,
|
||||
val data:T
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
package bean
|
||||
|
||||
//登录-bean
|
||||
data class Login<T>(
|
||||
val message: String,
|
||||
val result: T,
|
||||
val status: String
|
||||
)
|
||||
|
||||
data class LoginBean(
|
||||
val headPic: String,
|
||||
val nickName: String,
|
||||
val sex: Int,
|
||||
val signature: String,
|
||||
val token: String,
|
||||
val userId: Int
|
||||
)
|
||||
@@ -5,13 +5,39 @@ import androidx.fragment.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.example.defenseapplication.R
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.example.defenseapplication.adapter.DeviceAdapter
|
||||
import com.example.defenseapplication.adapter.DeviceUi
|
||||
import com.example.defenseapplication.adapter.FamilyAdapter
|
||||
import com.example.defenseapplication.databinding.HomeMenuFragmentBinding
|
||||
|
||||
class HomeMenuFragment : Fragment() {
|
||||
// ViewBinding
|
||||
private var _binding: HomeMenuFragmentBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val familyAdapter by lazy { FamilyAdapter(::onFamilySelected) }
|
||||
private val deviceAdapter by lazy { DeviceAdapter() }
|
||||
|
||||
private var isFamilyExpanded = false
|
||||
private var currentFamily = "我的家庭"
|
||||
|
||||
private val familyList = listOf("我的家庭", "工作室", "父母家")
|
||||
private val familyDeviceMap = mapOf(
|
||||
"我的家庭" to listOf(
|
||||
DeviceUi("智能挂式防御机", true),
|
||||
DeviceUi("智能防御机", false),
|
||||
DeviceUi("智能轨道防御机", false)
|
||||
),
|
||||
"工作室" to listOf(
|
||||
DeviceUi("走廊防御机", true),
|
||||
DeviceUi("门禁防御机", true)
|
||||
),
|
||||
"父母家" to listOf(
|
||||
DeviceUi("客厅防御机", false),
|
||||
DeviceUi("阳台防御机", true)
|
||||
)
|
||||
)
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@@ -19,11 +45,59 @@ class HomeMenuFragment : Fragment() {
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = HomeMenuFragmentBinding.inflate(inflater, container, false)
|
||||
initView()
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
binding.rvFamilyList.layoutManager = LinearLayoutManager(requireContext())
|
||||
binding.rvFamilyList.adapter = familyAdapter
|
||||
familyAdapter.submitList(familyList, currentFamily)
|
||||
|
||||
binding.rvDeviceList.layoutManager = GridLayoutManager(requireContext(), 2)
|
||||
binding.rvDeviceList.adapter = deviceAdapter
|
||||
updateDeviceList()
|
||||
|
||||
binding.tvCurrentFamily.text = currentFamily
|
||||
binding.familyHeaderLayout.setOnClickListener {
|
||||
toggleFamilyList()
|
||||
}
|
||||
binding.familyPopupMask.setOnClickListener {
|
||||
if (isFamilyExpanded) {
|
||||
toggleFamilyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleFamilyList() {
|
||||
isFamilyExpanded = !isFamilyExpanded
|
||||
val visibility = if (isFamilyExpanded) View.VISIBLE else View.GONE
|
||||
binding.familyPopupMask.visibility = visibility
|
||||
binding.familyPopupCard.visibility = visibility
|
||||
binding.ivFamilyArrow.animate()
|
||||
.rotation(if (isFamilyExpanded) 180f else 0f)
|
||||
.setDuration(200L)
|
||||
.start()
|
||||
}
|
||||
|
||||
private fun onFamilySelected(familyName: String) {
|
||||
currentFamily = familyName
|
||||
binding.tvCurrentFamily.text = familyName
|
||||
familyAdapter.submitList(familyList, currentFamily)
|
||||
updateDeviceList()
|
||||
if (isFamilyExpanded) {
|
||||
toggleFamilyList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateDeviceList() {
|
||||
deviceAdapter.submitList(familyDeviceMap[currentFamily].orEmpty())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
binding.rvFamilyList.adapter = null
|
||||
binding.rvDeviceList.adapter = null
|
||||
_binding = null // 避免内存泄漏
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package com.example.defenseapplication.login
|
||||
import android.os.Bundle
|
||||
import android.os.CountDownTimer
|
||||
import android.text.InputType
|
||||
import android.text.TextUtils
|
||||
import android.widget.Toast
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
@@ -12,6 +11,7 @@ import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.example.defenseapplication.R
|
||||
import com.example.defenseapplication.databinding.ForgetPasswordActivityBinding
|
||||
import com.google.firebase.crashlytics.buildtools.reloc.org.apache.http.util.TextUtils
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.random.Random
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.example.defenseapplication.okhttp
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import java.io.IOException
|
||||
|
||||
object ApiService {
|
||||
private const val BASE_URL = "https://stem-boozy-margarine.ngrok-free.dev"
|
||||
private val client = OkHttpClient()
|
||||
private val gson = Gson()
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.example.defenseapplication.utils
|
||||
|
||||
import com.google.gson.Gson
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.http.GET
|
||||
|
||||
interface ApiService {
|
||||
// 获取登录注册验证码
|
||||
@GET("/resource/sms/code")
|
||||
suspend fun getCode(): String
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.defenseapplication.okhttp
|
||||
package com.example.defenseapplication.utils
|
||||
|
||||
data class Post(
|
||||
val userId: Int,
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.example.defenseapplication.utils
|
||||
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Response
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
//网络工具类
|
||||
object HttpUtils {
|
||||
|
||||
val okHttpClient = OkHttpClient.Builder()
|
||||
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
|
||||
.writeTimeout(3, TimeUnit.MINUTES)
|
||||
.readTimeout(3, TimeUnit.MINUTES)
|
||||
.addInterceptor(object : Interceptor {
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val s = UserinfoUtil.getUserInfo()
|
||||
val aa = chain.request().newBuilder()
|
||||
.addHeader("token", s?.token ?: "")
|
||||
.addHeader("userId", "${s?.userId ?: 0}")
|
||||
.build()
|
||||
return chain.proceed(aa)
|
||||
}
|
||||
})
|
||||
.build()
|
||||
|
||||
val retrofit = Retrofit.Builder()
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.client(okHttpClient)
|
||||
.baseUrl("https://stem-boozy-margarine.ngrok-free.dev")
|
||||
.build()
|
||||
|
||||
|
||||
val api = retrofit.create(ApiService::class.java)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.example.defenseapplication.utils
|
||||
|
||||
import bean.LoginBean
|
||||
import com.blankj.utilcode.util.SPUtils
|
||||
import com.google.gson.Gson
|
||||
|
||||
//存储登录的token和userid
|
||||
object UserinfoUtil {
|
||||
|
||||
private const val KEY_USER = "NAME_USER"
|
||||
private val gson = Gson()
|
||||
|
||||
fun saveUserInfo(userinfo: LoginBean?) {
|
||||
userinfo ?: return
|
||||
val json = gson.toJson(userinfo)
|
||||
SPUtils.getInstance().put(KEY_USER, json)
|
||||
}
|
||||
|
||||
fun getUserInfo(): LoginBean? {
|
||||
val string = SPUtils.getInstance().getString(KEY_USER)
|
||||
if (string.isNullOrEmpty()) {
|
||||
return null
|
||||
}
|
||||
return gson.fromJson(string, LoginBean::class.java)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +1,174 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F9F9F9 "
|
||||
tools:context=".home.HomeMenuFragment">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingTop="20dp"
|
||||
android:paddingBottom="12dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/familyHeaderLayout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCurrentFamily"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="我的家庭"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="20dp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivFamilyArrow"
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="6dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:src="@drawable/triangle" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="38dp"
|
||||
android:layout_height="38dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:background="@drawable/bg_home_top_icon_light"
|
||||
android:padding="7dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/message"/>
|
||||
|
||||
<View
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_gravity="end|top"
|
||||
android:background="@drawable/ic_red_dot" />
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="38dp"
|
||||
android:layout_height="38dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:background="@drawable/bg_home_top_icon_light"
|
||||
android:padding="7dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/scan_icon"/>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="38dp"
|
||||
android:layout_height="38dp"
|
||||
android:background="@drawable/bg_home_top_icon_green"
|
||||
android:padding="7dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/add"/>
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDeviceTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="14dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="设备"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="16dp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<GridLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:columnCount="2"
|
||||
android:orientation="vertical"
|
||||
android:rowCount="1" >
|
||||
</GridLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvDeviceList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_weight="1"
|
||||
android:clipToPadding="false"
|
||||
android:nestedScrollingEnabled="false"
|
||||
android:paddingBottom="16dp"
|
||||
tools:itemCount="3"
|
||||
tools:listitem="@layout/item_device" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/familyPopupMask"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#4D000000"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/familyPopupCard"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="首页 Fragment"
|
||||
android:textSize="20sp"/>
|
||||
</LinearLayout>
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="62dp"
|
||||
android:background="@drawable/textinput_white_bg"
|
||||
android:elevation="8dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
android:padding="10dp">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvFamilyList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:nestedScrollingEnabled="false"
|
||||
tools:itemCount="3"
|
||||
tools:listitem="@layout/item_family" />
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
Reference in New Issue
Block a user