稍微完善输入法以及输入法体验页

This commit is contained in:
pengxiaolong
2025-12-11 14:52:29 +08:00
parent 867dad509e
commit 79b5bc0273
45 changed files with 2174 additions and 727 deletions

View File

@@ -1,24 +0,0 @@
package com.example.myapplication
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.example.myapplication", appContext.packageName)
}
}

View File

@@ -18,7 +18,6 @@
android:name=".SplashActivity"
android:exported="true"
android:theme="@style/Theme.MyApp.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -33,7 +32,8 @@
<!-- 输入法体验页 -->
<activity
android:name=".GuideActivity"
android:exported="true"/>
android:exported="true"
android:windowSoftInputMode="stateHidden|adjustNothing" />
<!-- 引导页 -->
<activity

Binary file not shown.

After

Width:  |  Height:  |  Size: 945 B

View File

@@ -1,29 +1,232 @@
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.EditText
import android.widget.FrameLayout
import android.widget.TextView
import android.widget.Toast
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import com.example.myapplication.MyInputMethodService
import android.content.ClipData
import android.content.ClipboardManager
import android.widget.Toast
import androidx.core.widget.NestedScrollView
import de.hdodenhof.circleimageview.CircleImageView
import android.widget.TextView
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.view.inputmethod.InputMethodManager
import android.view.WindowManager
import android.graphics.Rect
import android.view.inputmethod.EditorInfo
import android.view.KeyEvent
class GuideActivity : AppCompatActivity() {
private lateinit var scrollView: NestedScrollView
private lateinit var listLayout: LinearLayout
private lateinit var inputMessage: EditText
private lateinit var btnSend: Button
private lateinit var itemAnim: Animation
private lateinit var bottomPanel: LinearLayout
// 我方的预设回复
private val replyData = listOf(
"你好",
"这是第二条消息",
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_guide)
window.setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN or
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING
)
// 1. 找到控件
scrollView = findViewById(R.id.scrollView)
listLayout = findViewById(R.id.message_list)
inputMessage = findViewById(R.id.input_message)
btnSend = findViewById(R.id.btn_send)
bottomPanel = findViewById(R.id.bottom_panel)
val rootView = findViewById<View>(R.id.rootCoordinator)
// 动画
itemAnim = AnimationUtils.loadAnimation(this, R.anim.item_slide_in_up)
//自动聚焦
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
// 自动弹出键盘
inputMessage.post {
inputMessage.isFocusable = true
inputMessage.isFocusableInTouchMode = true
inputMessage.requestFocus()
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(inputMessage, InputMethodManager.SHOW_FORCED)
}
// 情话复制
findViewById<TextView>(R.id.love_words_1).setOnClickListener {
val text = it as TextView
val clipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
clipboard.setPrimaryClip(ClipData.newPlainText("text", text.text))
Toast.makeText(this, "Copy successfully", Toast.LENGTH_SHORT).show()
}
findViewById<TextView>(R.id.love_words_2).setOnClickListener {
val text = it as TextView
val clipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
clipboard.setPrimaryClip(ClipData.newPlainText("text", text.text))
Toast.makeText(this, "Copy successfully", Toast.LENGTH_SHORT).show()
}
// 关闭按钮
findViewById<FrameLayout>(R.id.iv_close).setOnClickListener {
finish()
}
//输入框上移
rootView.viewTreeObserver.addOnGlobalLayoutListener {
val r = Rect()
// 获取窗口可见区域
rootView.getWindowVisibleDisplayFrame(r)
val screenHeight = rootView.rootView.height
val visibleBottom = r.bottom
val keyboardHeight = screenHeight - visibleBottom
// 这个阈值防止“状态栏/导航栏变化”被误认为键盘
val isKeyboardVisible = keyboardHeight > screenHeight * 0.15
if (isKeyboardVisible) {
// 键盘高度为正,仅仅把 bottomPanel 抬上去
bottomPanel.translationY = -keyboardHeight.toFloat()
// 为了让最后一条消息不被挡住,可以给 scrollView 加个 paddingBottom
scrollView.setPadding(
scrollView.paddingLeft,
scrollView.paddingTop,
scrollView.paddingRight,
keyboardHeight + bottomPanel.height
)
// 再滚到底,保证能看到最新消息
scrollToBottom()
} else {
// 键盘收起,复位
bottomPanel.translationY = 0f
scrollView.setPadding(
scrollView.paddingLeft,
scrollView.paddingTop,
scrollView.paddingRight,
bottomPanel.height // 保持底部有一点空隙也可以按你需求调
)
}
}
// 键盘发送
inputMessage.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_SEND) {
// 走同一套发送逻辑
sendMessage()
true
} else {
false
}
}
// 2. 发送按钮点击事件
btnSend.setOnClickListener {
sendMessage()
}
}
}
// 发送消息
private fun sendMessage() {
val text = inputMessage.text.toString().trim()
// 判空,没输入就不发
if (text.isEmpty()) {
return
}
// 2.1 把“对方”的消息(你刚输入的)显示出来
addOtherPartyMessage(text)
// 2.2 清空输入框
inputMessage.setText("")
val replyText = replyData.random()
// 延迟执行我方回复
scrollView.postDelayed({
addOurMessage(replyText)
}, 500)
inputMessage.isFocusable = true
inputMessage.isFocusableInTouchMode = true
inputMessage.post {
// 重新获取焦点
inputMessage.requestFocus()
// 光标移到文本末尾(虽然现在是空的,但习惯性加上)
inputMessage.setSelection(inputMessage.text.length)
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(inputMessage, InputMethodManager.SHOW_IMPLICIT)
}
}
// ======== 渲染“对方”消息item_other_party_message ========
private fun addOtherPartyMessage(text: String) {
// inflate 对方消息布局
val itemView = layoutInflater.inflate(
R.layout.item_other_party_message,
listLayout,
false
)
val avatar = itemView.findViewById<CircleImageView>(R.id.avatar)
val container = itemView.findViewById<TextView>(R.id.container)
// 头像(你可以换成对方头像)
avatar.setImageResource(R.drawable.logo)
// 显示内容
container.text = text
// 加到列表里
listLayout.addView(itemView)
itemView.startAnimation(itemAnim)
// 每加一条就滚动到底
scrollToBottom()
}
// ======== 渲染“我方”消息item_our_news_message ========
private fun addOurMessage(text: String) {
val itemView = layoutInflater.inflate(
R.layout.item_our_news_message,
listLayout,
false
)
val avatar = itemView.findViewById<CircleImageView>(R.id.avatar)
val container = itemView.findViewById<TextView>(R.id.container)
// 我方头像(随便放一个)
avatar.setImageResource(R.drawable.logo)
container.text = text
listLayout.addView(itemView)
itemView.startAnimation(itemAnim)
scrollToBottom()
}
// ======== 滚动到底部 ========
private fun scrollToBottom() {
scrollView.post {
scrollView.fullScroll(View.FOCUS_DOWN)
}
}
}

View File

