save code

This commit is contained in:
xsl
2026-04-26 00:12:56 +08:00
parent 50680ee854
commit c5ec7c7dc5
22 changed files with 1170 additions and 216 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ android {
defaultConfig {
applicationId "com.inewme.uvmirror.f20260113"
minSdk 30
minSdk 29
targetSdk 36
versionCode 1
versionName "1.0"
+5 -1
View File
@@ -23,7 +23,11 @@
<activity
android:name=".MakeupActivity"
android:exported="false" />
android:exported="false"
android:screenOrientation="portrait"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|keyboard|navigation|smallestScreenSize" />
<!-- MakeupActivity 继承 FaceActivityface_sdk 渲染目前只支持竖屏。
configChanges 与 FaceActivity 保持一致,避免软键盘/导航栏触发重建。 -->
</application>
</manifest>
@@ -5,16 +5,27 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.selection.selectable
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import androidx.compose.ui.tooling.preview.Preview
import androidx.camera.core.CameraSelector
import com.hmwl.face_sdk.FaceActivity
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -36,17 +47,30 @@ fun MyApp(modifier: Modifier = Modifier) {
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
val context = LocalContext.current // 获取上下文用于启动 Activity
val context = LocalContext.current
// 默认前置:化妆/美妆类典型场景。
// 用 CameraSelector.LENS_FACING_FRONT / LENS_FACING_BACK 直接当 state,省去
// 中间枚举类型,最后通过 Intent extra 透传给 FaceActivity。
var lensFacing by remember { mutableStateOf(CameraSelector.LENS_FACING_FRONT) }
Column(
modifier = modifier.padding(16.dp)
) {
Text(text = "Hello $name!")
LensFacingRadioGroup(
selected = lensFacing,
onSelected = { lensFacing = it }
)
Button(
onClick = {
// 跳转到 MakeupActivity
val intent = Intent(context, MakeupActivity::class.java)
val intent = Intent(context, MakeupActivity::class.java).apply {
// FaceActivity 在 onCreate 里读这个 extra 来决定 CameraSelector 朝向
// 与 isFrontCamera 镜像逻辑;缺省时(旧调用方)走 LENS_FACING_BACK
// 向后兼容。
putExtra(FaceActivity.EXTRA_LENS_FACING, lensFacing)
}
context.startActivity(intent)
}
) {
@@ -55,10 +79,43 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
}
}
@Composable
private fun LensFacingRadioGroup(
selected: Int,
onSelected: (Int) -> Unit,
modifier: Modifier = Modifier
) {
val options = listOf(
CameraSelector.LENS_FACING_FRONT to "前置摄像头",
CameraSelector.LENS_FACING_BACK to "后置摄像头"
)
Column(modifier = modifier.padding(vertical = 8.dp)) {
Text(text = "摄像头朝向")
options.forEach { (value, label) ->
Row(
modifier = Modifier
.selectable(
selected = (value == selected),
onClick = { onSelected(value) },
role = Role.RadioButton
)
.padding(vertical = 4.dp),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = (value == selected),
onClick = null
)
Text(text = label, modifier = Modifier.padding(start = 8.dp))
}
}
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
MaterialTheme {
Greeting("Android")
}
}
}
@@ -8,6 +8,7 @@ import android.view.KeyEvent.KEYCODE_BACK
import android.view.MotionEvent
import androidx.lifecycle.lifecycleScope
import com.hmwl.face_sdk.DebugLog
import com.hmwl.face_sdk.FaceActivity
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
@@ -29,9 +30,12 @@ class MakeupActivity : FaceActivity()
}
}
DebugLog.i("MakeupActivity", "onCreate: starting LoadMotionList(sequenceAll=$sequenceAll)")
// 首先一次性加载当前业务逻辑所要求的所有动画资源, 之后就可以任意跳转,和播放,不用考虑状态
motionMgr.LoadMotionList(sequenceAll){
//当加载完成了所有资源后会回调
DebugLog.i("MakeupActivity",
"LoadMotionList callback fired -> isMotionLoadFinished=true (sequenceAll=$sequenceAll)")
isMotionLoadFinished = true
}
}
@@ -58,6 +62,7 @@ class MakeupActivity : FaceActivity()
if(isMotionLoadFinished)
{
if(elapsedTime == 0){
DebugLog.i("MakeupActivity", "update: first call -> PlayMotionList(sequenceA=$sequenceA, loop=true)")
//这次播放是一直循环播放,我们不需要判断动画是否播放完成, 回调函数直接传入null
PlayMotionList(sequenceA, true, null)
}
@@ -65,17 +70,21 @@ class MakeupActivity : FaceActivity()
elapsedTime += 10 // 动画加载完成后开始计时,每次调用增加 10ms
if(elapsedTime == 10*1000){
DebugLog.i("MakeupActivity", "update: 10s tick -> StopMotion()")
//暂停动画
StopMotion()
}
if(elapsedTime == 10*1000 + 5*1000){
DebugLog.i("MakeupActivity", "update: 15s tick -> ResumeMotion()")
//恢复播放动画
ResumeMotion()
}
if(elapsedTime == 10*1000 + 5*1000 + 8*1000){
DebugLog.i("MakeupActivity", "update: 23s tick -> PlayMotionList(sequenceB=$sequenceB, loop=true)")
PlayMotionList(sequenceB, true){
DebugLog.i("MakeupActivity", "sequenceB cb -> PlayMotionList(sequenceA, loop=true)")
//这里是播放完动画后的回调,再次切换到原来的 sequenceA
PlayMotionList(sequenceA, true, null)
}