添加了密码登录和人脸登录界面

This commit is contained in:
zxj
2025-07-16 10:57:52 +08:00
parent 751aa9e710
commit 229591dcb3
24 changed files with 545 additions and 36 deletions
+23 -2
View File
@@ -2,6 +2,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:name=".MyApp"
android:allowBackup="true"
@@ -14,14 +21,28 @@
android:theme="@style/Theme.SmartPlateCabinet"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
android:name=".activity.LoginByPwdActivity"
android:exported="false"
android:launchMode="singleTask" />
<activity
android:name=".activity.LoginByFaceActivity"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activity.MainActivity"
android:exported="true">
<!-- <intent-filter>-->
<!-- <action android:name="android.intent.action.MAIN" />-->
<!-- <category android:name="android.intent.category.LAUNCHER" />-->
<!-- </intent-filter>-->
</activity>
</application>
</manifest>
@@ -1,20 +0,0 @@
package com.sw.platecabinet
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
}
}
@@ -0,0 +1,40 @@
package com.sw.platecabinet.activity
import android.content.Context
import android.os.Bundle
import android.view.WindowManager
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
/**
* activity 基类
*/
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
protected lateinit var binding: VB
private set
protected lateinit var context: Context
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
context = this
binding = inflateViewBinding()
setContentView(binding.root)
initialize()
}
protected abstract fun inflateViewBinding(): VB
protected abstract fun initialize()
override fun onDestroy() {
super.onDestroy()
}
}
@@ -0,0 +1,73 @@
package com.sw.platecabinet.activity
import android.content.Intent
import android.graphics.Outline
import android.view.View
import android.view.ViewOutlineProvider
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import com.google.common.util.concurrent.ListenableFuture
import com.sw.platecabinet.databinding.ActivityLoginFaceBinding
import timber.log.Timber
/**
* 人脸识别
*/
class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>() {
private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
override fun inflateViewBinding(): ActivityLoginFaceBinding {
return ActivityLoginFaceBinding.inflate(layoutInflater)
}
override fun initialize() {
initView()
startCamera()
binding.llToPwd.setOnClickListener {
val intent = Intent(this, LoginByPwdActivity::class.java)
startActivity(intent)
}
}
private fun initView() {
binding.previewView.outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
// outline.setRoundRect(0, 0, view.width, view.height, 12f.dp)
outline.setOval(0, 0, view.width, view.height)
}
}
binding.previewView.clipToOutline = true
}
private fun startCamera() {
cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
val cameraProvider = cameraProviderFuture.get()
// 创建预览用例
val preview = Preview.Builder()
.build()
.also {
it.setSurfaceProvider(binding.previewView.surfaceProvider)
}
// 选择后置摄像头
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
// 解绑所有用例
cameraProvider.unbindAll()
// 绑定到生命周期
cameraProvider.bindToLifecycle(
this, cameraSelector, preview
)
} catch (exc: Exception) {
Timber.e(exc, "Use case binding failed")
}
}, ContextCompat.getMainExecutor(this))
}
}
@@ -0,0 +1,18 @@
package com.sw.platecabinet.activity
import android.content.Intent
import com.sw.platecabinet.databinding.ActivityLoginByPwdBinding
class LoginByPwdActivity : BaseActivity<ActivityLoginByPwdBinding>() {
override fun inflateViewBinding(): ActivityLoginByPwdBinding {
return ActivityLoginByPwdBinding.inflate(layoutInflater)
}
override fun initialize() {
binding.tvFaceRec.setOnClickListener {
val intent = Intent(this, LoginByFaceActivity::class.java)
startActivity(intent)
}
}
}
@@ -0,0 +1,14 @@
package com.sw.platecabinet.activity
import com.sw.platecabinet.databinding.ActivityMainBinding
class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun inflateViewBinding(): ActivityMainBinding {
return ActivityMainBinding.inflate(layoutInflater)
}
override fun initialize() {
}
}
@@ -0,0 +1,49 @@
package com.sw.platecabinet.ext
import android.content.res.Resources
import android.util.TypedValue
import androidx.annotation.Dimension
/**
* 将 Int 值转换为 dp 值
*/
val Int.dp: Int
@Dimension(unit = Dimension.DP)
get() = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
this.toFloat(),
Resources.getSystem().displayMetrics
).toInt()
/**
* 将 Float 值转换为 dp 值
*/
val Float.dp: Float
@Dimension(unit = Dimension.DP)
get() = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
this,
Resources.getSystem().displayMetrics
)
/**
* 将 Int 值转换为 sp 值
*/
val Int.sp: Float
@Dimension(unit = Dimension.SP)
get() = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,
this.toFloat(),
Resources.getSystem().displayMetrics
)
/**
* 将 Float 值转换为 sp 值
*/
val Float.sp: Float
@Dimension(unit = Dimension.SP)
get() = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,
this,
Resources.getSystem().displayMetrics
)
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="12dp" />
<stroke
android:width="2dp"
android:color="#887872" />
</shape>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:inset="0dp">
<shape android:shape="oval">
<stroke
android:width="2dp"
android:color="#8C7D76"
android:dashWidth="8dp"
android:dashGap="4dp" />
<solid android:color="@android:color/transparent" />
</shape>
</inset>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/transparent" />
<!-- 边框设置 -->
<stroke
android:width="2dp"
android:color="#19ECE7D0" />
<!-- 圆角半径 -->
<corners android:radius="24dp" />
</shape>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="12dp" />
<!-- <solid android:color="#F3D2BD"/>-->
<gradient
android:endColor="#E5B79F"
android:startColor="#F9DDC9" />
</shape>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="12dp" />
<stroke
android:width="2dp"
android:color="#F0C8B4" />
</shape>
@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/bg"
android:orientation="vertical">
<include layout="@layout/item_title_time" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:paddingStart="60dp"
android:paddingEnd="60dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="手机后四位"
android:textColor="#F0C8B4"
android:textSize="26sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginTop="23dp"
android:background="@drawable/shape_pwd_bg"
android:gravity="center_vertical">
<ImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="24dp"
android:layout_marginEnd="55dp"
android:src="@mipmap/ic_phone" />
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="20dp"
android:background="@android:color/transparent"
android:hint="输入手机后四位"
android:inputType="number"
android:maxLength="4"
android:maxLines="1"
android:textColor="#F3D2BD"
android:textColorHint="#7B6D6A"
android:textSize="26sp"
android:textStyle="bold" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:text="校验码"
android:textColor="#F0C8B4"
android:textSize="26sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginTop="23dp"
android:background="@drawable/shape_pwd_bg"
android:gravity="center_vertical">
<ImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="24dp"
android:layout_marginEnd="55dp"
android:src="@mipmap/ic_password" />
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="20dp"
android:background="@android:color/transparent"
android:hint="输入校验码"
android:inputType="textPassword"
android:maxLines="1"
android:textColor="#F3D2BD"
android:textColorHint="#7B6D6A"
android:textSize="26sp"
android:textStyle="bold" />
</LinearLayout>
<android.widget.Button
android:id="@+id/btnLogin"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginTop="46dp"
android:background="@drawable/shape_btn_bg"
android:text="登录"
android:textColor="#11111C"
android:textSize="30sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvFaceRec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:padding="8dp"
android:text="人脸识别"
android:textColor="#887872"
android:textSize="26sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
@@ -0,0 +1,71 @@
<?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/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/bg"
android:orientation="vertical"
tools:context=".activity.LoginByFaceActivity">
<include layout="@layout/item_title_time" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/tv_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="159dp"
android:text="请正视屏幕"
android:textColor="#fff0c8b4"
android:textSize="36sp" />
<FrameLayout
android:layout_width="380dp"
android:layout_height="380dp"
android:layout_marginTop="119dp"
android:padding="10dp"
android:visibility="visible">
<androidx.camera.view.PreviewView
android:id="@+id/previewView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:background="@drawable/circle_dashed_border" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/bg_face" />
</FrameLayout>
<LinearLayout
android:id="@+id/ll_to_pwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="120dp"
android:background="@drawable/btn_outline_887872"
android:gravity="center"
android:paddingHorizontal="45dp"
android:paddingVertical="18dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密码登录"
android:textColor="#ff887872"
android:textSize="24sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
+1 -10
View File
@@ -1,19 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
tools:context=".activity.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="24dp">
<TextView
android:id="@+id/tvLeftDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textColor="#F0C8B4"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="2025年6月18日 星期三" />
<TextView
android:id="@+id/tvRightTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textColor="#F0C8B4"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tvLeftDate"
tools:text="14:02:39" />
</androidx.constraintlayout.widget.ConstraintLayout>
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

+1 -2
View File
@@ -2,6 +2,5 @@
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="color_bg_notification">#80000000</color>
<color name="transparent">#00000000</color>
</resources>