@@ -5,28 +5,27 @@ import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.provider.Settings
import android.view.View
import android.util.Log
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 val TAG = "ImeGuideActivity"
// 改成可空,避免 findViewById 返回 null 时直接 NPE
private var btnEnable: LinearLayout? = null
private var btnSelect: LinearLayout? = null
private var tvStep1Status: TextView? = null
private var tvStep2Status: TextView? = null
private var btnEnabledText: TextView? = null
private var btnSelectText: TextView? = null
private var btnEnabledimg: ImageView? = null
private var btnSelectimg: ImageView? = null
private var imeObserver: android.database.ContentObserver? = null
@@ -34,68 +33,79 @@ class ImeGuideActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_ime_guide)
// // 设置关闭按钮点击事件
// findViewById<FrameLayout>(R.id.iv_close).setOnClickListener {
// finish()
// }
Log.d(TAG, "onCreate")
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()
// }
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) // 选择输入法按钮图片
}
override fun onResume() {
super.onResume()
refreshStatus()
registerImeObserver()
try {
refreshStatus()
} catch (e: Exception) {
Log.e(TAG, "refreshStatus 崩了", e)
}
try {
registerImeObserver()
} catch (e: Exception) {
Log.e(TAG, "registerImeObserver 崩了", e)
}
}
override fun onPause() {
super.onPause()
unregisterImeObserver()
try {
unregisterImeObserver()
} catch (e: Exception) {
Log.e(TAG, "unregisterImeObserver 崩了", e)
}
}
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()
try {
refreshStatus()
} catch (e: Exception) {
Log.e(TAG, "onChange -> refreshStatus 崩了", e)
}
}
}
contentResolver.registerContentObserver(
android.provider.Settings.Secure.getUriFor(
android.provider.Settings.Secure.DEFAULT_INPUT_METHOD
),
false,
imeObserver!!
)
try {
contentResolver.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.DEFAULT_INPUT_METHOD),
false,
imeObserver!!
)
} catch (e: SecurityException) {
// 部分 ROM/系统可能在这里抛异常
Log.e(TAG, "registerContentObserver SecurityException", e)
} catch (e: Exception) {
Log.e(TAG, "registerContentObserver 其他异常", e)
}
}
private fun unregisterImeObserver() {
imeObserver?.let {
contentResolver.unregisterContentObserver(it)
try {
contentResolver.unregisterContentObserver(it)
} catch (e: Exception) {
Log.e(TAG, "unregisterContentObserver 异常", e)
}
}
imeObserver = null
}
@@ -104,100 +114,144 @@ class ImeGuideActivity : AppCompatActivity() {
private fun refreshStatus() {
val enabled = isImeEnabled()
val selected = isImeSelected()
// 把所有 view 拿成局部变量并判空,避免 NPE
val enableLayout = btnEnable
val selectLayout = btnSelect
val step1 = tvStep1Status
val step2 = tvStep2Status
val enableText = btnEnabledText
val selectText = btnSelectText
val enableImg = btnEnabledimg
val selectImg = btnSelectimg
if (enableLayout == null || selectLayout == null ||
step1 == null || step2 == null ||
enableText == null || selectText == null ||
enableImg == null || selectImg == null
) {
Log.e(TAG, "有 View 为 null检查 activity_ime_guide.xml 的 id 是否匹配")
return
}
// 根据状态设置按钮的点击行为
if (enabled) {
// 输入法已启用时,禁用启用按钮的点击事件
btnEnable.setOnClickListener(null)
enableLayout.setOnClickListener(null)
} else {
// 输入法未启用时,设置启用按钮的点击事件
btnEnable.setOnClickListener {
enableLayout.setOnClickListener {
startActivity(Intent(Settings.ACTION_INPUT_METHOD_SETTINGS))
}
}
if (selected) {
// 输入法已切换时,禁用选择按钮的点击事件
btnSelect.setOnClickListener(null)
selectLayout.setOnClickListener(null)
} else {
// 输入法未切换时,设置选择按钮的点击事件
btnSelect.setOnClickListener {
selectLayout.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"
if (!enabled && !selected) {
enableLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
selectLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
enableText.setTextColor(Color.parseColor("#FFFFFF"))
selectText.setTextColor(Color.parseColor("#FFFFFF"))
enableImg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
selectImg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
step1.text = "Step one"
step2.text = "Check to enable key of love"
} else if (!enabled && selected) {
enableLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
selectLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
enableImg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
selectImg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
enableText.setTextColor(Color.parseColor("#FFFFFF"))
selectText.setTextColor(Color.parseColor("#FFFFFF"))
step1.text = "Step one"
step2.text = "Check to enable key of love"
} else if (enabled && !selected) {
enableLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_completed)
selectLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
enableImg.setImageResource(R.drawable.ime_guide_activity_btn_completed_img)
selectImg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
enableText.setTextColor(Color.parseColor("#A1A1A1"))
selectText.setTextColor(Color.parseColor("#FFFFFF"))
step1.text = "Step two"
step2.text = "Select key of love as your default input method"
} else if (enabled && selected) {
enableLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_completed)
selectLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_completed)
enableImg.setImageResource(R.drawable.ime_guide_activity_btn_completed_img)
selectImg.setImageResource(R.drawable.ime_guide_activity_btn_completed_img)
enableText.setTextColor(Color.parseColor("#A1A1A1"))
selectText.setTextColor(Color.parseColor("#A1A1A1"))
step1.text = "Completed"
step2.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))
try {
startActivity(Intent(this, GuideActivity::class.java))
} catch (e: Exception) {
Log.e(TAG, "启动 GuideActivity 失败,检查是否在 Manifest 中声明", e)
}
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 isImeEnabled(): Boolean {
return try {
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
val myComponent = ComponentName(this, MyInputMethodService::class.java)
val result = imm.enabledInputMethodList.any { imeInfo ->
imeInfo.packageName == myComponent.packageName &&
imeInfo.serviceName == myComponent.className
}
Log.d(TAG, "isImeEnabled = $result")
result
} catch (e: Exception) {
Log.e(TAG, "isImeEnabled 出错", e)
false
}
}
/** 是否已切换为当前输入法 */
private fun isImeSelected(): Boolean {
val currentIme = Settings.Secure.getString(
/** 是否已切换为当前输入法 */
private fun isImeSelected(): Boolean {
return try {
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
val myComponent = ComponentName(this, MyInputMethodService::class.java)
val currentImeId = 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
Log.d(TAG, "DEFAULT_INPUT_METHOD = $currentImeId")
// 找到“当前默认 IME”对应的 InputMethodInfo
val currentImeInfo = imm.enabledInputMethodList.firstOrNull { imeInfo ->
imeInfo.id == currentImeId
}
if (currentImeInfo == null) {
Log.d(TAG, "currentImeInfo == null")
return false
}
val isMine = currentImeInfo.packageName == myComponent.packageName &&
currentImeInfo.serviceName == myComponent.className
Log.d(TAG, "isImeSelected = $isMine")
isMine
} catch (e: Exception) {
Log.e(TAG, "isImeSelected 出错", e)
false
}
}
}

View File

@@ -34,15 +34,21 @@ class MainActivity : AppCompatActivity() {
// 5. 添加导航监听(用于某些 Fragment 隐藏底部导航栏)
navController.addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.rechargeFragment, R.id.goldCoinRechargeFragment,R.id.PersonalSettings,R.id.MySkin,R.id.searchFragment,R.id.MyKeyboard,R.id.searchResultFragment,R.id.keyboardDetailFragment,R.id.feedbackFragment,R.id.notificationFragment-> {
bottomNav.visibility = View.GONE
}
else -> {
bottomNav.visibility = View.VISIBLE
}
// 只有这些页面显示 BottomNav
val pagesWithBottomNav = setOf(
R.id.mineFragment,
R.id.homeFragment,
R.id.shopFragment
)
if (destination.id in pagesWithBottomNav) {
bottomNav.visibility = View.VISIBLE
} else {
bottomNav.visibility = View.GONE
}
}
// 6. 检查是否有导航参数,处理从键盘跳转过来的请求
handleNavigationFromIntent()

View File

@@ -31,6 +31,11 @@ import com.example.myapplication.keyboard.MainKeyboard
import com.example.myapplication.keyboard.NumberKeyboard
import com.example.myapplication.keyboard.SymbolKeyboard
import com.example.myapplication.keyboard.AiKeyboard
import android.text.InputType
import android.view.KeyEvent
import android.os.SystemClock
class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
@@ -119,6 +124,16 @@ class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
ColorStateList.valueOf(Color.TRANSPARENT)
private set
// 键盘关闭
override fun getInputConnection(): InputConnection? {
return currentInputConnection
}
override fun hideKeyboard() {
currentInputConnection?.finishComposingText()
requestHideSelf(0)
}
// 副字符映射表(主键盘上滑)
private val swipeAltMap: Map<Char, Char> = mapOf(
'q' to '1',
@@ -204,6 +219,8 @@ class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
tryStartForegroundSafe()
}
private fun createNotificationChannelIfNeeded() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
@@ -245,7 +262,43 @@ class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
override fun onStartInputView(info: EditorInfo?, restarting: Boolean) {
super.onStartInputView(info, restarting)
isInputViewShownFlag = true
showMainKeyboard()
// 根据当前输入框类型自动切换键盘
if (isNumberEditor(info)) {
showNumberKeyboard()
} else {
showMainKeyboard()
}
}
//判断当前输入框是否是数字相关输入框:
private fun isNumberEditor(info: EditorInfo?): Boolean {
if (info == null) return false
val inputType = info.inputType
val clazz = inputType and InputType.TYPE_MASK_CLASS
val variation = inputType and InputType.TYPE_MASK_VARIATION
// 纯数字、电话输入
if (clazz == InputType.TYPE_CLASS_NUMBER || clazz == InputType.TYPE_CLASS_PHONE) {
return true
}
// 数字密码numberPassword
if (clazz == InputType.TYPE_CLASS_TEXT &&
variation == InputType.TYPE_TEXT_VARIATION_PASSWORD &&
(inputType and InputType.TYPE_NUMBER_FLAG_DECIMAL != 0 ||
inputType and InputType.TYPE_NUMBER_FLAG_SIGNED != 0)
) {
return true
}
return false
}
override fun onFinishInput() {
super.onFinishInput()
clearEditorState()
}
override fun onFinishInputView(finishingInput: Boolean) {
@@ -253,6 +306,9 @@ class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
isInputViewShownFlag = false
stopRepeatDelete()
// 清理本次输入状态
clearEditorState()
mainHandler.postDelayed({
if (!isInputViewShownFlag) {
try {
@@ -283,12 +339,22 @@ class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
)
mainKeyboardView = mainKeyboard!!.rootView
// 这里再给删除键挂长按连删(用你自己的 attachRepeatDeleteInternal
// 初始状态:隐藏联想条,显示控制面板
mainKeyboardView
?.findViewById<HorizontalScrollView>(R.id.completion_scroll)
?.visibility = View.GONE
mainKeyboardView
?.findViewById<LinearLayout>(R.id.control_layout)
?.visibility = View.VISIBLE
// 删除键长按连删
val delId = resources.getIdentifier("key_del", "id", packageName)
mainKeyboardView?.findViewById<View?>(delId)?.let { attachRepeatDeleteInternal(it) }
}
return mainKeyboard!!
}
private fun ensureNumberKeyboard(): NumberKeyboard {
if (numberKeyboard == null) {
@@ -398,26 +464,39 @@ class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
// 删除一个字符(原 handleBackspace
override fun deleteOne() {
val ic = currentInputConnection ?: return
ic.deleteSurroundingText(1, 0)
// 1⃣ 发送一个 DEL 按键DOWN + UP让客户端有机会拦截
ic.sendKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
ic.sendKeyEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL))
// 如果你担心有些 EditText 不处理 DEL可以加一个兜底
// ic.deleteSurroundingText(1, 0)
// 2⃣ 你原来的逻辑可以继续保留
val prefix = getCurrentWordPrefix()
updateCompletionsAndRender(prefix)
playKeyClick()
}
// 发送(原 performSendAction
// 发送(标准 SEND + 回车 fallback
override fun performSendAction() {
val ic = currentInputConnection ?: return
// 1. 尝试执行标准发送动作IME_ACTION_SEND
val handled = ic.performEditorAction(EditorInfo.IME_ACTION_SEND)
if (!handled) {
// 2. 如果输入框不支持 SEND则退回到插入换行
ic.commitText("\n", 1)
}
playKeyClick()
clearEditorState()
}
// 按键音效
override fun playKeyClick() {
try {
@@ -436,15 +515,31 @@ class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
// 统一处理补全/联想
override fun updateCompletionsAndRender(prefix: String) {
val ic = currentInputConnection
// 先判断整个编辑框是不是“真的空”
val beforeAll = ic?.getTextBeforeCursor(256, 0)?.toString().orEmpty()
val afterAll = ic?.getTextAfterCursor(256, 0)?.toString().orEmpty()
val editorReallyEmpty = beforeAll.isEmpty() && afterAll.isEmpty()
// 当前输入前缀
currentInput.clear()
currentInput.append(prefix)
// 如果整个编辑框都是空的:直接清空联想 & 刷新 UI什么都不算
if (editorReallyEmpty) {
clearEditorState()
return
}
// 否则再去算 lastWord
val lastWord = getPrevWordBeforeCursor()
Thread {
val list = try {
if (prefix.isEmpty()) {
if (lastWord == null) {
// 这里也保持 emptyList防止空前缀 + 无上文时走全局高频随机词
emptyList()
} else {
suggestWithBigram("", lastWord, topK = 20)
@@ -468,13 +563,14 @@ class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
emptyList()
}
}
mainHandler.post {
completionSuggestions = suggestionStats.sortByCount(list.distinct().take(20))
showCompletionSuggestions()
}
}.start()
}
// 显示自动完成建议(布局不变)
private fun showCompletionSuggestions() {
@@ -482,14 +578,43 @@ class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
val suggestionsView =
mainKeyboardView?.findViewById<LinearLayout>(R.id.completion_suggestions)
// 新增:联想滚动条 & 控制面板
val completionScroll =
mainKeyboardView?.findViewById<HorizontalScrollView>(R.id.completion_scroll)
val controlLayout =
mainKeyboardView?.findViewById<LinearLayout>(R.id.control_layout)
val suggestions = (0..20).map { i ->
mainKeyboardView?.findViewById<TextView>(
resources.getIdentifier("suggestion_$i", "id", packageName)
)
}
// suggestion_0 显示 prefix
// 当前前缀
val prefix = getCurrentWordPrefix()
val hasPrefix = prefix.isNotEmpty()
val hasSuggestions = completionSuggestions.isNotEmpty()
// 判断光标前是否有任何输入(“没有输入”的判断)
val hasAnyInput = try {
val ic = currentInputConnection
val before = ic?.getTextBeforeCursor(1, 0)
!before.isNullOrEmpty()
} catch (_: Throwable) {
false
}
// 当:没有前缀 && 没有联想/补全词 && 光标前也没有任何输入
// -> 隐藏联想条,显示控制面板
if (!hasPrefix && !hasSuggestions && !hasAnyInput) {
completionScroll?.visibility = View.GONE
controlLayout?.visibility = View.VISIBLE
} else {
completionScroll?.visibility = View.VISIBLE
controlLayout?.visibility = View.GONE
}
// suggestion_0 显示 prefix
suggestions[0]?.text = prefix
suggestions[0]?.visibility = if (prefix.isEmpty()) View.GONE else View.VISIBLE
suggestions[0]?.setOnClickListener {
@@ -500,11 +625,13 @@ class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
suggestions.drop(1).forEachIndexed { index, textView ->
textView?.text = completionSuggestions.getOrNull(index) ?: ""
if (index < completionSuggestions.size) {
textView?.visibility = View.VISIBLE
textView?.setOnClickListener {
suggestionStats.incClick(completionSuggestions[index])
insertCompletion(completionSuggestions[index])
}
} else {
textView?.visibility = View.GONE
textView?.setOnClickListener(null)
}
}
@@ -513,6 +640,7 @@ class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
}
}
// 自动滚回到最左边
private fun scrollSuggestionsToStart() {
val sv = mainKeyboardView?.findViewById<HorizontalScrollView>(R.id.completion_scroll)
@@ -741,4 +869,71 @@ class MyInputMethodService : InputMethodService(), KeyboardEnvironment {
out.reverse()
return out
}
override fun onUpdateSelection(
oldSelStart: Int,
oldSelEnd: Int,
newSelStart: Int,
newSelEnd: Int,
candidatesStart: Int,
candidatesEnd: Int
) {
super.onUpdateSelection(
oldSelStart,
oldSelEnd,
newSelStart,
newSelEnd,
candidatesStart,
candidatesEnd
)
val ic = currentInputConnection ?: return
// 这里不用取太多1 个字符就够判断是否为空了
val before = ic.getTextBeforeCursor(1, 0)?.toString().orEmpty()
val after = ic.getTextAfterCursor(1, 0)?.toString().orEmpty()
// 当编辑框光标前后都没有任何字符,说明真的完全空了
if (before.isEmpty() && after.isEmpty()) {
clearEditorState()
}
}
// 清理本次编辑框相关的状态(光标、联想、长按等)
private fun clearEditorState() {
// 1. 文本联想/补全相关
currentInput.clear()
completionSuggestions = emptyList()
lastWordForLM = null
// 2. Shift 状态
isShiftOn = false
// 3. 停止长按删除
stopRepeatDelete()
// 4. UI联想条隐藏 & 控制面板显示
mainHandler.post {
val completionScroll =
mainKeyboardView?.findViewById<HorizontalScrollView>(R.id.completion_scroll)
val controlLayout =
mainKeyboardView?.findViewById<LinearLayout>(R.id.control_layout)
completionScroll?.visibility = View.GONE
controlLayout?.visibility = View.VISIBLE
// 再让联想区域里的文本都清空一下
val suggestions = (0..20).map { i ->
mainKeyboardView?.findViewById<TextView>(
resources.getIdentifier("suggestion_$i", "id", packageName)
)
}
suggestions.forEach { tv ->
tv?.text = ""
tv?.visibility = View.GONE
tv?.setOnClickListener(null)
}
}
}
}

View File

@@ -5,6 +5,7 @@ import android.content.res.ColorStateList
import android.media.AudioManager
import android.os.Handler
import android.view.LayoutInflater
import android.view.inputmethod.InputConnection
interface KeyboardEnvironment {
val ctx: Context
@@ -27,6 +28,10 @@ interface KeyboardEnvironment {
fun deleteOne()
fun performSendAction()
//键盘关闭
fun getInputConnection(): InputConnection?
fun hideKeyboard()
// 键盘切换
fun showMainKeyboard()
fun showNumberKeyboard()

View File

@@ -40,8 +40,8 @@ class MainKeyboard(
env.ctx.getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator
private fun vibrateKey(
duration: Long = 20L, // 时间10~40 推荐
amplitude: Int = 150 // 1~255100~150 最舒服
duration: Long = 30L, // 时间10~40 推荐
amplitude: Int = 255 // 1~255100~150 最舒服
) {
val v = vibrator ?: return
if (!v.hasVibrator()) return
@@ -93,7 +93,8 @@ class MainKeyboard(
"key_del",
"key_up",
"key_123",
"key_ai"
"key_ai",
"Key_collapse"
)
for (idName in others) {
applyKeyBackground(root, idName)
@@ -192,6 +193,13 @@ class MainKeyboard(
env.deleteOne()
}
//关闭键盘
rootView.findViewById<View?>(res.getIdentifier("collapse_button", "id", pkg))
?.setOnClickListener {
vibrateKey() // 如果这个方法在当前类里有
env.hideKeyboard()
}
// 切换数字键盘
view.findViewById<View?>(res.getIdentifier("key_123", "id", pkg))
?.setOnClickListener {

View File

@@ -35,8 +35,8 @@ class NumberKeyboard(
env.ctx.getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator
private fun vibrateKey(
duration: Long = 20L, // 时间10~40 推荐
amplitude: Int = 150 // 1~255100~150 最舒服
duration: Long = 30L, // 时间10~40 推荐
amplitude: Int = 255 // 1~255100~150 最舒服
) {
val v = vibrator ?: return
if (!v.hasVibrator()) return
@@ -111,7 +111,8 @@ class NumberKeyboard(
"key_ai",
"key_space",
"key_send",
"key_del"
"key_del",
"Key_collapse"
)
others.forEach { idName ->
applyKeyBackground(root, idName)
@@ -246,6 +247,13 @@ class NumberKeyboard(
vibrateKey()
env.deleteOne()
}
//关闭键盘
rootView.findViewById<View?>(res.getIdentifier("collapse_button", "id", pkg))
?.setOnClickListener {
vibrateKey() // 如果这个方法在当前类里有
env.hideKeyboard()
}
}
// ================= 按键触摸 & 预览 =================

View File

@@ -35,8 +35,8 @@ class SymbolKeyboard(
env.ctx.getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator
private fun vibrateKey(
duration: Long = 20L, // 时间10~40 推荐
amplitude: Int = 150 // 1~255100~150 最舒服
duration: Long = 30L, // 时间10~40 推荐
amplitude: Int = 255 // 1~255100~150 最舒服
) {
val v = vibrator ?: return
if (!v.hasVibrator()) return
@@ -121,7 +121,8 @@ class SymbolKeyboard(
"key_abc",
"key_ai",
"key_space",
"key_send"
"key_send",
"Key_collapse"
)
others.forEach { idName ->
@@ -264,6 +265,13 @@ class SymbolKeyboard(
vibrateKey()
env.showAiKeyboard()
}
//关闭键盘
rootView.findViewById<View?>(res.getIdentifier("collapse_button", "id", pkg))
?.setOnClickListener {
vibrateKey() // 如果这个方法在当前类里有
env.hideKeyboard()
}
}
// ================== 触摸 + 预览 ==================

View File

@@ -66,7 +66,9 @@ class HomeFragment : Fragment() {
}
//输入法激活跳转
view.findViewById<ImageView>(R.id.floatingImage).setOnClickListener {
startActivity(Intent(requireContext(), ImeGuideActivity::class.java))
if (isAdded) {
startActivity(Intent(requireActivity(), ImeGuideActivity::class.java))
}
}
scrim = view.findViewById(R.id.view_scrim)

View File

@@ -0,0 +1,31 @@
// 忘记密码邮箱输入页面
package com.example.myapplication.ui.login
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.myapplication.R
import com.google.android.material.textfield.TextInputLayout
import android.widget.TextView
import androidx.navigation.fragment.findNavController
class ForgetPasswordEmailFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_forget_password_email, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//验证码页面
view.findViewById<TextView>(R.id.nextstep).setOnClickListener {
findNavController().navigate(R.id.action_forgetPasswordEmailFragment_to_forgetPasswordVerifyFragment)
}
}
}

View File

@@ -0,0 +1,21 @@
// 忘记密码重置密码页面
package com.example.myapplication.ui.login
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.myapplication.R
class ForgetPasswordResetFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_forget_password_reset, container, false)
}
}

View File

@@ -0,0 +1,116 @@
// 忘记密码验证码输入页面
package com.example.myapplication.ui.login
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.fragment.app.Fragment
import com.example.myapplication.R
import android.widget.TextView
import androidx.navigation.fragment.findNavController
class ForgetPasswordVerifyFragment : Fragment() {
private lateinit var codeInputs: List<EditText>
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_forget_password_verify, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//验证码页面
view.findViewById<
TextView>(R.id.nextstep).setOnClickListener {
findNavController().navigate(R.id.action_forgetPasswordVerifyFragment_to_forgetPasswordResetFragment)
}
codeInputs = listOf<EditText>(
view.findViewById(R.id.et_code_1),
view.findViewById(R.id.et_code_2),
view.findViewById(R.id.et_code_3),
view.findViewById(R.id.et_code_4),
view.findViewById(R.id.et_code_5),
view.findViewById(R.id.et_code_6)
)
setupVerifyCodeInputs()
}
private fun setupVerifyCodeInputs() {
codeInputs.forEachIndexed { index, editText ->
// 输入监听:自动跳到下一格
editText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable?) {
val text = s?.toString() ?: ""
// 保证只有1位
if (text.length > 1) {
editText.setText(text.last().toString())
editText.setSelection(1)
}
if (text.isNotEmpty() && index < codeInputs.size - 1) {
codeInputs[index + 1].requestFocus()
}
}
})
// 关键:监听删除键,通过 EditorAction 捕捉硬件删除
editText.setOnKeyListener { _, keyCode, event ->
if (event.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_DEL) {
// 当前为空 -> 回到上一格
if (editText.text.isEmpty() && index > 0) {
val prev = codeInputs[index - 1]
prev.requestFocus()
prev.text.clear()
return@setOnKeyListener true
}
}
false
}
// 特别关键:有些系统不会触发 KEYCODE_DEL这个可以兜底捕捉删除动作
editText.setOnEditorActionListener { _, _, event ->
if (event != null &&
event.action == KeyEvent.ACTION_DOWN &&
event.keyCode == KeyEvent.KEYCODE_DEL
) {
if (editText.text.isEmpty() && index > 0) {
val prev = codeInputs[index - 1]
prev.requestFocus()
prev.text.clear()
true
} else false
} else false
}
}
}
// 获取完整验证码
private fun getVerifyCode(): String {
return codeInputs.joinToString("") { it.text.toString() }
}
}

View File

@@ -0,0 +1,82 @@
package com.example.myapplication.ui.login
import android.os.Bundle
import android.text.InputType
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import android.widget.FrameLayout
import android.widget.TextView
import com.example.myapplication.R
import com.google.android.material.button.MaterialButton
class LoginFragment : Fragment() {
private lateinit var passwordEditText: EditText
private lateinit var toggleImageView: ImageView
private lateinit var loginButton: MaterialButton // 如果你 XML 里有这个按钮 id: btn_login
private var isPasswordVisible = false
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_login, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// 注册
view.findViewById<TextView>(R.id.tv_signup).setOnClickListener {
findNavController().navigate(R.id.action_mineFragment_to_registerFragment)
}
// 忘记密码
view.findViewById<TextView>(R.id.tv_forgot_password).setOnClickListener {
findNavController().navigate(R.id.action_loginFragment_to_forgetPasswordEmailFragment)
}
// 返回按钮
view.findViewById<FrameLayout>(R.id.iv_close).setOnClickListener {
parentFragmentManager.popBackStack()
}
// 绑定控件id 必须和 xml 里的一样)
passwordEditText = view.findViewById(R.id.et_password)
toggleImageView = view.findViewById(R.id.iv_toggle)
// loginButton = view.findViewById(R.id.btn_login) // 如果没有这个按钮就把这一行和变量删了
// 初始是隐藏密码状态
passwordEditText.inputType =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
toggleImageView.setOnClickListener {
isPasswordVisible = !isPasswordVisible
if (isPasswordVisible) {
// 显示密码
passwordEditText.inputType =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
toggleImageView.setImageResource(R.drawable.display)
} else {
// 隐藏密码
passwordEditText.inputType =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
toggleImageView.setImageResource(R.drawable.hide)
}
// 保持光标在末尾
passwordEditText.setSelection(passwordEditText.text?.length ?: 0)
}
// // 登录按钮逻辑你自己填
// loginButton.setOnClickListener {
// val pwd = passwordEditText.text?.toString().orEmpty()
// // TODO: 登录处理
// }
}
}

View File

@@ -0,0 +1,31 @@
package com.example.myapplication.ui.login
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import android.widget.FrameLayout
import android.widget.TextView
import com.example.myapplication.R
class RegisterFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_register, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// 返回按钮
view.findViewById<FrameLayout>(R.id.iv_close).setOnClickListener {
parentFragmentManager.popBackStack()
}
}
}

View File

@@ -55,5 +55,10 @@ class MineFragment : Fragment() {
findNavController().navigate(R.id.action_mineFragment_to_notificationFragment)
}
//隐私政策
view.findViewById<LinearLayout>(R.id.click_Privacy).setOnClickListener {
findNavController().navigate(R.id.action_mineFragment_to_loginFragment)
}
}
}

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/decelerate_cubic">
<!-- 位移动画:从稍微偏下的位置移动到原位 -->
<translate
android:fromYDelta="20%"
android:toYDelta="0"
android:duration="250" />
<!-- 透明度动画:从透明到不透明 -->
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="250" />
</set>

View File

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

View File

@@ -0,0 +1,4 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#F4F8FB"/>
<corners android:radius="6dp"/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1002 B

View File

@@ -0,0 +1,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color=" #F4F8FB" /> <!-- 背景色 -->
<corners android:radius="12dp" /> <!-- 圆角半径,越大越圆 -->
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -0,0 +1,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#02BEAC" />
<corners android:radius="10dp" />
</shape>

View File

@@ -0,0 +1,14 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
<stroke
android:width="1dp"
android:color="#FFFFFF" />
<corners
android:topLeftRadius="36dp"
android:topRightRadius="36dp"
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 KiB

View File

@@ -0,0 +1,9 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#02BEAC" />
<corners
android:topLeftRadius="10dp"
android:topRightRadius="0dp"
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp" />
</shape>

View File

@@ -0,0 +1,9 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners
android:topLeftRadius="0dp"
android:topRightRadius="10dp"
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp" />
</shape>

View File

@@ -1,39 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootCoordinator"
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_height="match_parent"
android:background="#F6F7FB"
tools:context=".ui.home.MyKeyboard">
<ImageView
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="键盘体验页" />
android:src="@drawable/login_bg"
android:scaleType="fitXY"
android:adjustViewBounds="true" />
<!-- 标题和返回 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<!-- 返回按钮 -->
<FrameLayout
android:id="@+id/iv_close"
android:layout_width="46dp"
android:layout_marginStart="13dp"
android:layout_height="46dp">
<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>
</FrameLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="46dp"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="16dp">
<!-- 我方消息 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical">
<!-- 头像 -->
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/avatar"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="5dp"
android:clickable="true"
android:focusable="true"
android:src="@drawable/logo" />
<!-- 消息内容 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginTop="-20dp"
android:background="@drawable/our_news"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Welcome to use the [key of love] keyboard"
android:textColor="#929292"
android:textSize="10sp" />
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxWidth="179dp"
android:layout_marginTop="12dp"
android:text="Click &quot;Copy any conversation&quot;, &quot;Paste&quot; and try replying using the keyboard [Persona] method"
android:textColor="#929292"
android:textSize="10sp"
android:lineHeight="20dp" />
<TextView
android:id="@+id/love_words_1"
android:layout_width="203dp"
android:layout_height="29dp"
android:layout_marginTop="8dp"
android:gravity="center"
android:text="I miss you"
android:textColor="#1B1F1A"
android:background="@drawable/acttivity_guide_btn_bg"
android:textSize="10sp" />
<TextView
android:id="@+id/love_words_2"
android:layout_width="203dp"
android:layout_height="29dp"
android:layout_marginTop="8dp"
android:gravity="center"
android:text="I'm going to take a bath"
android:textColor="#1B1F1A"
android:background="@drawable/acttivity_guide_btn_bg"
android:textSize="10sp" />
</LinearLayout>
</LinearLayout>
<!-- 渲染消息列表 -->
<LinearLayout
android:id="@+id/message_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<LinearLayout
android:id="@+id/bottom_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:padding="16dp"
android:layout_gravity="bottom">
<EditText
android:id="@+id/input_message"
android:layout_width="200dp"
android:layout_height="52dp"
android:background="@drawable/input_box_bg"
android:padding="15dp"
android:hint="Please enter your content"
android:textColorHint="#CBCBCB"
android:textSize="14sp"
android:textColor="#CBCBCB"
android:focusable="true"
android:focusableInTouchMode="true"
android:cursorVisible="true"
android:imeOptions="actionSend"
android:inputType="text"/>
<Button
android:id="@+id/btn_send"
android:layout_width="60dp"
android:layout_height="52dp"
android:text="Send"
android:textColor="#FFFFFF"
android:textSize="14sp"
android:imeOptions="actionSend"
android:inputType="text"/>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -0,0 +1,81 @@
<!-- 忘记密码邮箱输入页面 -->
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootCoordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F6F7FB"
tools:context=".ui.login.ForgetPasswordEmailFragment">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
<!-- 标题和返回 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<FrameLayout
android:id="@+id/iv_close"
android:layout_width="46dp"
android:layout_height="46dp">
<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>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="30dp"
android:orientation="vertical">
<!-- 标题 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textStyle="bold"
android:text="Reset password"
android:textColor="#1B1F1A"/>
<EditText
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginTop="20dp"
android:background="@drawable/input_box_bg"
android:padding="15dp"
android:hint="Enter email address"
android:textColorHint="#CBCBCB"
android:textSize="14sp"
android:textColor="#CBCBCB" />
<TextView
android:id="@+id/nextstep"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginTop="20dp"
android:background="@drawable/login_btn_bg"
android:gravity="center"
android:textStyle="bold"
android:textColor="#FFFFFF"
android:textSize="18sp"
android:text="Next step" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -0,0 +1,121 @@
<!-- 忘记密码重置密码页面 -->
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootCoordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F6F7FB"
tools:context=".ui.login.ForgetPasswordResetFragment">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
<!-- 标题和返回 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<FrameLayout
android:id="@+id/iv_close"
android:layout_width="46dp"
android:layout_height="46dp">
<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>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="30dp"
android:orientation="vertical">
<!-- 标题 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textStyle="bold"
android:text="Reset password"
android:textColor="#1B1F1A"/>
<RelativeLayout
android:layout_width="match_parent"
android:background="@drawable/input_box_bg"
android:layout_marginTop="14dp"
android:layout_height="52dp">
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="14sp"
android:padding="15dp"
android:textColor="#000000"
android:hint="Enter password"
android:textColorHint="#CBCBCB"
android:background="@null"
android:inputType="textPassword" />
<ImageView
android:id="@+id/iv_toggle"
android:layout_width="52dp"
android:layout_height="52dp"
android:padding="16dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@drawable/hide" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:background="@drawable/input_box_bg"
android:layout_marginTop="14dp"
android:layout_height="52dp">
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="14sp"
android:padding="15dp"
android:textColor="#000000"
android:hint="Enter repeat password"
android:textColorHint="#CBCBCB"
android:background="@null"
android:inputType="textPassword" />
<ImageView
android:id="@+id/iv_toggle"
android:layout_width="52dp"
android:layout_height="52dp"
android:padding="16dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@drawable/hide" />
</RelativeLayout>
<TextView
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginTop="20dp"
android:background="@drawable/login_btn_bg"
android:gravity="center"
android:textStyle="bold"
android:textColor="#FFFFFF"
android:textSize="18sp"
android:text="Next step" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -0,0 +1,111 @@
<!-- 忘记密码验证码输入页面 -->
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootCoordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
tools:context=".ui.login.ForgetPasswordVerifyFragment">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
<!-- 标题和返回 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<FrameLayout
android:id="@+id/iv_close"
android:layout_width="46dp"
android:layout_height="46dp">
<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>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="30dp"
android:orientation="vertical">
<!-- 标题 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textStyle="bold"
android:text="Reset password"
android:textColor="#1B1F1A"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="13sp"
android:textStyle="bold"
android:text="Enter email verification code"
android:textColor="#1B1F1A"/>
<!-- 验证码输入框 -->
<LinearLayout
android:id="@+id/ll_code_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:gravity="center"
android:orientation="horizontal">
<EditText
android:id="@+id/et_code_1"
style="@style/VerifyCodeBox" />
<EditText
android:id="@+id/et_code_2"
style="@style/VerifyCodeBox" />
<EditText
android:id="@+id/et_code_3"
style="@style/VerifyCodeBox" />
<EditText
android:id="@+id/et_code_4"
style="@style/VerifyCodeBox" />
<EditText
android:id="@+id/et_code_5"
style="@style/VerifyCodeBox" />
<EditText
android:id="@+id/et_code_6"
style="@style/VerifyCodeBox" />
</LinearLayout>
<TextView
android:id="@+id/nextstep"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginTop="20dp"
android:background="@drawable/login_btn_bg"
android:gravity="center"
android:textStyle="bold"
android:textColor="#FFFFFF"
android:textSize="18sp"
android:text="Next step" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -0,0 +1,244 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootCoordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F6F7FB"
tools:context=".ui.login.LoginFragment">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/login_bg"
android:scaleType="fitXY"
android:adjustViewBounds="true" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
<!-- 标题和返回 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<FrameLayout
android:id="@+id/iv_close"
android:layout_width="46dp"
android:layout_height="46dp">
<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>
<!-- 标题图片 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginStart="16dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="Hello"
android:textStyle="bold"
android:textColor="#403B5A" />
<TextView
android:layout_width="130dp"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="Welcome to key of love keyboard"
android:textColor="#554F70" />
</LinearLayout>
<ImageView
android:layout_width="243dp"
android:layout_height="223dp"
android:layout_marginStart="-35dp"
android:src="@drawable/login_icon"
android:scaleType="fitCenter" />
</LinearLayout>
<!-- 内容 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minHeight="200dp"
android:padding="16dp"
android:layout_marginTop="-10dp"
android:background="@drawable/login_content_bg"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginTop="10dp"
android:textStyle="bold"
android:text="Log in to key of love"
android:textColor="#1B1F1A" />
<!-- 输入框 -->
<EditText
android:id="@+id/et_username"
android:layout_width="315dp"
android:layout_height="52dp"
android:layout_marginTop="20dp"
android:background="@drawable/input_box_bg"
android:padding="15dp"
android:hint="Please enter your email address"
android:textColorHint="#CBCBCB"
android:textSize="14sp"
android:textColor="#CBCBCB" />
<!-- 密码输入框 -->
<RelativeLayout
android:layout_width="315dp"
android:background="@drawable/input_box_bg"
android:layout_marginTop="14dp"
android:layout_height="52dp">
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="14sp"
android:padding="15dp"
android:textColor="#000000"
android:hint="Please enter the password"
android:textColorHint="#CBCBCB"
android:background="@null"
android:inputType="textPassword" />
<ImageView
android:id="@+id/iv_toggle"
android:layout_width="52dp"
android:layout_height="52dp"
android:padding="16dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@drawable/hide" />
</RelativeLayout>
<!-- 登录按钮 -->
<TextView
android:id="@+id/btn_login"
android:layout_width="315dp"
android:layout_height="52dp"
android:layout_marginTop="20dp"
android:background="@drawable/login_btn_bg"
android:gravity="center"
android:textStyle="bold"
android:textColor="#FFFFFF"
android:textSize="18sp"
android:text="Login" />
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/agreement_container"
android:layout_width="350dp"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:layout_gravity="center_horizontal"
android:paddingHorizontal="20dp"
app:flexDirection="row"
app:flexWrap="wrap"
app:justifyContent="center"
app:alignItems="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="By Continuing, You Agree To Our "
android:textSize="10sp"
android:textColor="#554F70"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Terms Of Service "
android:textStyle="bold"
android:textSize="10sp"
android:textColor="#554F70"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="And Confirm"
android:textSize="10sp"
android:textColor="#554F70"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="That You Have Read Our "
android:textSize="10sp"
android:textColor="#554F70"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Privacy Policy"
android:textStyle="bold"
android:textSize="10sp"
android:textColor="#554F70"/>
</com.google.android.flexbox.FlexboxLayout>
</LinearLayout>
<!-- 注册和忘记密码 -->
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/agreement_container"
android:layout_width="match_parent"
android:layout_height="77dp"
android:layout_gravity="center_horizontal"
android:paddingHorizontal="20dp"
android:padding="16dp"
app:flexDirection="row"
app:flexWrap="wrap"
app:justifyContent="center"
app:alignItems="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Don't have an account?"
android:textSize="12sp"
android:textColor="#554F70"/>
<TextView
android:id="@+id/tv_signup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="Sign up"
android:textStyle="bold"
android:textSize="12sp"
android:textColor="#02BEAC"/>
<TextView
android:id="@+id/tv_forgot_password"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:text="Forgot password?"
android:layout_marginTop="6dp"
android:gravity="center"
android:textStyle="bold"
android:textSize="12sp"
android:textColor="#02BEAC"/>
</com.google.android.flexbox.FlexboxLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -345,6 +345,7 @@
<!-- 隐私政策 -->
<LinearLayout
android:id="@+id/click_Privacy"
android:layout_width="match_parent"
android:layout_height="64dp"
android:gravity="center_vertical"

View File

@@ -0,0 +1,229 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootCoordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F6F7FB"
tools:context=".ui.login.LoginFragment">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/login_bg"
android:scaleType="fitXY"
android:adjustViewBounds="true" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
<!-- 标题和返回 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<FrameLayout
android:id="@+id/iv_close"
android:layout_width="46dp"
android:layout_height="46dp">
<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>
<!-- 标题图片 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginStart="16dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="Hello"
android:textStyle="bold"
android:textColor="#403B5A" />
<TextView
android:layout_width="130dp"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="Welcome to key of love keyboard"
android:textColor="#554F70" />
</LinearLayout>
<ImageView
android:layout_width="243dp"
android:layout_height="223dp"
android:layout_marginStart="-35dp"
android:src="@drawable/login_icon"
android:scaleType="fitCenter" />
</LinearLayout>
<!-- 内容 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minHeight="200dp"
android:padding="16dp"
android:layout_marginTop="-10dp"
android:background="@drawable/login_content_bg"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginTop="10dp"
android:textStyle="bold"
android:text="Log in to key of love"
android:textColor="#1B1F1A" />
<!-- 输入框 -->
<EditText
android:id="@+id/et_username"
android:layout_width="315dp"
android:layout_height="52dp"
android:layout_marginTop="20dp"
android:background="@drawable/input_box_bg"
android:hint="Enter email address"
android:textColorHint="#CBCBCB"
android:padding="15dp"
android:textSize="14sp"
android:textColor="#CBCBCB" />
<!-- 密码输入框 -->
<RelativeLayout
android:layout_width="315dp"
android:background="@drawable/input_box_bg"
android:layout_marginTop="14dp"
android:layout_height="52dp">
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="14sp"
android:padding="15dp"
android:textColor="#000000"
android:hint="Enter password"
android:textColorHint="#CBCBCB"
android:background="@null"
android:inputType="textPassword" />
<ImageView
android:id="@+id/iv_toggle"
android:layout_width="52dp"
android:layout_height="52dp"
android:padding="16dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@drawable/hide" />
</RelativeLayout>
<!-- 重复密码输入框 -->
<RelativeLayout
android:layout_width="315dp"
android:background="@drawable/input_box_bg"
android:layout_marginTop="14dp"
android:layout_height="52dp">
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="14sp"
android:padding="15dp"
android:textColor="#000000"
android:background="@null"
android:hint="Enter Repeat password"
android:textColorHint="#CBCBCB"
android:inputType="textPassword" />
<ImageView
android:id="@+id/iv_toggle"
android:layout_width="52dp"
android:layout_height="52dp"
android:padding="16dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@drawable/hide" />
</RelativeLayout>
<!-- 登录按钮 -->
<TextView
android:id="@+id/btn_login"
android:layout_width="315dp"
android:layout_height="52dp"
android:layout_marginTop="20dp"
android:background="@drawable/login_btn_bg"
android:gravity="center"
android:textStyle="bold"
android:textColor="#FFFFFF"
android:textSize="18sp"
android:text="Login" />
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/agreement_container"
android:layout_width="350dp"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:layout_gravity="center_horizontal"
android:paddingHorizontal="20dp"
app:flexDirection="row"
app:flexWrap="wrap"
app:justifyContent="center"
app:alignItems="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="By Continuing, You Agree To Our "
android:textSize="10sp"
android:textColor="#554F70"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Terms Of Service "
android:textStyle="bold"
android:textSize="10sp"
android:textColor="#554F70"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="And Confirm"
android:textSize="10sp"
android:textColor="#554F70"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="That You Have Read Our "
android:textSize="10sp"
android:textColor="#554F70"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Privacy Policy"
android:textStyle="bold"
android:textSize="10sp"
android:textColor="#554F70"/>
</com.google.android.flexbox.FlexboxLayout>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -0,0 +1,37 @@
<!-- 对方消息 -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:gravity="end"
android:orientation="vertical">
<!-- 头像 -->
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/avatar"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="5dp"
android:clickable="true"
android:focusable="true"
android:src="@drawable/logo" />
<!-- 消息内容 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="40dp"
android:layout_marginTop="-20dp"
android:background="@drawable/other_party_message"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:maxWidth="203dp"
android:textSize="10sp"
android:lineHeight="20dp"/>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,38 @@
<!-- 我方消息 -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:gravity="center_vertical"
android:orientation="vertical">
<!-- 头像 -->
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/avatar"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="5dp"
android:clickable="true"
android:focusable="true"
android:src="@drawable/logo" />
<!-- 消息内容 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginTop="-20dp"
android:background="@drawable/our_news"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Welcome to use the [key of love] keyboard"
android:textColor="#929292"
android:maxWidth="203dp"
android:textSize="10sp"
android:lineHeight="20dp" />
</LinearLayout>
</LinearLayout>

View File

@@ -4,11 +4,37 @@
android:layout_height="wrap_content"
android:id="@+id/background"
android:orientation="vertical">
<!-- 控制 -->
<LinearLayout
android:id="@+id/control_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
</LinearLayout>
<LinearLayout
android:id="@+id/collapse_button"
android:layout_width="50dp"
android:layout_height="50dp"
android:gravity="center">
<TextView
android:id="@+id/Key_collapse"
android:layout_width="19dp"
android:layout_height="10dp"
/>
</LinearLayout>
</LinearLayout>
<!-- 补全建议区域(可横向滑动) -->
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_height="50dp"
android:scrollbars="none"
android:overScrollMode="never"
android:id="@+id/completion_scroll">

View File

@@ -5,255 +5,30 @@
android:background="@drawable/keyboard_background"
android:id="@+id/background"
android:orientation="vertical">
<!-- 补全建议区域(可横向滑动) -->
<HorizontalScrollView
<!-- 控制 -->
<LinearLayout
android:id="@+id/control_layout"
android:layout_width="match_parent"
android:layout_height="40dp"
android:scrollbars="none"
android:overScrollMode="never"
android:id="@+id/completion_scroll">
android:layout_height="50dp"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/completion_suggestions"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingStart="4dp"
android:paddingEnd="4dp">
<TextView
android:id="@+id/suggestion_0"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_4"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_5"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_6"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_7"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_8"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_9"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_10"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_11"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_12"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_13"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_14"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_15"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_16"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_17"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_18"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_19"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_20"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
android:layout_weight="1">
</LinearLayout>
</HorizontalScrollView>
<LinearLayout
android:id="@+id/collapse_button"
android:layout_width="50dp"
android:layout_height="50dp"
android:gravity="center">
<TextView
android:id="@+id/Key_collapse"
android:layout_width="19dp"
android:layout_height="10dp"
/>
</LinearLayout>
</LinearLayout>
<!-- 第一行数字键 -->
<LinearLayout
android:layout_width="match_parent"

View File

@@ -5,255 +5,31 @@
android:id="@+id/background"
android:layout_height="wrap_content"
android:orientation="vertical">
<HorizontalScrollView
<!-- 控制 -->
<LinearLayout
android:id="@+id/control_layout"
android:layout_width="match_parent"
android:layout_height="40dp"
android:scrollbars="none"
android:overScrollMode="never"
android:id="@+id/completion_scroll">
android:layout_height="50dp"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/completion_suggestions"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingStart="4dp"
android:paddingEnd="4dp">
<TextView
android:id="@+id/suggestion_0"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_4"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_5"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_6"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_7"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_8"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_9"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_10"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_11"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_12"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_13"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_14"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_15"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_16"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_17"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_18"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_19"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
<TextView
android:id="@+id/suggestion_20"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="12sp"
android:paddingHorizontal="12dp"
android:gravity="center"
android:clickable="true"
android:background="@drawable/btn_keyboard"
android:textColor="#3C3C3C"/>
android:layout_weight="1">
</LinearLayout>
</HorizontalScrollView>
<LinearLayout
android:id="@+id/collapse_button"
android:layout_width="50dp"
android:layout_height="50dp"
android:gravity="center">
<TextView
android:id="@+id/Key_collapse"
android:layout_width="19dp"
android:layout_height="10dp"
/>
</LinearLayout>
</LinearLayout>
<!-- 第一行: [ ] { } # % ^ * + = -->
<LinearLayout

View File

@@ -179,6 +179,81 @@
android:label="Feedback"
tools:layout="@layout/feedback_fragment" />
<!-- 登录页面 -->
<fragment
android:id="@+id/loginFragment"
android:name="com.example.myapplication.ui.login.LoginFragment"
android:label="Login"
tools:layout="@layout/fragment_login" />
<action
android:id="@+id/action_mineFragment_to_loginFragment"
app:destination="@id/loginFragment"
app:enterAnim="@anim/fade_in"
app:exitAnim="@anim/fade_out"
app:popEnterAnim="@anim/fade_in_fast"
app:popExitAnim="@anim/fade_out_fast"/>
<!-- 注册页面 -->
<fragment
android:id="@+id/registerFragment"
android:name="com.example.myapplication.ui.login.RegisterFragment"
android:label="Register"
tools:layout="@layout/fragment_register" />
<action
android:id="@+id/action_mineFragment_to_registerFragment"
app:destination="@id/registerFragment"
app:enterAnim="@anim/fade_in"
app:exitAnim="@anim/fade_out"
app:popEnterAnim="@anim/fade_in_fast"
app:popExitAnim="@anim/fade_out_fast"/>
<!-- 忘记密码邮箱输入页面 -->
<fragment
android:id="@+id/forgetPasswordEmailFragment"
android:name="com.example.myapplication.ui.login.ForgetPasswordEmailFragment"
android:label="Forget Password Email"
tools:layout="@layout/fragment_forget_password_email" />
<action
android:id="@+id/action_loginFragment_to_forgetPasswordEmailFragment"
app:destination="@id/forgetPasswordEmailFragment"
app:enterAnim="@anim/fade_in"
app:exitAnim="@anim/fade_out"
app:popEnterAnim="@anim/fade_in_fast"
app:popExitAnim="@anim/fade_out_fast"/>
<!-- 忘记密码验证码输入页面 -->
<fragment
android:id="@+id/forgetPasswordVerifyFragment"
android:name="com.example.myapplication.ui.login.ForgetPasswordVerifyFragment"
android:label="Forget Password Verify"
tools:layout="@layout/fragment_forget_password_verify" />
<action
android:id="@+id/action_forgetPasswordEmailFragment_to_forgetPasswordVerifyFragment"
app:destination="@id/forgetPasswordVerifyFragment"
app:enterAnim="@anim/fade_in"
app:exitAnim="@anim/fade_out"
app:popEnterAnim="@anim/fade_in_fast"
app:popExitAnim="@anim/fade_out_fast"/>
<!-- 忘记密码重置密码页面 -->
<fragment
android:id="@+id/forgetPasswordResetFragment"
android:name="com.example.myapplication.ui.login.ForgetPasswordResetFragment"
android:label="Forget Password Reset"
tools:layout="@layout/fragment_forget_password_reset" />
<action
android:id="@+id/action_forgetPasswordVerifyFragment_to_forgetPasswordResetFragment"
app:destination="@id/forgetPasswordResetFragment"
app:enterAnim="@anim/fade_in"
app:exitAnim="@anim/fade_out"
app:popEnterAnim="@anim/fade_in_fast"
app:popExitAnim="@anim/fade_out_fast"/>
<!-- 通知 -->
<fragment
android:id="@+id/notificationFragment"

View File

@@ -11,5 +11,16 @@
<item name="cornerFamily">rounded</item>
<item name="cornerSize">16dp</item>
</style>
<style name="VerifyCodeBox">
<item name="android:layout_width">45dp</item>
<item name="android:layout_height">50dp</item>
<item name="android:layout_margin">3dp</item>
<item name="android:gravity">center</item>
<item name="android:textSize">20sp</item>
<item name="android:maxLength">1</item>
<item name="android:background">@drawable/code_box_bg</item>
<item name="android:textColor">#000000</item>
</style>
</resources>

View File

@@ -1,17 +0,0 @@
package com.example.myapplication
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}