多数页面完成
@@ -67,4 +67,11 @@ dependencies {
|
|||||||
implementation("androidx.navigation:navigation-compose:2.7.5")
|
implementation("androidx.navigation:navigation-compose:2.7.5")
|
||||||
debugImplementation("androidx.compose.ui:ui-tooling")
|
debugImplementation("androidx.compose.ui:ui-tooling")
|
||||||
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
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")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,12 @@
|
|||||||
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.MyApplication">
|
android:theme="@style/Theme.MyApplication">
|
||||||
@@ -21,6 +25,16 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<!-- 输入法激活页(强烈建议增加) -->
|
||||||
|
<activity
|
||||||
|
android:name=".ImeGuideActivity"
|
||||||
|
android:exported="true"/>
|
||||||
|
|
||||||
|
<!-- 输入法体验页 -->
|
||||||
|
<activity
|
||||||
|
android:name=".GuideActivity"
|
||||||
|
android:exported="true"/>
|
||||||
|
|
||||||
<!-- 引导页 -->
|
<!-- 引导页 -->
|
||||||
<activity
|
<activity
|
||||||
android:name=".OnboardingActivity"
|
android:name=".OnboardingActivity"
|
||||||
|
|||||||
BIN
app/src/main/ic_launcher-playstore.png
Normal file
|
After Width: | Height: | Size: 287 KiB |
29
app/src/main/java/com/example/myapplication/GuideActivity.kt
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
203
app/src/main/java/com/example/myapplication/ImeGuideActivity.kt
Normal 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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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()
|
||||||
|
}
|
||||||
@@ -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~255,100~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()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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~255,100~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()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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~255,100~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()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// ApiResponse.kt
|
||||||
|
package com.example.network
|
||||||
|
|
||||||
|
data class ApiResponse<T>(
|
||||||
|
val code: Int,
|
||||||
|
val msg: String,
|
||||||
|
val data: T?
|
||||||
|
)
|
||||||
@@ -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>
|
||||||
|
}
|
||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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()
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
)
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ import android.widget.HorizontalScrollView
|
|||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import com.example.myapplication.ImeGuideActivity
|
||||||
|
|
||||||
class HomeFragment : Fragment() {
|
class HomeFragment : Fragment() {
|
||||||
|
|
||||||
@@ -63,6 +64,10 @@ class HomeFragment : Fragment() {
|
|||||||
view.findViewById<View>(R.id.rechargeButton).setOnClickListener {
|
view.findViewById<View>(R.id.rechargeButton).setOnClickListener {
|
||||||
findNavController().navigate(R.id.action_global_rechargeFragment)
|
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)
|
scrim = view.findViewById(R.id.view_scrim)
|
||||||
bottomSheet = view.findViewById(R.id.bottomSheet)
|
bottomSheet = view.findViewById(R.id.bottomSheet)
|
||||||
|
|||||||
@@ -3,18 +3,14 @@
|
|||||||
<!-- 按下状态 -->
|
<!-- 按下状态 -->
|
||||||
<item android:state_pressed="true">
|
<item android:state_pressed="true">
|
||||||
<shape android:shape="rectangle">
|
<shape android:shape="rectangle">
|
||||||
<solid android:color="#CCCCCC"/>
|
|
||||||
<corners android:radius="4dp"/>
|
<corners android:radius="4dp"/>
|
||||||
<stroke android:width="1dp" android:color="#999999"/>
|
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
|
|
||||||
<!-- 默认状态 -->
|
<!-- 默认状态 -->
|
||||||
<item>
|
<item>
|
||||||
<shape android:shape="rectangle">
|
<shape android:shape="rectangle">
|
||||||
<solid android:color="#FFFFFF"/>
|
|
||||||
<corners android:radius="4dp"/>
|
<corners android:radius="4dp"/>
|
||||||
<stroke android:width="1dp" android:color="#DDDDDD"/>
|
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
</selector>
|
</selector>
|
||||||
|
|||||||
BIN
app/src/main/res/drawable/copy_the_message.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/drawable/default_avatar.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
@@ -1,170 +1,74 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
android:height="108dp"
|
||||||
|
android:width="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
android:viewportWidth="108"
|
android:viewportWidth="108"
|
||||||
android:viewportHeight="108">
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path
|
<path android:fillColor="#3DDC84"
|
||||||
android:fillColor="#3DDC84"
|
android:pathData="M0,0h108v108h-108z"/>
|
||||||
android:pathData="M0,0h108v108h-108z" />
|
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
|
||||||
android:pathData="M9,0L9,108"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeWidth="0.8"
|
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
<path
|
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:pathData="M19,0L19,108"
|
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
|
||||||
android:strokeWidth="0.8"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeColor="#33FFFFFF" />
|
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
|
||||||
android:pathData="M29,0L29,108"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeWidth="0.8"
|
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
<path
|
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:pathData="M39,0L39,108"
|
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
|
||||||
android:strokeWidth="0.8"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeColor="#33FFFFFF" />
|
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
|
||||||
android:pathData="M49,0L49,108"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeWidth="0.8"
|
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
<path
|
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:pathData="M59,0L59,108"
|
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
|
||||||
android:strokeWidth="0.8"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeColor="#33FFFFFF" />
|
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
|
||||||
android:pathData="M69,0L69,108"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeWidth="0.8"
|
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
<path
|
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:pathData="M79,0L79,108"
|
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
|
||||||
android:strokeWidth="0.8"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeColor="#33FFFFFF" />
|
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
|
||||||
android:pathData="M89,0L89,108"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeWidth="0.8"
|
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
<path
|
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:pathData="M99,0L99,108"
|
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
|
||||||
android:strokeWidth="0.8"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeColor="#33FFFFFF" />
|
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
|
||||||
android:pathData="M0,9L108,9"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeWidth="0.8"
|
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
<path
|
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:pathData="M0,19L108,19"
|
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
|
||||||
android:strokeWidth="0.8"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeColor="#33FFFFFF" />
|
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
|
||||||
android:pathData="M0,29L108,29"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
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" />
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
After Width: | Height: | Size: 808 B |
@@ -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>
|
||||||
|
After Width: | Height: | Size: 576 B |
BIN
app/src/main/res/drawable/jump_to_the_keyboard.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
app/src/main/res/drawable/jump_to_vip.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
5
app/src/main/res/drawable/keyboard_button_bg1.xml
Normal 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>
|
||||||
5
app/src/main/res/drawable/keyboard_button_bg2.xml
Normal 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>
|
||||||
5
app/src/main/res/drawable/keyboard_button_bg3.xml
Normal 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>
|
||||||
BIN
app/src/main/res/drawable/keyboard_icon_voice.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable/logo.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
39
app/src/main/res/layout/activity_guide.xml
Normal 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>
|
||||||
99
app/src/main/res/layout/activity_ime_guide.xml
Normal 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>
|
||||||
@@ -221,7 +221,7 @@
|
|||||||
<de.hdodenhof.circleimageview.CircleImageView
|
<de.hdodenhof.circleimageview.CircleImageView
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:src="@drawable/bg" />
|
android:src="@drawable/default_avatar" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvNickname"
|
android:id="@+id/tvNickname"
|
||||||
|
|||||||
@@ -1,18 +1,194 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<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_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
|
||||||
android:background="@drawable/keyboard_background"
|
|
||||||
android:id="@+id/background"
|
android:id="@+id/background"
|
||||||
android:gravity="center"
|
android:orientation="vertical">
|
||||||
android:padding="16dp">
|
<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"/>
|
||||||
|
|
||||||
<!-- 暂时空的 AI 键盘区域 -->
|
<ImageView
|
||||||
<TextView
|
android:id="@+id/key_vip"
|
||||||
android:layout_width="wrap_content"
|
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:layout_height="wrap_content"
|
||||||
android:text="AI 键盘功能区"
|
android:id="@+id/keyboard_row_1"
|
||||||
android:textColor="#A9A9A9"
|
android:paddingStart="4dp"
|
||||||
android:textSize="16sp"/>
|
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"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
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>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
android:layout_width="67dp"
|
android:layout_width="67dp"
|
||||||
android:layout_height="67dp"
|
android:layout_height="67dp"
|
||||||
android:elevation="4dp"
|
android:elevation="4dp"
|
||||||
android:src="@drawable/bg"
|
android:src="@drawable/default_avatar"
|
||||||
app:civ_border_color="#DFF346"
|
app:civ_border_color="#DFF346"
|
||||||
app:civ_border_width="2dp" />
|
app:civ_border_width="2dp" />
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
android:layout_width="67dp"
|
android:layout_width="67dp"
|
||||||
android:layout_height="67dp"
|
android:layout_height="67dp"
|
||||||
android:elevation="4dp"
|
android:elevation="4dp"
|
||||||
android:src="@drawable/bg"
|
android:src="@drawable/default_avatar"
|
||||||
app:civ_border_width="2dp"
|
app:civ_border_width="2dp"
|
||||||
app:civ_border_color="#DFF346" />
|
app:civ_border_color="#DFF346" />
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
android:layout_width="67dp"
|
android:layout_width="67dp"
|
||||||
android:layout_height="67dp"
|
android:layout_height="67dp"
|
||||||
android:elevation="4dp"
|
android:elevation="4dp"
|
||||||
android:src="@drawable/bg"
|
android:src="@drawable/default_avatar"
|
||||||
app:civ_border_width="2dp"
|
app:civ_border_width="2dp"
|
||||||
app:civ_border_color="#DFF346" />
|
app:civ_border_color="#DFF346" />
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:elevation="4dp"
|
android:elevation="4dp"
|
||||||
android:src="@drawable/bg"/>
|
android:src="@drawable/default_avatar"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="140dp"
|
android:layout_width="140dp"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
android:layout_width="67dp"
|
android:layout_width="67dp"
|
||||||
android:layout_height="67dp"
|
android:layout_height="67dp"
|
||||||
android:elevation="7dp"
|
android:elevation="7dp"
|
||||||
android:src="@drawable/bg"
|
android:src="@drawable/default_avatar"
|
||||||
app:civ_border_width="2dp"
|
app:civ_border_width="2dp"
|
||||||
app:civ_border_color="#DFF346" />
|
app:civ_border_color="#DFF346" />
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@
|
|||||||
android:layout_width="70dp"
|
android:layout_width="70dp"
|
||||||
android:layout_height="70dp"
|
android:layout_height="70dp"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:src="@drawable/bg"
|
android:src="@drawable/default_avatar"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"/>
|
android:focusable="true"/>
|
||||||
|
|
||||||
|
|||||||
@@ -25,232 +25,232 @@
|
|||||||
android:id="@+id/suggestion_0"
|
android:id="@+id/suggestion_0"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_1"
|
android:id="@+id/suggestion_1"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_2"
|
android:id="@+id/suggestion_2"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_3"
|
android:id="@+id/suggestion_3"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_4"
|
android:id="@+id/suggestion_4"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_5"
|
android:id="@+id/suggestion_5"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_6"
|
android:id="@+id/suggestion_6"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_7"
|
android:id="@+id/suggestion_7"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_8"
|
android:id="@+id/suggestion_8"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_9"
|
android:id="@+id/suggestion_9"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_10"
|
android:id="@+id/suggestion_10"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_11"
|
android:id="@+id/suggestion_11"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_12"
|
android:id="@+id/suggestion_12"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_13"
|
android:id="@+id/suggestion_13"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_14"
|
android:id="@+id/suggestion_14"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_15"
|
android:id="@+id/suggestion_15"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_16"
|
android:id="@+id/suggestion_16"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_17"
|
android:id="@+id/suggestion_17"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_18"
|
android:id="@+id/suggestion_18"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_19"
|
android:id="@+id/suggestion_19"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_20"
|
android:id="@+id/suggestion_20"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="12sp"
|
android:textSize="16sp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
android:id="@+id/avatar"
|
android:id="@+id/avatar"
|
||||||
android:layout_width="20dp"
|
android:layout_width="20dp"
|
||||||
android:layout_height="20dp"
|
android:layout_height="20dp"
|
||||||
android:src="@drawable/bg"
|
android:src="@drawable/default_avatar"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"/>
|
android:focusable="true"/>
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="127dp"
|
android:layout_height="127dp"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
android:src="@drawable/bg" />
|
android:src="@drawable/default_avatar" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="130dp"
|
android:layout_width="130dp"
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_1"
|
android:id="@+id/suggestion_1"
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_2"
|
android:id="@+id/suggestion_2"
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_3"
|
android:id="@+id/suggestion_3"
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_4"
|
android:id="@+id/suggestion_4"
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_5"
|
android:id="@+id/suggestion_5"
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_6"
|
android:id="@+id/suggestion_6"
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_7"
|
android:id="@+id/suggestion_7"
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_8"
|
android:id="@+id/suggestion_8"
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_9"
|
android:id="@+id/suggestion_9"
|
||||||
@@ -129,7 +129,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_10"
|
android:id="@+id/suggestion_10"
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_11"
|
android:id="@+id/suggestion_11"
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_12"
|
android:id="@+id/suggestion_12"
|
||||||
@@ -162,7 +162,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_13"
|
android:id="@+id/suggestion_13"
|
||||||
@@ -173,7 +173,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_14"
|
android:id="@+id/suggestion_14"
|
||||||
@@ -184,7 +184,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_15"
|
android:id="@+id/suggestion_15"
|
||||||
@@ -195,7 +195,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_16"
|
android:id="@+id/suggestion_16"
|
||||||
@@ -206,7 +206,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_17"
|
android:id="@+id/suggestion_17"
|
||||||
@@ -217,7 +217,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_18"
|
android:id="@+id/suggestion_18"
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_19"
|
android:id="@+id/suggestion_19"
|
||||||
@@ -239,7 +239,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_20"
|
android:id="@+id/suggestion_20"
|
||||||
@@ -250,7 +250,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
android:id="@+id/avatar"
|
android:id="@+id/avatar"
|
||||||
android:layout_width="88dp"
|
android:layout_width="88dp"
|
||||||
android:layout_height="88dp"
|
android:layout_height="88dp"
|
||||||
android:src="@drawable/bg"
|
android:src="@drawable/default_avatar"
|
||||||
android:elevation="1dp"
|
android:elevation="1dp"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"/>
|
android:focusable="true"/>
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_1"
|
android:id="@+id/suggestion_1"
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_2"
|
android:id="@+id/suggestion_2"
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_3"
|
android:id="@+id/suggestion_3"
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_4"
|
android:id="@+id/suggestion_4"
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_5"
|
android:id="@+id/suggestion_5"
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_6"
|
android:id="@+id/suggestion_6"
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_7"
|
android:id="@+id/suggestion_7"
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_8"
|
android:id="@+id/suggestion_8"
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_9"
|
android:id="@+id/suggestion_9"
|
||||||
@@ -129,7 +129,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_10"
|
android:id="@+id/suggestion_10"
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_11"
|
android:id="@+id/suggestion_11"
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_12"
|
android:id="@+id/suggestion_12"
|
||||||
@@ -162,7 +162,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_13"
|
android:id="@+id/suggestion_13"
|
||||||
@@ -173,7 +173,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_14"
|
android:id="@+id/suggestion_14"
|
||||||
@@ -184,7 +184,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_15"
|
android:id="@+id/suggestion_15"
|
||||||
@@ -195,7 +195,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_16"
|
android:id="@+id/suggestion_16"
|
||||||
@@ -206,7 +206,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_17"
|
android:id="@+id/suggestion_17"
|
||||||
@@ -217,7 +217,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_18"
|
android:id="@+id/suggestion_18"
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_19"
|
android:id="@+id/suggestion_19"
|
||||||
@@ -239,7 +239,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/suggestion_20"
|
android:id="@+id/suggestion_20"
|
||||||
@@ -250,7 +250,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@drawable/btn_keyboard"
|
android:background="@drawable/btn_keyboard"
|
||||||
android:textColor="?android:attr/textColorPrimary" />
|
android:textColor="#3C3C3C"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
|
|||||||
@@ -11,10 +11,10 @@
|
|||||||
android:icon="@drawable/shop_selector"
|
android:icon="@drawable/shop_selector"
|
||||||
android:title="Shop" />
|
android:title="Shop" />
|
||||||
|
|
||||||
<item
|
<!-- <item
|
||||||
android:id="@+id/circleFragment"
|
android:id="@+id/circleFragment"
|
||||||
android:icon="@drawable/circle_selector"
|
android:icon="@drawable/circle_selector"
|
||||||
android:title="Circle" />
|
android:title="Circle" /> -->
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/mineFragment"
|
android:id="@+id/mineFragment"
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
<background android:drawable="@drawable/ic_launcher_background"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
<background android:drawable="@drawable/ic_launcher_background"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 5.0 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 982 B After Width: | Height: | Size: 3.0 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 7.6 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 20 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 28 KiB |
@@ -1,5 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?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
|
<subtype
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeLocale="en_US"
|
android:imeSubtypeLocale="en_US"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.13.0"
|
agp = "8.13.1"
|
||||||
kotlin = "2.0.21"
|
kotlin = "2.0.21"
|
||||||
coreKtx = "1.17.0"
|
coreKtx = "1.17.0"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
|
|||||||