多数页面完成

This commit is contained in:
pengxiaolong
2025-12-05 20:48:22 +08:00
parent 242d690e17
commit 867dad509e
68 changed files with 2663 additions and 1174 deletions

View File

@@ -67,4 +67,11 @@ dependencies {
implementation("androidx.navigation:navigation-compose:2.7.5")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
implementation("com.squareup.retrofit2:retrofit:2.11.0")
implementation("com.squareup.retrofit2:converter-gson:2.11.0")
// 协程(如果还没加)
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0")
}

View File

@@ -3,8 +3,12 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication">
@@ -21,6 +25,16 @@
</intent-filter>
</activity>
<!-- 输入法激活页(强烈建议增加) -->
<activity
android:name=".ImeGuideActivity"
android:exported="true"/>
<!-- 输入法体验页 -->
<activity
android:name=".GuideActivity"
android:exported="true"/>
<!-- 引导页 -->
<activity
android:name=".OnboardingActivity"

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

View File

@@ -0,0 +1,29 @@
package com.example.myapplication
import android.content.ComponentName
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.provider.Settings
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Button
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.FrameLayout
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.myapplication.MyInputMethodService
class GuideActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_guide)
findViewById<FrameLayout>(R.id.iv_close).setOnClickListener {
finish()
}
}
}

View File

@@ -0,0 +1,203 @@
package com.example.myapplication
import android.content.ComponentName
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.provider.Settings
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Button
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.FrameLayout
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.myapplication.MyInputMethodService
class ImeGuideActivity : AppCompatActivity() {
private lateinit var btnEnable: LinearLayout
private lateinit var btnSelect: LinearLayout
private lateinit var tvStep1Status: TextView//
private lateinit var tvStep2Status: TextView//
private lateinit var btnEnabledText: TextView//
private lateinit var btnSelectText: TextView//
private lateinit var btnEnabledimg: ImageView//
private lateinit var btnSelectimg: ImageView//
private var imeObserver: android.database.ContentObserver? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_ime_guide)
// // 设置关闭按钮点击事件
// findViewById<FrameLayout>(R.id.iv_close).setOnClickListener {
// finish()
// }
btnEnable = findViewById(R.id.enabled)//btn启用输入法
btnSelect = findViewById(R.id.select)//btn选择输入法
tvStep1Status = findViewById(R.id.Steps)//第一步的提示
tvStep2Status = findViewById(R.id.stepTips)//第二步的提示
btnEnabledText = findViewById(R.id.btnEnabledText)//启用输入法按钮文字
btnSelectText = findViewById(R.id.btnSelectText)//选择输入法按钮文字
btnEnabledimg = findViewById(R.id.btnEnabledimg)//启用输入法按钮图片
btnSelectimg = findViewById(R.id.btnSelectimg)//选择输入法按钮图片
// // 第一步:启用输入法
// btnEnable.setOnClickListener {
// startActivity(Intent(Settings.ACTION_INPUT_METHOD_SETTINGS))
// }
// // 第二步:切换输入法
// btnSelect.setOnClickListener {
// val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
// imm.showInputMethodPicker()
// }
}
override fun onResume() {
super.onResume()
refreshStatus()
registerImeObserver()
}
override fun onPause() {
super.onPause()
unregisterImeObserver()
}
private fun registerImeObserver() {
if (imeObserver != null) return
imeObserver = object : android.database.ContentObserver(
android.os.Handler(android.os.Looper.getMainLooper())
) {
override fun onChange(selfChange: Boolean) {
super.onChange(selfChange)
refreshStatus()
}
}
contentResolver.registerContentObserver(
android.provider.Settings.Secure.getUriFor(
android.provider.Settings.Secure.DEFAULT_INPUT_METHOD
),
false,
imeObserver!!
)
}
private fun unregisterImeObserver() {
imeObserver?.let {
contentResolver.unregisterContentObserver(it)
}
imeObserver = null
}
/** 刷新步骤状态(是否启用/选择) */
private fun refreshStatus() {
val enabled = isImeEnabled()
val selected = isImeSelected()
// 根据状态设置按钮的点击行为
if (enabled) {
// 输入法已启用时,禁用启用按钮的点击事件
btnEnable.setOnClickListener(null)
} else {
// 输入法未启用时,设置启用按钮的点击事件
btnEnable.setOnClickListener {
startActivity(Intent(Settings.ACTION_INPUT_METHOD_SETTINGS))
}
}
if (selected) {
// 输入法已切换时,禁用选择按钮的点击事件
btnSelect.setOnClickListener(null)
} else {
// 输入法未切换时,设置选择按钮的点击事件
btnSelect.setOnClickListener {
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.showInputMethodPicker()
}
}
if(!enabled &&!selected) {
btnEnable.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
btnSelect.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
btnEnabledText.setTextColor(Color.parseColor("#FFFFFF"))
btnSelectText.setTextColor(Color.parseColor("#FFFFFF"))
btnEnabledimg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
btnSelectimg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
tvStep1Status.text = "Step one"
tvStep1Status.text = "Step one"
tvStep2Status.text = "Check to enable key of love"
}else if(!enabled && selected){
btnEnable.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
btnSelect.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
btnEnabledimg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
btnSelectimg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
btnEnabledText.setTextColor(Color.parseColor("#FFFFFF"))
btnSelectText.setTextColor(Color.parseColor("#FFFFFF"))
tvStep1Status.text = "Step one"
tvStep2Status.text = "Check to enable key of love"
}else if(enabled && !selected){
btnEnable.background = getDrawable(R.drawable.ime_guide_activity_btn_completed)
btnSelect.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
btnEnabledimg.setImageResource(R.drawable.ime_guide_activity_btn_completed_img)
btnSelectimg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
btnEnabledText.setTextColor(Color.parseColor("#A1A1A1"))
btnSelectText.setTextColor(Color.parseColor("#FFFFFF"))
tvStep1Status.text = "Step two"
tvStep2Status.text = "Select key of love as your default input method"
}else if(enabled && selected){
btnEnable.background = getDrawable(R.drawable.ime_guide_activity_btn_completed)
btnSelect.background = getDrawable(R.drawable.ime_guide_activity_btn_completed)
btnEnabledimg.setImageResource(R.drawable.ime_guide_activity_btn_completed_img)
btnSelectimg.setImageResource(R.drawable.ime_guide_activity_btn_completed_img)
btnEnabledText.setTextColor(Color.parseColor("#A1A1A1"))
btnSelectText.setTextColor(Color.parseColor("#A1A1A1"))
tvStep1Status.text = "Completed"
tvStep2Status.text = "You have completed the relevant Settings"
Toast.makeText(this, "The input method is all set!", Toast.LENGTH_SHORT).show()
startActivity(Intent(this, GuideActivity::class.java))
finish()
}
}
/** 是否启用了本输入法 */
private fun isImeEnabled(): Boolean {
val enabledImes = Settings.Secure.getString(
contentResolver,
Settings.Secure.ENABLED_INPUT_METHODS
) ?: return false
// 用真正的类,而不是手写字符串
val myImeComponent = ComponentName(this, MyInputMethodService::class.java)
// 系统存的是 flattenToString() 的格式
val myImeId = myImeComponent.flattenToString()
// enabledImes 是一个用 ":" 分隔的列表
return enabledImes.split(':').contains(myImeId)
}
/** 是否已切换为当前输入法 */
private fun isImeSelected(): Boolean {
val currentIme = Settings.Secure.getString(
contentResolver,
Settings.Secure.DEFAULT_INPUT_METHOD
) ?: return false
val myImeComponent = ComponentName(this, MyInputMethodService::class.java)
val myImeId = myImeComponent.flattenToString()
// 直接用同一种格式比对
return currentIme == myImeId
}
}

