v9.0.0 设置页/商店页遥控焦点高亮(获得焦点变蓝)+商店手动导航
This commit is contained in:
1 parent
1798429a2f
commit
6ae217b9cd
3 files changed
+135
-29
No files matched your search
@@ -27,6 +27,29 @@ class SettingsActivity : Activity() {
|
||||
|
||||
private lateinit var statusText: TextView
|
||||
|
||||
/** 焦点高亮背景:获得焦点→蓝色,普通→深灰 */
|
||||
private fun focusBg(normal: Int = 0xFF2A2F3A.toInt(), focused: Int = 0xFF1B6EF3.toInt())
|
||||
: android.graphics.drawable.StateListDrawable {
|
||||
val sl = android.graphics.drawable.StateListDrawable()
|
||||
sl.addState(intArrayOf(android.R.attr.state_focused), android.graphics.drawable.ColorDrawable(focused))
|
||||
sl.addState(intArrayOf(), android.graphics.drawable.ColorDrawable(normal))
|
||||
return sl
|
||||
}
|
||||
|
||||
/** 可聚焦的操作行(代替固定背景的 Button,保证遥控器上能看到选中) */
|
||||
private fun mkAction(label: String, onClick: () -> Unit): TextView =
|
||||
TextView(this).apply {
|
||||
text = label
|
||||
textSize = 17f
|
||||
setTextColor(Color.WHITE)
|
||||
gravity = Gravity.CENTER
|
||||
setPadding(24, 26, 24, 26)
|
||||
isFocusable = true
|
||||
isFocusableInTouchMode = true
|
||||
background = focusBg()
|
||||
setOnClickListener { onClick() }
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
try {
|
||||
@@ -44,7 +67,12 @@ class SettingsActivity : Activity() {
|
||||
setBackgroundColor(Color.parseColor("#12141A"))
|
||||
setPadding(96, 64, 96, 64)
|
||||
}
|
||||
setContentView(root)
|
||||
val scroll = android.widget.ScrollView(this).apply {
|
||||
setBackgroundColor(Color.parseColor("#12141A"))
|
||||
isFillViewport = true
|
||||
}
|
||||
scroll.addView(root)
|
||||
setContentView(scroll)
|
||||
|
||||
root.addView(TextView(this).apply {
|
||||
text = "设置"
|
||||
@@ -88,7 +116,9 @@ class SettingsActivity : Activity() {
|
||||
isChecked = isBootReceiverEnabled()
|
||||
val pad = (24 * resources.displayMetrics.density).toInt()
|
||||
setPadding(pad, pad / 2, pad, pad / 2)
|
||||
setBackgroundColor(Color.parseColor("#1C2028"))
|
||||
isFocusable = true
|
||||
isFocusableInTouchMode = true
|
||||
background = focusBg(normal = 0xFF1C2028.toInt())
|
||||
}
|
||||
bootSwitch.setOnCheckedChangeListener { _, checked ->
|
||||
val pm = packageManager
|
||||
@@ -135,20 +165,17 @@ class SettingsActivity : Activity() {
|
||||
textSize = 16f
|
||||
setTextColor(Color.WHITE)
|
||||
setHintTextColor(Color.parseColor("#888888"))
|
||||
setBackgroundColor(Color.parseColor("#1C2028"))
|
||||
setPadding(24, 20, 24, 20)
|
||||
isSingleLine = true
|
||||
isFocusable = true
|
||||
isFocusableInTouchMode = true
|
||||
background = focusBg(normal = 0xFF1C2028.toInt())
|
||||
inputType = android.text.InputType.TYPE_CLASS_TEXT
|
||||
}
|
||||
root.addView(cardInput, LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT).apply { bottomMargin = 12 })
|
||||
|
||||
val actBtn = Button(this).apply {
|
||||
text = "激活"
|
||||
textSize = 17f
|
||||
setBackgroundColor(Color.parseColor("#1B6EF3"))
|
||||
setOnClickListener { doActivate(cardInput.text.toString().trim()) }
|
||||
}
|
||||
val actBtn = mkAction("激活") { doActivate(cardInput.text.toString().trim()) }
|
||||
root.addView(actBtn, LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT).apply { bottomMargin = 40 })
|
||||
|
||||
@@ -159,11 +186,8 @@ class SettingsActivity : Activity() {
|
||||
gravity = Gravity.CENTER; setPadding(0, 24, 0, 24)
|
||||
})
|
||||
} else {
|
||||
val btn = Button(this).apply {
|
||||
text = "支付成为会员(月/季/年)"
|
||||
textSize = 17f
|
||||
setBackgroundColor(Color.parseColor("#1B6EF3"))
|
||||
setOnClickListener { startActivity(Intent(this@SettingsActivity, ShopActivity::class.java)) }
|
||||
val btn = mkAction("支付成为会员(月/季/年)") {
|
||||
startActivity(Intent(this@SettingsActivity, ShopActivity::class.java))
|
||||
}
|
||||
root.addView(btn, LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT))
|
||||
|
||||
@@ -33,11 +33,44 @@ class ShopActivity : Activity() {
|
||||
data class Plan(val id: Int, val name: String, val price: String, val days: Int)
|
||||
|
||||
private lateinit var list: ListView
|
||||
private var rowAdapterRef: RowAdapter? = null
|
||||
private lateinit var alipay: TextView
|
||||
private lateinit var wxpay: TextView
|
||||
private var shopZone = 0 // 0=套餐列表 1=支付方式
|
||||
private lateinit var statusText: TextView
|
||||
private var payType = "alipay"
|
||||
private var orderNo = ""
|
||||
private var machineId = ""
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
|
||||
/** 高亮自控的行适配器 */
|
||||
private inner class RowAdapter(private var items: List<String>) : android.widget.BaseAdapter() {
|
||||
var selected = 0
|
||||
set(value) { field = value; notifyDataSetChanged() }
|
||||
fun setItems(v: List<String>) { items = v; notifyDataSetChanged() }
|
||||
override fun getCount(): Int = items.size
|
||||
override fun getItem(position: Int): Any = items[position]
|
||||
override fun getItemId(position: Int): Long = position.toLong()
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
|
||||
val tv = (convertView as? TextView) ?: TextView(this@ShopActivity).apply {
|
||||
textSize = 18f; setPadding(36, 26, 36, 26)
|
||||
isSingleLine = true
|
||||
ellipsize = android.text.TextUtils.TruncateAt.END
|
||||
}
|
||||
tv.text = items[position]
|
||||
val on = position == selected
|
||||
tv.setBackgroundColor(if (on) Color.parseColor("#1B6EF3") else Color.parseColor("#1C1F26"))
|
||||
tv.setTextColor(Color.WHITE)
|
||||
return tv
|
||||
}
|
||||
}
|
||||
|
||||
private fun focusBg(normal: Int, focused: Int): android.graphics.drawable.StateListDrawable {
|
||||
val sl = android.graphics.drawable.StateListDrawable()
|
||||
sl.addState(intArrayOf(android.R.attr.state_focused), android.graphics.drawable.ColorDrawable(focused))
|
||||
sl.addState(intArrayOf(), android.graphics.drawable.ColorDrawable(normal))
|
||||
return sl
|
||||
}
|
||||
private var pollTask: Runnable? = null
|
||||
private var pollCount = 0
|
||||
|
||||
@@ -76,6 +109,10 @@ class ShopActivity : Activity() {
|
||||
|
||||
list = ListView(this).apply {
|
||||
setBackgroundColor(Color.parseColor("#1C1F26"))
|
||||
setSelector(android.graphics.drawable.ColorDrawable(Color.TRANSPARENT))
|
||||
isFocusable = false
|
||||
isFocusableInTouchMode = false
|
||||
setItemsCanFocus(false)
|
||||
}
|
||||
root.addView(list, LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f
|
||||
@@ -88,15 +125,16 @@ class ShopActivity : Activity() {
|
||||
root.addView(statusText)
|
||||
|
||||
val row = LinearLayout(this).apply { orientation = LinearLayout.HORIZONTAL }
|
||||
val alipay = Button(this).apply { text = "支付宝"; textSize = 15f }
|
||||
val wxpay = Button(this).apply { text = "微信"; textSize = 15f }
|
||||
fun sel(b: Button, t: String) {
|
||||
val active = payType == t
|
||||
b.setBackgroundColor(if (active) Color.parseColor("#1B6EF3") else Color.parseColor("#2A2F3A"))
|
||||
fun mkPay(label: String, t: String) = TextView(this).apply {
|
||||
text = label; textSize = 16f
|
||||
setTextColor(Color.WHITE); gravity = Gravity.CENTER
|
||||
setPadding(24, 26, 24, 26)
|
||||
isFocusable = true; isFocusableInTouchMode = true
|
||||
background = focusBg(0xFF2A2F3A.toInt(), 0xFF1B6EF3.toInt())
|
||||
setOnClickListener { payType = t; refreshPayBtns() }
|
||||
}
|
||||
alipay.setOnClickListener { payType = "alipay"; sel(alipay, "alipay"); sel(wxpay, "wxpay") }
|
||||
wxpay.setOnClickListener { payType = "wxpay"; sel(alipay, "alipay"); sel(wxpay, "wxpay") }
|
||||
sel(alipay, "alipay"); sel(wxpay, "wxpay")
|
||||
alipay = mkPay("支付宝", "alipay")
|
||||
wxpay = mkPay("微信", "wxpay")
|
||||
row.addView(alipay, LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f).apply { rightMargin = 16 })
|
||||
row.addView(wxpay, LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f))
|
||||
root.addView(row)
|
||||
@@ -104,10 +142,20 @@ class ShopActivity : Activity() {
|
||||
list.onItemClickListener = AdapterView.OnItemClickListener { _, _, pos, _ ->
|
||||
if (pos < plans.size) createOrder(plans[pos])
|
||||
}
|
||||
refreshPayBtns()
|
||||
|
||||
loadPlans()
|
||||
}
|
||||
|
||||
/** 当前支付方式:亮蓝 + 焦点时更亮 */
|
||||
private fun refreshPayBtns() {
|
||||
val a = payType == "alipay"
|
||||
alipay.setBackgroundColor(Color.parseColor(if (a) "#1B6EF3" else "#2A2F3A"))
|
||||
wxpay.setBackgroundColor(Color.parseColor(if (a) "#2A2F3A" else "#1B6EF3"))
|
||||
alipay.alpha = if (a) 1f else 0.75f
|
||||
wxpay.alpha = if (a) 0.75f else 1f
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun loadPlans() {
|
||||
statusText.text = "加载套餐…"
|
||||
@@ -130,11 +178,13 @@ class ShopActivity : Activity() {
|
||||
}
|
||||
runOnUiThread {
|
||||
plans.sortBy { it.days }
|
||||
list.adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, plans.map {
|
||||
val ra = RowAdapter(plans.map {
|
||||
val d = it.days
|
||||
"📱 ${it.name} ¥${it.price} ${if (d >= 999) "永久" else "${d}天"}"
|
||||
})
|
||||
statusText.text = "选择套餐后按 OK 购买"
|
||||
rowAdapterRef = ra
|
||||
list.adapter = ra
|
||||
statusText.text = "上下选择套餐,OK 购买;左右可切支付方式"
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
runOnUiThread { statusText.text = "加载失败: ${e.javaClass.simpleName}: ${e.message?.take(150)}" }
|
||||
@@ -237,9 +287,41 @@ class ShopActivity : Activity() {
|
||||
}
|
||||
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && pollTask != null) {
|
||||
// 支付轮询中返回 → 取消轮询
|
||||
handler.removeCallbacks(pollTask!!); pollTask = null
|
||||
// 支付中:回归普通处理
|
||||
if (pollTask != null) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) { handler.removeCallbacks(pollTask!!); pollTask = null }
|
||||
return super.onKeyDown(keyCode, event)
|
||||
}
|
||||
val ra = rowAdapterRef
|
||||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN -> {
|
||||
val delta = if (keyCode == KeyEvent.KEYCODE_DPAD_UP) -1 else 1
|
||||
if (shopZone == 0 && ra != null && ra.count > 0) {
|
||||
val np = ra.selected + delta
|
||||
if (np < 0) { shopZone = 1; refreshPayBtns(); alipay.requestFocus() }
|
||||
else { ra.selected = np.coerceAtMost(ra.count - 1); list.setSelection(ra.selected) }
|
||||
} else if (shopZone == 1) {
|
||||
if (delta > 0) { } else { shopZone = 0; ra?.let { list.setSelection(it.selected) } }
|
||||
}
|
||||
return true
|
||||
}
|
||||
KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT -> {
|
||||
if (shopZone == 1) { payType = if (payType == "alipay") "wxpay" else "alipay"; refreshPayBtns() }
|
||||
else if (ra != null && ra.count > 0) {
|
||||
// 列表里左右也可切支付方式,方便一步到位
|
||||
payType = if (payType == "alipay") "wxpay" else "alipay"; refreshPayBtns()
|
||||
}
|
||||
return true
|
||||
}
|
||||
KeyEvent.KEYCODE_DPAD_CENTER, KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_NUMPAD_ENTER -> {
|
||||
if (shopZone == 1) { payType = if (payType == "alipay") "wxpay" else "alipay"; refreshPayBtns() }
|
||||
else {
|
||||
val pos = ra?.selected ?: -1
|
||||
if (pos in plans.indices) createOrder(plans[pos])
|
||||
}
|
||||
return true
|
||||
}
|
||||
KeyEvent.KEYCODE_BACK -> { finish(); return true }
|
||||
}
|
||||
return super.onKeyDown(keyCode, event)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user