稍微完善输入法以及输入法体验页
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
BIN
app/src/main/assets/keyboard_themes/default/Key_collapse.png
Normal file
BIN
app/src/main/assets/keyboard_themes/default/Key_collapse.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 945 B |
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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~255,100~150 最舒服
|
||||
duration: Long = 30L, // 时间:10~40 推荐
|
||||
amplitude: Int = 255 // 1~255,100~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 {
|
||||
|
||||
@@ -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~255,100~150 最舒服
|
||||
duration: Long = 30L, // 时间:10~40 推荐
|
||||
amplitude: Int = 255 // 1~255,100~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()
|
||||
}
|
||||
}
|
||||
|
||||
// ================= 按键触摸 & 预览 =================
|
||||
|
||||
@@ -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~255,100~150 最舒服
|
||||
duration: Long = 30L, // 时间:10~40 推荐
|
||||
amplitude: Int = 255 // 1~255,100~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()
|
||||
}
|
||||
}
|
||||
|
||||
// ================== 触摸 + 预览 ==================
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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() }
|
||||
}
|
||||
}
|
||||
@@ -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: 登录处理
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
17
app/src/main/res/anim/item_slide_in_up.xml
Normal file
17
app/src/main/res/anim/item_slide_in_up.xml
Normal 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>
|
||||
5
app/src/main/res/drawable/acttivity_guide_btn_bg.xml
Normal file
5
app/src/main/res/drawable/acttivity_guide_btn_bg.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="#F3F3F3"/>
|
||||
<corners android:radius="4dp"/>
|
||||
</shape>
|
||||
4
app/src/main/res/drawable/code_box_bg.xml
Normal file
4
app/src/main/res/drawable/code_box_bg.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#F4F8FB"/>
|
||||
<corners android:radius="6dp"/>
|
||||
</shape>
|
||||
BIN
app/src/main/res/drawable/display.png
Normal file
BIN
app/src/main/res/drawable/display.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/drawable/hide.png
Normal file
BIN
app/src/main/res/drawable/hide.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1002 B |
5
app/src/main/res/drawable/input_box_bg.xml
Normal file
5
app/src/main/res/drawable/input_box_bg.xml
Normal 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>
|
||||
BIN
app/src/main/res/drawable/login_bg.png
Normal file
BIN
app/src/main/res/drawable/login_bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
5
app/src/main/res/drawable/login_btn_bg.xml
Normal file
5
app/src/main/res/drawable/login_btn_bg.xml
Normal 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>
|
||||
14
app/src/main/res/drawable/login_content_bg.xml
Normal file
14
app/src/main/res/drawable/login_content_bg.xml
Normal 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>
|
||||
BIN
app/src/main/res/drawable/login_icon.png
Normal file
BIN
app/src/main/res/drawable/login_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 763 KiB |
9
app/src/main/res/drawable/other_party_message.xml
Normal file
9
app/src/main/res/drawable/other_party_message.xml
Normal 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>
|
||||
9
app/src/main/res/drawable/our_news.xml
Normal file
9
app/src/main/res/drawable/our_news.xml
Normal 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>
|
||||
@@ -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 "Copy any conversation", "Paste" 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>
|
||||
81
app/src/main/res/layout/fragment_forget_password_email.xml
Normal file
81
app/src/main/res/layout/fragment_forget_password_email.xml
Normal 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>
|
||||
121
app/src/main/res/layout/fragment_forget_password_reset.xml
Normal file
121
app/src/main/res/layout/fragment_forget_password_reset.xml
Normal 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>
|
||||
111
app/src/main/res/layout/fragment_forget_password_verify.xml
Normal file
111
app/src/main/res/layout/fragment_forget_password_verify.xml
Normal 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>
|
||||
244
app/src/main/res/layout/fragment_login.xml
Normal file
244
app/src/main/res/layout/fragment_login.xml
Normal 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>
|
||||
@@ -345,6 +345,7 @@
|
||||
|
||||
<!-- 隐私政策 -->
|
||||
<LinearLayout
|
||||
android:id="@+id/click_Privacy"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:gravity="center_vertical"
|
||||
|
||||
229
app/src/main/res/layout/fragment_register.xml
Normal file
229
app/src/main/res/layout/fragment_register.xml
Normal 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>
|
||||
37
app/src/main/res/layout/item_other_party_message.xml
Normal file
37
app/src/main/res/layout/item_other_party_message.xml
Normal 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>
|
||||
38
app/src/main/res/layout/item_our_news_message.xml
Normal file
38
app/src/main/res/layout/item_our_news_message.xml
Normal 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>
|
||||
@@ -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">
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user