View File

@@ -43,5 +43,23 @@ class MainActivity : AppCompatActivity() {
}
}
}
// 6. 检查是否有导航参数,处理从键盘跳转过来的请求
handleNavigationFromIntent()
}
private fun handleNavigationFromIntent() {
val navigateTo = intent.getStringExtra("navigate_to")
if (navigateTo == "recharge_fragment") {
// 延迟执行导航,确保导航控制器已经准备好
bottomNav.post {
try {
navController.navigate(R.id.action_global_rechargeFragment)
} catch (e: Exception) {
// 如果导航失败,记录错误日志
android.util.Log.e("MainActivity", "Failed to navigate to recharge fragment", e)
}
}
}
}
}

View File

@@ -0,0 +1,133 @@
package com.example.myapplication.keyboard
import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.example.myapplication.MainActivity
import com.example.myapplication.theme.ThemeManager
class AiKeyboard(
env: KeyboardEnvironment
) : BaseKeyboard(env) {
override val rootView: View = run {
val res = env.ctx.resources
val layoutId = res.getIdentifier("ai_keyboard", "layout", env.ctx.packageName)
if (layoutId != 0) {
env.layoutInflater.inflate(layoutId, null) as View
} else {
// 如果找不到布局创建一个默认的View
LinearLayout(env.ctx).apply {
orientation = LinearLayout.VERTICAL
gravity = Gravity.CENTER
addView(TextView(env.ctx).apply {
text = "AI Keyboard"
})
}
}
}
init {
applyKeyBackground(rootView, "background")
applyTheme(
env.currentTextColor,
env.currentBorderColor,
env.currentBackgroundColor
)
setupListeners()
}
private fun applyKeyBackground(
root: View,
viewIdName: String,
drawableName: String? = null
) {
val res = env.ctx.resources
val viewId = res.getIdentifier(viewIdName, "id", env.ctx.packageName)
if (viewId == 0) return
val v = root.findViewById<View?>(viewId) ?: return
val keyName = drawableName ?: viewIdName
val rawDrawable = ThemeManager.getDrawableForKey(env.ctx, keyName) ?: return
if (viewIdName == "background") {
val scaled = scaleDrawableToHeight(rawDrawable, 243f)
v.background = scaled
return
}
v.background = rawDrawable
}
private fun scaleDrawableToHeight(src: Drawable, targetDp: Float): Drawable {
val res = env.ctx.resources
val dm = res.displayMetrics
val targetHeightPx = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
targetDp,
dm
).toInt()
val bitmap = (src as? BitmapDrawable)?.bitmap ?: return src
val w = bitmap.width
val h = bitmap.height
val ratio = targetHeightPx.toFloat() / h
val targetWidthPx = (w * ratio).toInt()
val scaled = Bitmap.createScaledBitmap(bitmap, targetWidthPx, targetHeightPx, true)
return BitmapDrawable(res, scaled).apply {
setBounds(0, 0, targetWidthPx, targetHeightPx)
}
}
private fun setupListeners() {
val res = env.ctx.resources
val pkg = env.ctx.packageName
// 如果 ai_keyboard.xml 里有 “返回主键盘” 的按钮,比如 key_abc就绑定一下
val backId = res.getIdentifier("key_abc", "id", pkg)
if (backId != 0) {
rootView.findViewById<ImageView?>(backId)?.setOnClickListener {
env.showMainKeyboard()
}
}
// 绑定 VIP 按钮点击事件,跳转到充值页面
val vipButtonId = res.getIdentifier("key_vip", "id", pkg)
if (vipButtonId != 0) {
rootView.findViewById<ImageView?>(vipButtonId)?.setOnClickListener {
navigateToRechargeFragment()
}
}
}
private fun navigateToRechargeFragment() {
try {
val intent = Intent(env.ctx, MainActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
putExtra("navigate_to", "recharge_fragment")
}
env.ctx.startActivity(intent)
} catch (e: Exception) {
// 如果启动失败,记录错误日志
android.util.Log.e("AiKeyboard", "Failed to navigate to recharge fragment", e)
}
}
override fun applyTheme(
textColor: ColorStateList,
borderColor: ColorStateList,
backgroundColor: ColorStateList
) {
}
}

View File

@@ -0,0 +1,112 @@
package com.example.myapplication.keyboard
import android.content.res.ColorStateList
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
/**
* 所有键盘的基础类:只处理文本颜色、边距 / 内边距 这些通用样式。
* 不再直接访问 resources统一走 env.ctx.resources。
*/
abstract class BaseKeyboard(
protected val env: KeyboardEnvironment
) {
abstract val rootView: View
/**
* 应用主题:文字颜色 + 边框(只调 margin/padding不动你每个键的图片背景
*/
open fun applyTheme(
textColor: ColorStateList,
borderColor: ColorStateList,
backgroundColor: ColorStateList
) {
applyTextColorToAllTextViews(rootView, textColor)
applyBorderToAllKeyViews(rootView)
}
// 文字颜色递归设置
protected fun applyTextColorToAllTextViews(root: View?, color: ColorStateList) {
if (root == null) return
fun dfs(v: View?) {
when (v) {
is TextView -> v.setTextColor(color)
is ViewGroup -> {
val childCount = v.childCount
var i = 0
while (i < childCount) {
dfs(v.getChildAt(i))
i++
}
}
}
}
dfs(root)
}
/**
* 只设置 margin / padding不统一改背景避免覆盖你用 ThemeManager 设置的按键图。
* 跟你原来 MyInputMethodService.applyBorderColorToAllKeys 的逻辑保持一致。
*/
protected fun applyBorderToAllKeyViews(root: View?) {
if (root == null) return
val res = env.ctx.resources
val pkg = env.ctx.packageName
val keyMarginPx = 1.dpToPx()
val keyPaddingH = 6.dpToPx()
// 忽略 suggestion_0..20(联想栏),不改它们背景
val ignoredIds = HashSet<Int>().apply {
var i = 0
while (i <= 20) {
val id = res.getIdentifier("suggestion_$i", "id", pkg)
if (id != 0) add(id)
i++
}
}
fun dfs(v: View?) {
when (v) {
is TextView -> {
if (ignoredIds.contains(v.id)) {
// 联想词不加边距
return
}
val lp = v.layoutParams
if (lp is LinearLayout.LayoutParams) {
lp.setMargins(keyMarginPx, keyMarginPx, keyMarginPx, keyMarginPx)
v.layoutParams = lp
}
v.setPadding(
keyPaddingH,
v.paddingTop,
keyPaddingH,
v.paddingBottom
)
}
is ViewGroup -> {
val childCount = v.childCount
var i = 0
while (i < childCount) {
dfs(v.getChildAt(i))
i++
}
}
}
}
dfs(root)
}
// dp -> px 工具
protected fun Int.dpToPx(): Int {
val density = env.ctx.resources.displayMetrics.density
return (this * density + 0.5f).toInt()
}
}

