..
This commit is contained in:
@@ -4,6 +4,7 @@ import android.app.PendingIntent
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import androidx.wear.protolayout.ActionBuilders
|
||||
import androidx.wear.protolayout.ColorBuilders.argb
|
||||
import androidx.wear.protolayout.DimensionBuilders.dp
|
||||
@@ -38,7 +39,39 @@ class MainTileService : SuspendingTileService() {
|
||||
|
||||
override suspend fun tileRequest(
|
||||
requestParams: RequestBuilders.TileRequest
|
||||
) = tile(requestParams, this)
|
||||
): TileBuilders.Tile {
|
||||
// 💡 사용자가 방금 누른 버튼의 ID(path)를 가져옵니다.
|
||||
val clickedPath = requestParams.currentState.lastClickableId
|
||||
|
||||
// 눌린 버튼이 있다면 폰(런처)으로 메시지 전송!
|
||||
if (clickedPath.isNotEmpty()) {
|
||||
Log.d("MainTileService", "Clicked path: $clickedPath")
|
||||
|
||||
Wearable.getNodeClient(this).connectedNodes.addOnSuccessListener { nodes ->
|
||||
for (node in nodes) {
|
||||
Wearable.getMessageClient(this).sendMessage(node.id, clickedPath, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 타일 UI 렌더링
|
||||
val singleTileTimeline = TimelineBuilders.Timeline.Builder()
|
||||
.addTimelineEntry(
|
||||
TimelineBuilders.TimelineEntry.Builder()
|
||||
.setLayout(
|
||||
LayoutElementBuilders.Layout.Builder()
|
||||
.setRoot(tileLayout(requestParams, this))
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
|
||||
return TileBuilders.Tile.Builder()
|
||||
.setResourcesVersion(RESOURCES_VERSION)
|
||||
.setTileTimeline(singleTileTimeline)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
private fun resources(
|
||||
@@ -73,57 +106,56 @@ private fun tile(
|
||||
|
||||
private fun tileLayout(requestParams: RequestBuilders.TileRequest, context: Context): LayoutElementBuilders.LayoutElement {
|
||||
|
||||
fun createNavButton(label: String, path: String,x : Float, y :Float): LayoutElementBuilders.LayoutElement {
|
||||
// 리시버를 실행하기 위한 PendingIntent 생성
|
||||
val intent = Intent(context, TileActionReceiver::class.java).apply {
|
||||
putExtra("path", path)
|
||||
}
|
||||
val pendingIntent = PendingIntent.getBroadcast(
|
||||
context, path.hashCode(), intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
// 버튼 생성 함수 (크기를 48dp로 살짝 줄여서 화면에 쏙 들어가게 맞춤)
|
||||
fun createNavButton(label: String, path: String): LayoutElementBuilders.LayoutElement {
|
||||
return LayoutElementBuilders.Box.Builder()
|
||||
.setModifiers(ModifiersBuilders.Modifiers.Builder()
|
||||
.setClickable(ModifiersBuilders.Clickable.Builder()
|
||||
.setOnClick(ActionBuilders.LaunchAction.Builder()
|
||||
.setAndroidActivity(ActionBuilders.AndroidActivity.Builder()
|
||||
.setPackageName(context.packageName)
|
||||
.setClassName(TileActionReceiver::class.java.name) // 리시버 호출
|
||||
.build())
|
||||
.build())
|
||||
.build())
|
||||
.setTransformation(ModifiersBuilders.Transformation.Builder()
|
||||
// 방향에 따라 x, y 좌표 조절 (상: 0,-45 / 하: 0,45 / 좌: -45,0 / 우: 45,0)
|
||||
.setTranslationX(dp(x))
|
||||
.setTranslationY(dp(y))
|
||||
.setId(path)
|
||||
.setOnClick(ActionBuilders.LoadAction.Builder().build())
|
||||
.build())
|
||||
.setBackground(ModifiersBuilders.Background.Builder()
|
||||
.setColor(argb(0xFF303030.toInt()))
|
||||
.setCorner(ModifiersBuilders.Corner.Builder().setRadius(dp(15f)).build())
|
||||
.setCorner(ModifiersBuilders.Corner.Builder().setRadius(dp(24f)).build()) // 원형에 가깝게
|
||||
.build())
|
||||
.build())
|
||||
.setWidth(dp(56f)).setHeight(dp(56f))
|
||||
.addContent(Text.Builder(context, label).build())
|
||||
.setWidth(dp(48f)).setHeight(dp(48f))
|
||||
.addContent(
|
||||
Text.Builder(context, label)
|
||||
.setTypography(Typography.TYPOGRAPHY_CAPTION2) // 글자 크기 최적화
|
||||
.setColor(argb(0xFFFFFFFF.toInt()))
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
return PrimaryLayout.Builder(requestParams.deviceConfiguration)
|
||||
.setContent(
|
||||
LayoutElementBuilders.Box.Builder()
|
||||
// 상 (UP): X는 그대로, Y만 위로(-45dp)
|
||||
.addContent(createNavButton("UP", "/gesture/up", 0f, -50f))
|
||||
// 1층: 제일 위에 UP 버튼 하나만
|
||||
val topRow = LayoutElementBuilders.Row.Builder()
|
||||
.addContent(createNavButton("UP", "/gesture/up"))
|
||||
.build()
|
||||
|
||||
// 하 (DOWN): X는 그대로, Y만 아래로(+50dp)
|
||||
.addContent(createNavButton("DOWN", "/gesture/down", 0f, 50f))
|
||||
// 2층: 중간에 LEFT, 빈 공간, RIGHT 배치
|
||||
val middleRow = LayoutElementBuilders.Row.Builder()
|
||||
.addContent(createNavButton("LEFT", "/gesture/left"))
|
||||
// 좌우 버튼 사이의 널찍한 빈 공간 (UP/DOWN 버튼이 들어갈 간격)
|
||||
.addContent(LayoutElementBuilders.Spacer.Builder().setWidth(dp(56f)).build())
|
||||
.addContent(createNavButton("RIGHT", "/gesture/right"))
|
||||
.build()
|
||||
|
||||
// 좌 (LEFT): X를 왼쪽으로(-50dp), Y는 그대로
|
||||
.addContent(createNavButton("LEFT", "/gesture/left", -50f, 0f))
|
||||
// 3층: 제일 아래에 DOWN 버튼 하나만
|
||||
val bottomRow = LayoutElementBuilders.Row.Builder()
|
||||
.addContent(createNavButton("DOWN", "/gesture/down"))
|
||||
.build()
|
||||
|
||||
// 우 (RIGHT): X를 오른쪽으로(+50dp), Y는 그대로
|
||||
.addContent(createNavButton("RIGHT", "/gesture/right", 50f, 0f))
|
||||
.build()
|
||||
).build()
|
||||
// 전체를 세로로 정렬하여 합체
|
||||
return LayoutElementBuilders.Column.Builder()
|
||||
.setHorizontalAlignment(LayoutElementBuilders.HORIZONTAL_ALIGN_CENTER) // 가운데 정렬 필수
|
||||
.addContent(topRow)
|
||||
.addContent(LayoutElementBuilders.Spacer.Builder().setHeight(dp(8f)).build()) // 1~2층 간격
|
||||
.addContent(middleRow)
|
||||
.addContent(LayoutElementBuilders.Spacer.Builder().setHeight(dp(8f)).build()) // 2~3층 간격
|
||||
.addContent(bottomRow)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user