View File

@@ -0,0 +1,38 @@
package com.example.myapplication.keyboard
import android.content.Context
import android.content.res.ColorStateList
import android.media.AudioManager
import android.os.Handler
import android.view.LayoutInflater
interface KeyboardEnvironment {
val ctx: Context
val mainHandler: Handler
val audioManager: AudioManager
// 只保留 layoutInflater 的默认实现,避免跟 MyInputMethodService 冲突
val layoutInflater: LayoutInflater
get() = LayoutInflater.from(ctx)
// 主题色
val currentTextColor: ColorStateList
val currentBorderColor: ColorStateList
val currentBackgroundColor: ColorStateList
// 文本 / 联想
fun getCurrentWordPrefix(maxLen: Int = 128): String
fun updateCompletionsAndRender(prefix: String)
fun commitKey(c: Char)
fun deleteOne()
fun performSendAction()
// 键盘切换
fun showMainKeyboard()
fun showNumberKeyboard()
fun showSymbolKeyboard()
fun showAiKeyboard()
// 音效
fun playKeyClick()
}

View File

@@ -0,0 +1,314 @@
package com.example.myapplication.keyboard
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.util.TypedValue
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.widget.PopupWindow
import android.widget.TextView
import com.example.myapplication.theme.ThemeManager
class MainKeyboard(
env: KeyboardEnvironment,
private val swipeAltMap: Map<Char, Char>,
/**
* 交给 MyInputMethodService 切换 Shift 状态,并返回最新状态
*/
private val onToggleShift: () -> Boolean
) : BaseKeyboard(env) {
override val rootView: View = env.layoutInflater.inflate(
env.ctx.resources.getIdentifier("keyboard", "layout", env.ctx.packageName),
null
)
private var isShiftOn: Boolean = false
private var keyPreviewPopup: PopupWindow? = null
// ======================== 震动相关 ========================
private val vibrator: Vibrator? =
env.ctx.getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator
private fun vibrateKey(
duration: Long = 20L, // 时间10~40 推荐
amplitude: Int = 150 // 1~255100~150 最舒服
) {
val v = vibrator ?: return
if (!v.hasVibrator()) return
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(
VibrationEffect.createOneShot(duration, amplitude)
)
} else {
@Suppress("DEPRECATION")
v.vibrate(duration)
}
} catch (_: SecurityException) {
// 没权限就自动静音,不崩溃
}
}
init {
applyPerKeyBackgroundForMainKeyboard(rootView)
applyTheme(
env.currentTextColor,
env.currentBorderColor,
env.currentBackgroundColor
)
setupListenersForMain(rootView)
}
// ======================== 背景图 ========================
private fun applyPerKeyBackgroundForMainKeyboard(root: View) {
// a..z 小写
var c = 'a'
while (c <= 'z') {
val idName = "key_$c"
applyKeyBackground(root, idName)
c++
}
// 键盘背景
applyKeyBackground(root, "background")
// 其他功能键
val others = listOf(
"key_space",
"key_send",
"key_del",
"key_up",
"key_123",
"key_ai"
)
for (idName in others) {
applyKeyBackground(root, idName)
}
}
private fun applyKeyBackground(
root: View,
viewIdName: String,
drawableName: String? = null
) {
val res = env.ctx.resources
val viewId = res.getIdentifier(viewIdName, "id", env.ctx.packageName)
if (viewId == 0) return
val v = root.findViewById<View?>(viewId) ?: return
val keyName = drawableName ?: viewIdName
val rawDrawable = ThemeManager.getDrawableForKey(env.ctx, keyName) ?: return
if (viewIdName == "background") {
val scaled = scaleDrawableToHeight(rawDrawable, 243f)
v.background = scaled
return
}
v.background = rawDrawable
}
private fun scaleDrawableToHeight(src: Drawable, targetDp: Float): Drawable {
val res = env.ctx.resources
val dm = res.displayMetrics
val targetHeightPx = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
targetDp,
dm
).toInt()
val bitmap = (src as? BitmapDrawable)?.bitmap ?: return src
val w = bitmap.width
val h = bitmap.height
val ratio = targetHeightPx.toFloat() / h
val targetWidthPx = (w * ratio).toInt()
val scaled = Bitmap.createScaledBitmap(bitmap, targetWidthPx, targetHeightPx, true)
return BitmapDrawable(res, scaled).apply {
setBounds(0, 0, targetWidthPx, targetHeightPx)
}
}
// ======================== 事件绑定 ========================
private fun setupListenersForMain(view: View) {
val res = env.ctx.resources
val pkg = env.ctx.packageName
// a..z支持上滑副字符
var c = 'a'
while (c <= 'z') {
val id = res.getIdentifier("key_$c", "id", pkg)
val tv = view.findViewById<TextView?>(id)
if (tv != null) {
val baseChar = c
val altChar = swipeAltMap[baseChar]
attachKeyTouchWithSwipe(
tv,
normalCharProvider = { baseChar },
altCharProvider = altChar?.let { ac ->
{ ac }
}
)
}
c++
}
// space
view.findViewById<View?>(res.getIdentifier("key_space", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.commitKey(' ')
}
// Shift
val shiftId = res.getIdentifier("key_up", "id", pkg)
view.findViewById<View?>(shiftId)?.setOnClickListener {
vibrateKey()
isShiftOn = onToggleShift()
it.isActivated = isShiftOn
updateKeyBackgroundsForLetters(view)
}
// 删除(单击;长按由 MyInputMethodService 挂)
view.findViewById<View?>(res.getIdentifier("key_del", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.deleteOne()
}
// 切换数字键盘
view.findViewById<View?>(res.getIdentifier("key_123", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.showNumberKeyboard()
}
// 跳 AI
view.findViewById<View?>(res.getIdentifier("key_ai", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.showAiKeyboard()
}
// 发送
view.findViewById<View?>(res.getIdentifier("key_send", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.performSendAction()
}
}
// Shift 后更新字母按键背景key_a vs key_a_up
private fun updateKeyBackgroundsForLetters(root: View) {
var c = 'a'
while (c <= 'z') {
val idName = "key_$c"
val drawableName = if (isShiftOn) "${idName}_up" else idName
applyKeyBackground(root, idName, drawableName)
c++
}
val upKeyIdName = "key_up"
val upDrawableName = if (isShiftOn) "key_up_upper" else "key_up"
applyKeyBackground(root, upKeyIdName, upDrawableName)
}
// ======================== 触摸 + 预览 ========================
private fun attachKeyTouchWithSwipe(
view: View,
normalCharProvider: () -> Char,
altCharProvider: (() -> Char)?
) {
val swipeThreshold = 20.dpToPx().toFloat()
var downY = 0f
var isAlt = false
var currentChar: Char = '\u0000'
view.setOnTouchListener { v, event ->
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
downY = event.rawY
isAlt = false
currentChar = normalCharProvider()
vibrateKey() // 按下就震
showKeyPreview(v, currentChar.toString())
v.isPressed = true
true
}
MotionEvent.ACTION_MOVE -> {
if (altCharProvider != null) {
val dy = event.rawY - downY
val shouldAlt = dy < -swipeThreshold
if (shouldAlt != isAlt) {
isAlt = shouldAlt
currentChar = if (isAlt) altCharProvider() else normalCharProvider()
showKeyPreview(v, currentChar.toString())
}
}
true
}
MotionEvent.ACTION_UP -> {
env.commitKey(currentChar)
keyPreviewPopup?.dismiss()
v.isPressed = false
true
}
MotionEvent.ACTION_CANCEL,
MotionEvent.ACTION_OUTSIDE -> {
keyPreviewPopup?.dismiss()
v.isPressed = false
true
}
else -> false
}
}
}
private fun showKeyPreview(anchor: View, text: String) {
keyPreviewPopup?.dismiss()
val tv = TextView(env.ctx).apply {
this.text = text
textSize = 26f
setTextColor(Color.BLACK)
setPadding(20, 10, 20, 10)
background = GradientDrawable().apply {
shape = GradientDrawable.RECTANGLE
cornerRadius = 16f
setColor(Color.WHITE)
setStroke(1, Color.parseColor("#33000000"))
}
gravity = Gravity.CENTER
}
val w = (anchor.width * 1.2f).toInt()
val h = (anchor.height * 1.2f).toInt()
keyPreviewPopup = PopupWindow(tv, w, h, false).apply {
isClippingEnabled = false
}
keyPreviewPopup?.showAsDropDown(
anchor,
-(w - anchor.width) / 2,
-(h + anchor.height * 1.1f).toInt()
)
}
}

View File

@@ -0,0 +1,311 @@
package com.example.myapplication.keyboard
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.util.TypedValue
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.widget.PopupWindow
import android.widget.TextView
import com.example.myapplication.R
import com.example.myapplication.theme.ThemeManager
class NumberKeyboard(
env: KeyboardEnvironment
) : BaseKeyboard(env) {
override val rootView: View = env.layoutInflater.inflate(
env.ctx.resources.getIdentifier("number_keyboard", "layout", env.ctx.packageName),
null
)
private var keyPreviewPopup: PopupWindow? = null
// ================= 震动相关 =================
private val vibrator: Vibrator? =
env.ctx.getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator
private fun vibrateKey(
duration: Long = 20L, // 时间10~40 推荐
amplitude: Int = 150 // 1~255100~150 最舒服
) {
val v = vibrator ?: return
if (!v.hasVibrator()) return
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(
VibrationEffect.createOneShot(duration, amplitude)
)
} else {
@Suppress("DEPRECATION")
v.vibrate(duration)
}
} catch (_: SecurityException) {
// 没权限就自动静音,不崩溃
}
}
init {
applyPerKeyBackgroundForNumberKeyboard(rootView)
// 初次创建立刻应用当前主题
applyTheme(
env.currentTextColor,
env.currentBorderColor,
env.currentBackgroundColor
)
setupListenersForNumberView(rootView)
}
// ================= 背景(完全拷贝原逻辑,只是换成 env.ctx.resources =================
private fun applyPerKeyBackgroundForNumberKeyboard(root: View) {
val res = env.ctx.resources
// 0..9
for (i in 0..9) {
val idName = "key_$i"
applyKeyBackground(root, idName)
}
// 背景
applyKeyBackground(root, "background")
// 符号键
val symbolKeys = listOf(
"key_comma",
"key_dot",
"key_minus",
"key_slash",
"key_colon",
"key_semicolon",
"key_paren_l",
"key_paren_r",
"key_dollar",
"key_amp",
"key_at",
"key_question",
"key_exclam",
"key_quote",
"key_quote_d"
)
symbolKeys.forEach { idName ->
applyKeyBackground(root, idName)
}
// 功能键
val others = listOf(
"key_symbols_more",
"key_abc",
"key_ai",
"key_space",
"key_send",
"key_del"
)
others.forEach { idName ->
applyKeyBackground(root, idName)
}
}
private fun applyKeyBackground(
root: View,
viewIdName: String,
drawableName: String? = null
) {
val res = env.ctx.resources
val viewId = res.getIdentifier(viewIdName, "id", env.ctx.packageName)
if (viewId == 0) return
val v = root.findViewById<View?>(viewId) ?: return
val keyName = drawableName ?: viewIdName
val rawDrawable = ThemeManager.getDrawableForKey(env.ctx, keyName) ?: return
if (viewIdName == "background") {
val scaled = scaleDrawableToHeight(rawDrawable, 243f)
v.background = scaled
return
}
v.background = rawDrawable
}
private fun scaleDrawableToHeight(src: Drawable, targetDp: Float): Drawable {
val res = env.ctx.resources
val dm = res.displayMetrics
val targetHeightPx = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
targetDp,
dm
).toInt()
val bitmap = (src as? BitmapDrawable)?.bitmap ?: return src
val w = bitmap.width
val h = bitmap.height
val ratio = targetHeightPx.toFloat() / h
val targetWidthPx = (w * ratio).toInt()
val scaledBitmap = Bitmap.createScaledBitmap(
bitmap,
targetWidthPx,
targetHeightPx,
true
)
return BitmapDrawable(res, scaledBitmap).apply {
setBounds(0, 0, targetWidthPx, targetHeightPx)
}
}
// ================= 按键事件 =================
private fun setupListenersForNumberView(numView: View) {
val res = env.ctx.resources
val pkg = env.ctx.packageName
// 0~9
for (i in 0..9) {
val id = res.getIdentifier("key_$i", "id", pkg)
numView.findViewById<View?>(id)?.let { v ->
attachKeyTouch(v) { i.toString()[0] }
}
}
// 符号键
val symbolMap: List<Pair<String, Char>> = listOf(
"key_comma" to ',',
"key_dot" to '.',
"key_minus" to '-',
"key_slash" to '/',
"key_colon" to ':',
"key_semicolon" to ';',
"key_paren_l" to '(',
"key_paren_r" to ')',
"key_dollar" to '$',
"key_amp" to '&',
"key_at" to '@',
"key_question" to '?',
"key_exclam" to '!',
"key_quote" to '\'',
"key_quote_d" to '”'
)
symbolMap.forEach { (name, ch) ->
val id = res.getIdentifier(name, "id", pkg)
numView.findViewById<View?>(id)?.let { v ->
attachKeyTouch(v) { ch }
}
}
// 切换:符号层
numView.findViewById<View?>(res.getIdentifier("key_symbols_more", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.showSymbolKeyboard()
}
// 切回字母
numView.findViewById<View?>(res.getIdentifier("key_abc", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.showMainKeyboard()
}
// 跳 AI
numView.findViewById<View?>(res.getIdentifier("key_ai", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.showAiKeyboard()
}
// 空格
numView.findViewById<View?>(res.getIdentifier("key_space", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.commitKey(' ')
}
// 发送
numView.findViewById<View?>(res.getIdentifier("key_send", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.performSendAction()
}
// 删除(单击;长按连删在 MyInputMethodService 里挂)
numView.findViewById<View?>(res.getIdentifier("key_del", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.deleteOne()
}
}
// ================= 按键触摸 & 预览 =================
private fun attachKeyTouch(view: View, charProvider: () -> Char) {
view.setOnTouchListener { v, event ->
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
val ch = charProvider()
vibrateKey() // 按下就震一下
showKeyPreview(v, ch.toString())
v.isPressed = true
true
}
MotionEvent.ACTION_UP -> {
val ch = charProvider()
env.commitKey(ch)
keyPreviewPopup?.dismiss()
v.isPressed = false
true
}
MotionEvent.ACTION_CANCEL,
MotionEvent.ACTION_OUTSIDE -> {
keyPreviewPopup?.dismiss()
v.isPressed = false
true
}
else -> false
}
}
}
private fun showKeyPreview(anchor: View, text: String) {
keyPreviewPopup?.dismiss()
val tv = TextView(env.ctx).apply {
this.text = text
textSize = 26f
setTextColor(Color.BLACK)
setPadding(20, 10, 20, 10)
background = GradientDrawable().apply {
shape = GradientDrawable.RECTANGLE
cornerRadius = 16f
setColor(Color.WHITE)
setStroke(1, Color.parseColor("#33000000"))
}
gravity = Gravity.CENTER
}
val w = (anchor.width * 1.2f).toInt()
val h = (anchor.height * 1.2f).toInt()
keyPreviewPopup = PopupWindow(tv, w, h, false).apply {
isClippingEnabled = false
}
keyPreviewPopup?.showAsDropDown(
anchor,
-(w - anchor.width) / 2,
-(h + anchor.height * 1.1f).toInt()
)
}
}

View File

@@ -0,0 +1,329 @@
package com.example.myapplication.keyboard
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.util.TypedValue
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.widget.PopupWindow
import android.widget.TextView
import com.example.myapplication.R
import com.example.myapplication.theme.ThemeManager
class SymbolKeyboard(
env: KeyboardEnvironment
) : BaseKeyboard(env) {
override val rootView: View = env.layoutInflater.inflate(
env.ctx.resources.getIdentifier("symbol_keyboard", "layout", env.ctx.packageName),
null
)
private var keyPreviewPopup: PopupWindow? = null
// ================== 震动相关 ==================
private val vibrator: Vibrator? =
env.ctx.getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator
private fun vibrateKey(
duration: Long = 20L, // 时间10~40 推荐
amplitude: Int = 150 // 1~255100~150 最舒服
) {
val v = vibrator ?: return
if (!v.hasVibrator()) return
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(
VibrationEffect.createOneShot(duration, amplitude)
)
} else {
@Suppress("DEPRECATION")
v.vibrate(duration)
}
} catch (_: SecurityException) {
// 没权限就自动静音,不崩溃
}
}
init {
// 按键背景图片(跟你原来 applyPerKeyBackgroundForSymbolKeyboard 一样)
applyPerKeyBackgroundForSymbolKeyboard(rootView)
// 初次创建立刻应用当前主题色
applyTheme(
env.currentTextColor,
env.currentBorderColor,
env.currentBackgroundColor
)
setupListenersForSymbolView(rootView)
}
// ================== 背景(完全按你原来的 key 列表) ==================
private fun applyPerKeyBackgroundForSymbolKeyboard(root: View) {
val res = env.ctx.resources
val symbolKeys = listOf(
// 第一行
"key_bracket_l",
"key_bracket_r",
"key_brace_l",
"key_brace_r",
"key_hash",
"key_percent",
"key_caret",
"key_asterisk",
"key_plus",
"key_equal",
// 第二行
"key_underscore",
"key_backslash",
"key_pipe",
"key_tilde",
"key_lt",
"key_gt",
"key_euro",
"key_pound",
"key_money",
"key_bullet",
// 第三行
"key_dot",
"key_comma",
"key_question",
"key_exclam",
"key_quote"
)
symbolKeys.forEach { idName ->
applyKeyBackground(root, idName)
}
// 背景整体
applyKeyBackground(root, "background")
// 功能键
val others = listOf(
"key_symbols_123",
"key_backspace",
"key_abc",
"key_ai",
"key_space",
"key_send"
)
others.forEach { idName ->
applyKeyBackground(root, idName)
}
}
private fun applyKeyBackground(
root: View,
viewIdName: String,
drawableName: String? = null
) {
val res = env.ctx.resources
val viewId = res.getIdentifier(viewIdName, "id", env.ctx.packageName)
if (viewId == 0) return
val v = root.findViewById<View?>(viewId) ?: return
val keyName = drawableName ?: viewIdName
val rawDrawable = ThemeManager.getDrawableForKey(env.ctx, keyName) ?: return
if (viewIdName == "background") {
val scaled = scaleDrawableToHeight(rawDrawable, 243f)
v.background = scaled
return
}
v.background = rawDrawable
}
private fun scaleDrawableToHeight(src: Drawable, targetDp: Float): Drawable {
val res = env.ctx.resources
val dm = res.displayMetrics
val targetHeightPx = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
targetDp,
dm
).toInt()
val bitmap = (src as? BitmapDrawable)?.bitmap ?: return src
val w = bitmap.width
val h = bitmap.height
val ratio = targetHeightPx.toFloat() / h
val targetWidthPx = (w * ratio).toInt()
val scaledBitmap = Bitmap.createScaledBitmap(
bitmap,
targetWidthPx,
targetHeightPx,
true
)
return BitmapDrawable(res, scaledBitmap).apply {
setBounds(0, 0, targetWidthPx, targetHeightPx)
}
}
// ================== 符号键盘事件 ==================
private fun setupListenersForSymbolView(symView: View) {
val res = env.ctx.resources
val pkg = env.ctx.packageName
val pairs = listOf(
// 第一行
"key_bracket_l" to '[',
"key_bracket_r" to ']',
"key_brace_l" to '{',
"key_brace_r" to '}',
"key_hash" to '#',
"key_percent" to '%',
"key_caret" to '^',
"key_asterisk" to '*',
"key_plus" to '+',
"key_equal" to '=',
// 第二行
"key_underscore" to '_',
"key_backslash" to '\\',
"key_pipe" to '|',
"key_tilde" to '~',
"key_lt" to '<',
"key_gt" to '>',
"key_euro" to '€',
"key_pound" to '£',
"key_money" to '¥',
"key_bullet" to '•',
// 第三行
"key_dot" to '.',
"key_comma" to ',',
"key_question" to '?',
"key_exclam" to '!',
"key_quote" to '\''
)
pairs.forEach { (name, ch) ->
val id = res.getIdentifier(name, "id", pkg)
symView.findViewById<View?>(id)?.let { v ->
attachKeyTouch(v) { ch }
}
}
// 切换回数字
symView.findViewById<View?>(res.getIdentifier("key_symbols_123", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.showNumberKeyboard()
}
// 切回字母
symView.findViewById<View?>(res.getIdentifier("key_abc", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.showMainKeyboard()
}
// 空格
symView.findViewById<View?>(res.getIdentifier("key_space", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.commitKey(' ')
}
// 发送
symView.findViewById<View?>(res.getIdentifier("key_send", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.performSendAction()
}
// 删除(单击;长按连删在 MyInputMethodService 里统一挂)
symView.findViewById<View?>(res.getIdentifier("key_backspace", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.deleteOne()
}
// 跳 AI 键盘
symView.findViewById<View?>(res.getIdentifier("key_ai", "id", pkg))
?.setOnClickListener {
vibrateKey()
env.showAiKeyboard()
}
}
// ================== 触摸 + 预览 ==================
private fun attachKeyTouch(view: View, charProvider: () -> Char) {
view.setOnTouchListener { v, event ->
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
val ch = charProvider()
vibrateKey() // 按下震动
showKeyPreview(v, ch.toString())
v.isPressed = true
true
}
MotionEvent.ACTION_UP -> {
val ch = charProvider()
env.commitKey(ch)
keyPreviewPopup?.dismiss()
v.isPressed = false
true
}
MotionEvent.ACTION_CANCEL,
MotionEvent.ACTION_OUTSIDE -> {
keyPreviewPopup?.dismiss()
v.isPressed = false
true
}
else -> false
}
}
}
private fun showKeyPreview(anchor: View, text: String) {
keyPreviewPopup?.dismiss()
val tv = TextView(env.ctx).apply {
this.text = text
textSize = 26f
setTextColor(Color.BLACK)
setPadding(20, 10, 20, 10)
background = GradientDrawable().apply {
shape = GradientDrawable.RECTANGLE
cornerRadius = 16f
setColor(Color.WHITE)
setStroke(1, Color.parseColor("#33000000"))
}
gravity = Gravity.CENTER
}
val w = (anchor.width * 1.2f).toInt()
val h = (anchor.height * 1.2f).toInt()
keyPreviewPopup = PopupWindow(tv, w, h, false).apply {
isClippingEnabled = false
}
keyPreviewPopup?.showAsDropDown(
anchor,
-(w - anchor.width) / 2,
-(h + anchor.height * 1.1f).toInt()
)
}
}

View File

@@ -0,0 +1,8 @@
// ApiResponse.kt
package com.example.network
data class ApiResponse<T>(
val code: Int,
val msg: String,
val data: T?
)

View File

@@ -0,0 +1,43 @@
// 请求方法
package com.example.network
import okhttp3.ResponseBody
import retrofit2.Response
import retrofit2.http.*
interface ApiService {
// GET 示例:/users/{id}
@GET("users/{id}")
suspend fun getUser(
@Path("id") id: String
): ApiResponse<User>
// GET 示例:带查询参数 /users?page=1&pageSize=20
@GET("users")
suspend fun getUsers(
@Query("page") page: Int,
@Query("pageSize") pageSize: Int
): ApiResponse<List<User>>
// POST JSON 示例Body 为 JSON{"username": "...", "password": "..."}
@POST("auth/login")
suspend fun login(
@Body body: LoginRequest
): ApiResponse<LoginResponse>
// POST 表单示例x-www-form-urlencoded
@FormUrlEncoded
@POST("auth/loginForm")
suspend fun loginForm(
@Field("username") username: String,
@Field("password") password: String
): ApiResponse<LoginResponse>
// zip 文件下载(或其它大文件)——必须 @Streaming
@Streaming
@GET("files/{fileName}")
suspend fun downloadZip(
@Path("fileName") fileName: String // 比如 "xxx.zip"
): Response<ResponseBody>
}

View File

@@ -0,0 +1,86 @@
// zip 文件下载器
package com.example.network
import android.content.Context
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.ResponseBody
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.io.OutputStream
object FileDownloader {
/**
* 下载 zip 文件并保存到 app 专属目录
* @param context 用来获取文件目录
* @param remoteFileName 服务器上的文件名,比如 "test.zip"
* @param localFileName 本地保存名字,比如 "test_local.zip"
* @return 保存成功后返回 File失败返回 null
*/
suspend fun downloadZipFile(
context: Context,
remoteFileName: String,
localFileName: String = remoteFileName
): File? = withContext(Dispatchers.IO) {
val api = RetrofitClient.apiService
try {
val response = api.downloadZip(remoteFileName)
if (!response.isSuccessful) {
Log.e("Downloader", "download failed: code=${response.code()}")
return@withContext null
}
val body = response.body() ?: run {
Log.e("Downloader", "response body is null")
return@withContext null
}
val dir = File(context.getExternalFilesDir(null), "Downloads")
if (!dir.exists()) dir.mkdirs()
val outFile = File(dir, localFileName)
saveResponseBodyToFile(body, outFile)
Log.d("Downloader", "file saved to: ${outFile.absolutePath}")
return@withContext outFile
} catch (e: Exception) {
Log.e("Downloader", "download exception: ${e.message}", e)
return@withContext null
}
}
/**
* 把 ResponseBody 写入文件
*/
private fun saveResponseBodyToFile(body: ResponseBody, outFile: File) {
var inputStream: InputStream? = null
var outputStream: OutputStream? = null
try {
val buffer = ByteArray(8 * 1024)
var downloadedBytes: Long = 0
val totalBytes = body.contentLength()
inputStream = body.byteStream()
outputStream = FileOutputStream(outFile)
while (true) {
val read = inputStream.read(buffer)
if (read == -1) break
outputStream.write(buffer, 0, read)
downloadedBytes += read
// 需要的话可以在这里回调进度
val progress = downloadedBytes * 100 / totalBytes
}
outputStream.flush()
} finally {
inputStream?.close()
outputStream?.close()
}
}
}

View File

@@ -0,0 +1,53 @@
// 定义请求 & 响应拦截器
package com.example.network
import android.util.Log
import okhttp3.Interceptor
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
/**
* 请求拦截器:统一加 Header、token 等
*/
val requestInterceptor = Interceptor { chain ->
val original = chain.request()
val token = "your_token" // 这里换成你自己的 token
val newRequest = original.newBuilder()
.addHeader("Accept", "application/json")
.addHeader("Content-Type", "application/json")
// 这里加你自己的 token如果没有就注释掉
.addHeader("Authorization", "Bearer $token")
.build()
chain.proceed(newRequest)
}
/**
* 响应拦截器:统一打印日志、做一些简单的错误处理
*/
val responseInterceptor = Interceptor { chain ->
val request = chain.request()
val startNs = System.nanoTime()
val response: Response = chain.proceed(request)
val tookMs = (System.nanoTime() - startNs) / 1_000_000
val rawBody = response.body
val mediaType = rawBody?.contentType()
val bodyString = rawBody?.string() ?: ""
Log.d(
"HTTP",
"⬇⬇⬇\n" +
"URL : ${request.url}\n" +
"Method: ${request.method}\n" +
"Code : ${response.code}\n" +
"Time : ${tookMs}ms\n" +
"Body : $bodyString\n" +
"⬆⬆⬆"
)
// body 只能读一次,这里读完后再重新构建一个
response.newBuilder()
.body(bodyString.toResponseBody(mediaType))
.build()
}

View File

@@ -0,0 +1,18 @@
// Models.kt
package com.example.network
data class User(
val id: String,
val name: String,
val age: Int
)
data class LoginRequest(
val username: String,
val password: String
)
data class LoginResponse(
val token: String,
val user: User
)

View File

@@ -0,0 +1,44 @@
// RetrofitClient.kt
package com.example.network
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
object RetrofitClient {
private const val BASE_URL = "https://api.example.com/" // 换成你的地址
// 日志拦截器(可选)
private val loggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
private val okHttpClient: OkHttpClient by lazy {
OkHttpClient.Builder()
// 超时时间自己看需求改
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
// 顺序:请求拦截 -> logging -> 响应拦截
.addInterceptor(requestInterceptor)
.addInterceptor(loggingInterceptor)
.addInterceptor(responseInterceptor)
.build()
}
private val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
val apiService: ApiService by lazy {
retrofit.create(ApiService::class.java)
}
}

View File

@@ -24,6 +24,7 @@ import android.widget.HorizontalScrollView
import androidx.coordinatorlayout.widget.CoordinatorLayout
import kotlin.math.abs
import android.content.Intent
import com.example.myapplication.ImeGuideActivity
class HomeFragment : Fragment() {
@@ -63,6 +64,10 @@ class HomeFragment : Fragment() {
view.findViewById<View>(R.id.rechargeButton).setOnClickListener {
findNavController().navigate(R.id.action_global_rechargeFragment)
}
//输入法激活跳转
view.findViewById<ImageView>(R.id.floatingImage).setOnClickListener {
startActivity(Intent(requireContext(), ImeGuideActivity::class.java))
}
scrim = view.findViewById(R.id.view_scrim)
bottomSheet = view.findViewById(R.id.bottomSheet)

View File

@@ -3,18 +3,14 @@
<!-- 按下状态 -->
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#CCCCCC"/>
<corners android:radius="4dp"/>
<stroke android:width="1dp" android:color="#999999"/>
</shape>
</item>
<!-- 默认状态 -->
<item>
<shape android:shape="rectangle">
<solid android:color="#FFFFFF"/>
<corners android:radius="4dp"/>
<stroke android:width="1dp" android:color="#DDDDDD"/>
</shape>
</item>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -1,170 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
<vector
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z"/>
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#F3F3F3"/>
<corners android:radius="50dp"/>
<padding android:left="23dp" android:right="23dp" android:top="18dp" android:bottom="18dp"/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#02BEAC"/>
<corners android:radius="50dp"/>
<padding android:left="23dp" android:right="23dp" android:top="18dp" android:bottom="18dp"/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#02BEAC"/>
<corners android:radius="8dp"/>
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#B9BDC8"/>
<corners android:radius="8dp"/>
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#FFFFFF"/>
<corners android:radius="8dp"/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/iv_close"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_marginTop="16dp"
android:layout_marginLeft="16dp">
<ImageView
android:layout_width="13dp"
android:layout_height="13dp"
android:layout_gravity="center"
android:src="@drawable/more_icons"
android:rotation="180"
android:scaleType="fitCenter" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="#000000"
android:text="键盘体验页" />
</LinearLayout>
</FrameLayout>

View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- <FrameLayout
android:id="@+id/iv_close"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_marginTop="16dp"
android:layout_marginLeft="16dp">
<ImageView
android:layout_width="13dp"
android:layout_height="13dp"
android:layout_gravity="center"
android:src="@drawable/more_icons"
android:rotation="180"
android:scaleType="fitCenter" />
</FrameLayout> -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:layout_gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/ivImeLogo"
android:layout_width="69dp"
android:layout_height="69dp"
android:src="@drawable/logo" />
<TextView
android:id="@+id/Steps"
android:textSize="18sp"
android:layout_width="wrap_content"
android:layout_marginTop="48dp"
android:textColor="#1B1F1A"
android:gravity="center"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/stepTips"
android:textSize="14sp"
android:layout_width="175dp"
android:layout_marginTop="18dp"
android:textColor="#A1A1A1"
android:gravity="center"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/enabled"
android:layout_width="290dp"
android:layout_height="54dp"
android:layout_marginTop="60dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/btnEnabledText"
android:text="Enable it in Settings"
android:textSize="13sp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textColor="#1B1F1A" />
<ImageView
android:id="@+id/btnEnabledimg"
android:layout_width="16dp"
android:layout_height="13dp"/>
<!--android:src="@drawable/next_arrow" -->
</LinearLayout>
<LinearLayout
android:id="@+id/select"
android:layout_width="290dp"
android:layout_height="54dp"
android:layout_marginTop="25dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/btnSelectText"
android:text="Select an input method"
android:textSize="13sp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textColor="#1B1F1A" />
<ImageView
android:id="@+id/btnSelectimg"
android:layout_width="16dp"
android:layout_height="13dp"/>
<!--android:src="@drawable/next_arrow" -->
</LinearLayout>
</LinearLayout>
</FrameLayout>

View File

@@ -221,7 +221,7 @@
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/bg" />
android:src="@drawable/default_avatar" />
<TextView
android:id="@+id/tvNickname"

View File

@@ -1,18 +1,194 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/keyboard_background"
android:id="@+id/background"
android:gravity="center"
android:padding="16dp">
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="52dp"
android:id="@+id/keyboard_container"
android:paddingStart="12dp"
android:paddingEnd="8dp">
<ImageView
android:id="@+id/key_abc"
android:layout_width="34dp"
android:layout_height="34dp"
android:src="@drawable/jump_to_the_keyboard"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<ImageView
android:id="@+id/key_vip"
android:layout_width="115dp"
android:layout_height="35dp"
android:layout_alignParentEnd="true"
android:src="@drawable/jump_to_vip"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/keyboard_row_1"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:orientation="horizontal">
<!-- 粘贴框和人设 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<!-- 粘贴框 -->
<HorizontalScrollView
android:id="@+id/completion_scroll"
android:layout_width="match_parent"
android:layout_height="41dp"
android:overScrollMode="never"
android:scrollbars="none"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:background="@drawable/keyboard_button_bg3"
android:fillViewport="false">
<LinearLayout
android:id="@+id/completion_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="13dp"
android:layout_height="13dp"
android:src="@drawable/copy_the_message"/>
<!-- 暂时空的 AI 键盘区域 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AI 键盘功能区"
android:textColor="#A9A9A9"
android:textSize="16sp"/>
android:layout_marginStart="8dp"
android:text="Paste Ta's words"
android:textColor="#02BEAC"
android:textSize="13sp" />
</LinearLayout>
</HorizontalScrollView>
<!-- 人设 -->
<ScrollView
android:layout_width="match_parent"
android:layout_marginTop="4dp"
android:layout_height="131dp"
android:scrollbars="none">
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/persona_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flexDirection="row"
app:flexWrap="wrap"
app:justifyContent="space_between">
<!-- 卡片 -->
<LinearLayout
android:layout_width="90dp"
android:layout_height="41dp"
android:layout_marginBottom="4dp"
android:gravity="center"
android:orientation="horizontal"
android:background="@drawable/keyboard_button_bg3">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/avatar"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/default_avatar"
android:clickable="true"
android:focusable="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="5dp"
android:text="Humor"
android:textColor="#1B1F1A"
android:textSize="13sp"/>
</LinearLayout>
<!-- ```````````````` -->
</com.google.android.flexbox.FlexboxLayout>
</ScrollView>
</LinearLayout>
<!-- 操作 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/keyboard_button_1"
android:layout_marginStart="4dp"
android:orientation="vertical">
<LinearLayout
android:id="@+id/keyboard_button_Paste"
android:layout_width="60dp"
android:layout_height="41dp"
android:gravity="center"
android:orientation="horizontal"
android:background="@drawable/keyboard_button_bg1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Paste"
android:textColor="#FFFFFF"
android:textSize="13sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/keyboard_button_Delete"
android:layout_width="60dp"
android:layout_height="41dp"
android:layout_marginTop="4dp"
android:gravity="center"
android:orientation="horizontal"
android:background="@drawable/keyboard_button_bg2">
<ImageView
android:layout_width="23dp"
android:layout_height="14dp"
android:src="@drawable/keyboard_icon_voice"/>
</LinearLayout>
<LinearLayout
android:id="@+id/keyboard_button_Clear"
android:layout_width="60dp"
android:layout_marginTop="4dp"
android:layout_height="41dp"
android:gravity="center"
android:orientation="horizontal"
android:background="@drawable/keyboard_button_bg2">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clear"
android:textColor="#1B1F1A"
android:textSize="13sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/keyboard_button_Send"
android:layout_width="60dp"
android:layout_marginTop="4dp"
android:layout_height="41dp"
android:gravity="center"
android:orientation="horizontal"
android:background="@drawable/keyboard_button_bg1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send"
android:textColor="#FFFFFF"
android:textSize="13sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@@ -32,7 +32,7 @@
android:layout_width="67dp"
android:layout_height="67dp"
android:elevation="4dp"
android:src="@drawable/bg"
android:src="@drawable/default_avatar"
app:civ_border_color="#DFF346"
app:civ_border_width="2dp" />
@@ -69,7 +69,7 @@
android:layout_width="67dp"
android:layout_height="67dp"
android:elevation="4dp"
android:src="@drawable/bg"
android:src="@drawable/default_avatar"
app:civ_border_width="2dp"
app:civ_border_color="#DFF346" />
@@ -106,7 +106,7 @@
android:layout_width="67dp"
android:layout_height="67dp"
android:elevation="4dp"
android:src="@drawable/bg"
android:src="@drawable/default_avatar"
app:civ_border_width="2dp"
app:civ_border_color="#DFF346" />
@@ -165,7 +165,7 @@
android:layout_weight="1"
android:layout_marginEnd="10dp"
android:elevation="4dp"
android:src="@drawable/bg"/>
android:src="@drawable/default_avatar"/>
<LinearLayout
android:layout_width="140dp"

View File

@@ -23,7 +23,7 @@
android:layout_width="67dp"
android:layout_height="67dp"
android:elevation="7dp"
android:src="@drawable/bg"
android:src="@drawable/default_avatar"
app:civ_border_width="2dp"
app:civ_border_color="#DFF346" />

View File

@@ -81,7 +81,7 @@
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginStart="5dp"
android:src="@drawable/bg"
android:src="@drawable/default_avatar"
android:clickable="true"
android:focusable="true"/>

View File

@@ -25,232 +25,232 @@
android:id="@+id/suggestion_0"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_4"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_5"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_6"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_7"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_8"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_9"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_10"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_11"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_12"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_13"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_14"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_15"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_16"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_17"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_18"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_19"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_20"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:textSize="16sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
</LinearLayout>
</HorizontalScrollView>

View File

@@ -82,7 +82,7 @@
android:id="@+id/avatar"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/bg"
android:src="@drawable/default_avatar"
android:clickable="true"
android:focusable="true"/>

View File

@@ -81,7 +81,7 @@
android:layout_width="match_parent"
android:layout_height="127dp"
android:scaleType="centerCrop"
android:src="@drawable/bg" />
android:src="@drawable/default_avatar" />
<TextView
android:layout_width="130dp"

View File

@@ -30,7 +30,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_1"
@@ -41,7 +41,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_2"
@@ -52,7 +52,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_3"
@@ -63,7 +63,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_4"
@@ -74,7 +74,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_5"
@@ -85,7 +85,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_6"
@@ -96,7 +96,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_7"
@@ -107,7 +107,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_8"
@@ -118,7 +118,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_9"
@@ -129,7 +129,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_10"
@@ -140,7 +140,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_11"
@@ -151,7 +151,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_12"
@@ -162,7 +162,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_13"
@@ -173,7 +173,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_14"
@@ -184,7 +184,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_15"
@@ -195,7 +195,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_16"
@@ -206,7 +206,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_17"
@@ -217,7 +217,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_18"
@@ -228,7 +228,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_19"
@@ -239,7 +239,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_20"
@@ -250,7 +250,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
</LinearLayout>
</HorizontalScrollView>

View File

@@ -62,7 +62,7 @@
android:id="@+id/avatar"
android:layout_width="88dp"
android:layout_height="88dp"
android:src="@drawable/bg"
android:src="@drawable/default_avatar"
android:elevation="1dp"
android:clickable="true"
android:focusable="true"/>

View File

@@ -30,7 +30,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_1"
@@ -41,7 +41,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_2"
@@ -52,7 +52,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_3"
@@ -63,7 +63,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_4"
@@ -74,7 +74,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_5"
@@ -85,7 +85,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_6"
@@ -96,7 +96,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_7"
@@ -107,7 +107,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_8"
@@ -118,7 +118,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_9"
@@ -129,7 +129,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_10"
@@ -140,7 +140,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_11"
@@ -151,7 +151,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_12"
@@ -162,7 +162,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_13"
@@ -173,7 +173,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_14"
@@ -184,7 +184,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_15"
@@ -195,7 +195,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_16"
@@ -206,7 +206,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_17"
@@ -217,7 +217,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_18"
@@ -228,7 +228,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_19"
@@ -239,7 +239,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_20"
@@ -250,7 +250,7 @@
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="?android:attr/textColorPrimary" />
android:textColor="#3C3C3C"/>
</LinearLayout>
</HorizontalScrollView>

View File

@@ -11,10 +11,10 @@
android:icon="@drawable/shop_selector"
android:title="Shop" />
<item
<!-- <item
android:id="@+id/circleFragment"
android:icon="@drawable/circle_selector"
android:title="Circle" />
android:title="Circle" /> -->
<item
android:id="@+id/mineFragment"

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android">
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.example.myapplication.ImeGuideActivity">
<subtype
android:imeSubtypeMode="keyboard"
android:imeSubtypeLocale="en_US"

View File

@@ -1,5 +1,5 @@
[versions]
agp = "8.13.0"
agp = "8.13.1"
kotlin = "2.0.21"
coreKtx = "1.17.0"
junit = "4.13.2"