diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4895369..9ff3b48 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -25,6 +25,19 @@ + + + + + + + + diff --git a/app/src/main/java/com/timber/soft/newkeyboard/AppInputMethodService.kt b/app/src/main/java/com/timber/soft/newkeyboard/AppInputMethodService.kt index c605886..369cfc0 100644 --- a/app/src/main/java/com/timber/soft/newkeyboard/AppInputMethodService.kt +++ b/app/src/main/java/com/timber/soft/newkeyboard/AppInputMethodService.kt @@ -1,37 +1,100 @@ package com.timber.soft.newkeyboard import android.inputmethodservice.InputMethodService +import android.inputmethodservice.Keyboard import android.inputmethodservice.KeyboardView.OnKeyboardActionListener +import android.os.Build +import android.os.SystemClock +import android.view.KeyboardShortcutGroup import android.view.View +import android.view.inputmethod.EditorInfo +import androidx.annotation.RequiresApi +import com.timber.soft.newkeyboard.databinding.ViewInputBinding +import com.timber.soft.newkeyboard.tools.AppVal class AppInputMethodService : InputMethodService(), OnKeyboardActionListener { + private lateinit var binding: ViewInputBinding + private val views = + intArrayOf(R.xml.keyboard_letter, R.xml.keyboard_number, R.xml.keyboard_symbol) + private var mouble = false + private var laTime = -3L + + private fun keyCase(toBig: Boolean, keyboard: Keyboard) { + for (key in keyboard.keys) { + if (!key.label.isNullOrEmpty()) { + if (key.label.length == 1) { + var strin: Char = if (toBig) { + key.label.toString()[0].uppercaseChar() + } else { + key.label.toString()[0].lowercaseChar() + } + key.run { + label = strin.toString() + codes[0] = strin.code + } + } + } + } + } + + private fun changeXml(mode: Int) { + binding.myCustomInput.run { + when (mode) { + 0 -> { + xmlMode = AppVal.xml0 + keyboard = Keyboard(context, views[0]) + } + + 2 -> { + xmlMode = AppVal.xml2 + keyboard = Keyboard(context, views[2]) + + } + + 1 -> { + xmlMode = AppVal.xml1 + keyboard = Keyboard(context, views[1]) + } + } + } + } /** * 构建键盘视图 */ override fun onCreateInputView(): View { - return super.onCreateInputView() - TODO("Not yet implemented") + binding = ViewInputBinding.inflate(layoutInflater, null, false) + binding.myCustomInput.setOnKeyboardActionListener(this) + binding.myCustomInput.run { + keyboard = Keyboard(this@AppInputMethodService, views[0]) + isEnabled = true + } + return binding.root } - /** * 向用户展示键盘时候调用 */ + @RequiresApi(Build.VERSION_CODES.M) override fun onWindowShown() { super.onWindowShown() - TODO("Not yet implemented") + binding.myCustomInput.upUi(this@AppInputMethodService) } - /** * Called when the user presses a key. * * 监听特定的按钮 */ override fun onPress(primaryCode: Int) { - TODO("Not yet implemented") + mouble = false + if (primaryCode == Keyboard.KEYCODE_SHIFT) { + if (300 > SystemClock.elapsedRealtime() - laTime) { + mouble = true + } + laTime = SystemClock.elapsedRealtime() + } } /** @@ -40,7 +103,80 @@ class AppInputMethodService : InputMethodService(), OnKeyboardActionListener { * 监听用户点击的键盘按键 */ override fun onKey(primaryCode: Int, keyCodes: IntArray?) { - TODO("Not yet implemented") + + when (primaryCode) { + Keyboard.KEYCODE_SHIFT -> { + binding.myCustomInput.run { + val myKeyboard = keyboard + when (shiftStatus) { + AppVal.Shift_S -> { + shiftStatus = if (mouble) { + AppVal.Shift_B_lo + } else { + AppVal.Shift_B + } + keyCase(true, myKeyboard) + keyboard = myKeyboard + } + + AppVal.Shift_B_lo -> { + shiftStatus = AppVal.Shift_S + keyCase(false, myKeyboard) + keyboard = myKeyboard + } + + AppVal.Shift_B -> { + shiftStatus = if (mouble) { + AppVal.Shift_B_lo + } else { + keyCase(false, myKeyboard) + AppVal.Shift_S + } + keyboard = myKeyboard + } + } + } + + } + + Keyboard.KEYCODE_DONE -> { + currentInputConnection.performEditorAction(EditorInfo.IME_ACTION_DONE) + } + + Keyboard.KEYCODE_MODE_CHANGE -> { + binding.myCustomInput.run { + if (xmlMode == AppVal.xml0) { + changeXml(1) + } else { + changeXml(0) + } + } + } + + AppVal.SHIFT_NUMBER -> { + changeXml(2) + } + + Keyboard.KEYCODE_DELETE -> { + currentInputConnection.deleteSurroundingText(1, 0) + } + + AppVal.SHIFT_SYMBOL -> { + changeXml(1) + } + + else -> { + currentInputConnection.commitText(primaryCode.toChar().toString(), 1) + binding.myCustomInput.keyboard = binding.myCustomInput.apply { + if (shiftStatus == AppVal.Shift_B) { + shiftStatus = AppVal.Shift_S + keyCase(false, binding.myCustomInput.keyboard) + } + }.keyboard + } + + } + } diff --git a/app/src/main/java/com/timber/soft/newkeyboard/activity/ApplyActivity.kt b/app/src/main/java/com/timber/soft/newkeyboard/activity/ApplyActivity.kt index 4689c2e..830f511 100644 --- a/app/src/main/java/com/timber/soft/newkeyboard/activity/ApplyActivity.kt +++ b/app/src/main/java/com/timber/soft/newkeyboard/activity/ApplyActivity.kt @@ -67,7 +67,7 @@ class ApplyActivity : AppCompatActivity() { private fun isChoose(): Boolean { Settings.Secure.getString(contentResolver, Settings.Secure.DEFAULT_INPUT_METHOD).let { id -> return id.startsWith(packageName) - } ?: return false + } } private fun isEnable(): Boolean { diff --git a/app/src/main/java/com/timber/soft/newkeyboard/activity/DetailsActivity.kt b/app/src/main/java/com/timber/soft/newkeyboard/activity/DetailsActivity.kt index 5b48378..fe32099 100644 --- a/app/src/main/java/com/timber/soft/newkeyboard/activity/DetailsActivity.kt +++ b/app/src/main/java/com/timber/soft/newkeyboard/activity/DetailsActivity.kt @@ -22,6 +22,7 @@ import com.bumptech.glide.request.RequestListener import com.bumptech.glide.request.target.Target import com.timber.soft.newkeyboard.R import com.timber.soft.newkeyboard.databinding.ActivityDetailsBinding +import com.timber.soft.newkeyboard.listener.ApplyListener import com.timber.soft.newkeyboard.model.DataModel import com.timber.soft.newkeyboard.tools.AppVal import com.timber.soft.newkeyboard.tools.StatusBarTools @@ -36,13 +37,14 @@ import java.io.FileOutputStream import java.io.InputStream import java.io.RandomAccessFile -class DetailsActivity : AppCompatActivity() { +class DetailsActivity : AppCompatActivity(), ApplyListener { private lateinit var binding: ActivityDetailsBinding private lateinit var inputManager: InputMethodManager private lateinit var previewUrl: String private lateinit var zipPath: String private lateinit var dataModel: DataModel + private lateinit var sp: SharedPreferences override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -117,68 +119,59 @@ class DetailsActivity : AppCompatActivity() { e.printStackTrace() } + // 初始化键值对 + sp = getSharedPreferences( + AppVal.SHARE_NAME, Context.MODE_PRIVATE + ) } private fun applyTheme() { // 检查是否启动键盘并设置 if (!isEnable() || !isChoose()) { + Toast.makeText(this, getString(R.string.text_promote), Toast.LENGTH_SHORT).show() val intent = Intent(this, ApplyActivity::class.java) startActivity(intent) return } + binding.themeProgressbar.visibility = View.VISIBLE val file = File(zipPath) // 判断缓存中是否存在文件 if (file.exists()) { val allThemePath: String = getAllThemePath(dataModel.title) val edit = sp.edit() + // 存放键值对 edit.run { putString(AppVal.KEY_ALL_PATH, allThemePath) apply() } } else { - getZipData(dataModel.title, dataModel.zipUrl, this,this::onResult) + getZipData( + dataModel.title, dataModel.zipUrl, this@DetailsActivity, this@DetailsActivity + ) } } - private fun onResult(isSuccess: Boolean, path: String) { - binding.themeProgressbar.visibility = View.GONE - if (isSuccess) { - val lastIndexOf: Int = path.lastIndexOf(AppVal.res_path) - val substring = path.subSequence(0, lastIndexOf + AppVal.res_path.length).toString() - - val edit = sp.edit() - - edit.run { - putString(AppVal.KEY_ALL_PATH, substring) - apply() - } - - edit.run { - putString(dataModel.title, substring) - apply() - } - - Toast.makeText(this, getString(R.string.succ_apply), Toast.LENGTH_LONG).show() - finish() - } else { - Toast.makeText(this, getString(R.string.fail_apply), Toast.LENGTH_LONG).show() - } - } - - interface ApplyListener { - fun applyListener(isSuccess: Boolean, str: String) - } - + /** + * 从指定的URL下载zip文件,并在下载完成后处理该文件。 + * + * @param title 下载文件的标题 + * @param url 下载文件的URL + * @param con 上下文Context + * @param listener 处理文件完成后的回调接口 + */ private fun getZipData(title: String, url: String, con: Context, listener: ApplyListener) { Glide.with(con).asFile().load(url).addListener(object : RequestListener { + //失败回调 override fun onLoadFailed( e: GlideException?, model: Any?, target: Target, isFirstResource: Boolean ): Boolean { + // 回调失败 listener.applyListener(false, "") return false } + //成功回调 override fun onResourceReady( resource: File, model: Any, @@ -186,7 +179,6 @@ class DetailsActivity : AppCompatActivity() { dataSource: DataSource, isFirstResource: Boolean ): Boolean { - val fileInputStream = FileInputStream(resource) dealFile(title, url, fileInputStream, listener) return false @@ -201,9 +193,12 @@ class DetailsActivity : AppCompatActivity() { val zipPath = "${cacheDir}/${title}_ZIP" val unPath = "${cacheDir}/${title}" + // 将下载的zip文件保存到zipPath路径 val zipBoolean = writeNewFile(input, zipPath) + // 随机读写 val randomAccessFileInStream = RandomAccessFileInStream(RandomAccessFile(File(zipPath), "r")) + val openInArchive = SevenZip.openInArchive( ArchiveFormat.SEVEN_ZIP, randomAccessFileInStream ) @@ -213,6 +208,12 @@ class DetailsActivity : AppCompatActivity() { if (zipBoolean) { try { var filePath: String = "" + + /** + * 存档文件中的每个文件项。对于每个文件项,判断是否为文件(非文件夹), + * 如果是文件,则将其解压缩到目标路径unPath下的相应位置; + * 如果是文件夹,则创建对应的文件夹。 + */ openInArchive.simpleInterface.archiveItems.forEach { item -> if (!item.isFolder) { val file = File(unPath, item.path) @@ -223,10 +224,10 @@ class DetailsActivity : AppCompatActivity() { File(unPath, item.path).mkdirs() } } + //调用接口返回成功 listener.applyListener(true, filePath) } catch (ex: Exception) { listener.applyListener(false, "") - } finally { openInArchive.close() randomAccessFileInStream.close() @@ -266,9 +267,6 @@ class DetailsActivity : AppCompatActivity() { } - private val sp: SharedPreferences = getSharedPreferences( - AppVal.SHARE_NAME, Context.MODE_PRIVATE - ) private fun getAllThemePath(zip: String): String { val result = sp.getString(zip, "") @@ -281,7 +279,7 @@ class DetailsActivity : AppCompatActivity() { private fun isChoose(): Boolean { Settings.Secure.getString(contentResolver, Settings.Secure.DEFAULT_INPUT_METHOD).let { id -> return id.startsWith(packageName) - } ?: return false + } } /** @@ -296,4 +294,28 @@ class DetailsActivity : AppCompatActivity() { return false } + /** + * 点击设置后的回调接口 + */ + override fun applyListener(isSuccess: Boolean, str: String) { + binding.themeProgressbar.visibility = View.GONE + if (isSuccess) { + val lastIndexOf: Int = str.lastIndexOf(AppVal.res_path) + val substring = str.subSequence(0, lastIndexOf + AppVal.res_path.length).toString() + val edit = sp.edit() + edit.run { + putString(AppVal.KEY_ALL_PATH, substring) + apply() + } + edit.run { + putString(dataModel.title, substring) + apply() + } + Toast.makeText(this, getString(R.string.succ_apply), Toast.LENGTH_LONG).show() + finish() + } else { + Toast.makeText(this, getString(R.string.fail_apply), Toast.LENGTH_LONG).show() + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/timber/soft/newkeyboard/listener/ApplyListener.kt b/app/src/main/java/com/timber/soft/newkeyboard/listener/ApplyListener.kt new file mode 100644 index 0000000..3a218b6 --- /dev/null +++ b/app/src/main/java/com/timber/soft/newkeyboard/listener/ApplyListener.kt @@ -0,0 +1,5 @@ +package com.timber.soft.newkeyboard.listener + +interface ApplyListener { + fun applyListener(isSuccess: Boolean, str: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/timber/soft/newkeyboard/tools/ImgTools.kt b/app/src/main/java/com/timber/soft/newkeyboard/tools/ImgTools.kt deleted file mode 100644 index fe2215b..0000000 --- a/app/src/main/java/com/timber/soft/newkeyboard/tools/ImgTools.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.timber.soft.newkeyboard.tools - -object ImgTools { - -} \ No newline at end of file diff --git a/app/src/main/java/com/timber/soft/newkeyboard/view/MyKeyboardView.kt b/app/src/main/java/com/timber/soft/newkeyboard/view/MyKeyboardView.kt new file mode 100644 index 0000000..d70439c --- /dev/null +++ b/app/src/main/java/com/timber/soft/newkeyboard/view/MyKeyboardView.kt @@ -0,0 +1,317 @@ +package com.timber.soft.newkeyboard.view + +import android.annotation.SuppressLint +import android.content.Context +import android.content.SharedPreferences +import android.graphics.BitmapFactory +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.graphics.Rect +import android.graphics.drawable.BitmapDrawable +import android.graphics.drawable.Drawable +import android.graphics.drawable.StateListDrawable +import android.inputmethodservice.Keyboard +import android.inputmethodservice.KeyboardView +import android.os.Build +import android.util.AttributeSet +import android.util.Xml +import androidx.annotation.RequiresApi +import androidx.core.content.ContextCompat +import com.timber.soft.newkeyboard.R +import com.timber.soft.newkeyboard.tools.AppVal +import org.xmlpull.v1.XmlPullParser +import java.io.File +import java.io.StringReader + +@Suppress("DEPRECATION") +class MyKeyboardView @JvmOverloads constructor( + var myContext: Context, + attributeSet: AttributeSet? = null, + style: Int = 0 +) : KeyboardView(myContext, attributeSet, style) { + + inner class MyConfig { + lateinit var functionBackgroundDraw: Drawable + lateinit var spBackgroundDraw: Drawable + lateinit var normalBackgroundDraw: Drawable + var icShittLock: Drawable? = + ContextCompat.getDrawable(context, R.drawable.svg_shift_lit) + var icDel: Drawable? = + ContextCompat.getDrawable(context, R.drawable.svg_dele) + var allBg: Drawable? = + ContextCompat.getDrawable(context, R.mipmap.main_bg) + var icBshift: Drawable? = + ContextCompat.getDrawable(context, R.drawable.svg_shift_lit) + var icSshift: Drawable? = + ContextCompat.getDrawable(context, R.drawable.svg_shift_lit) + + @RequiresApi(Build.VERSION_CODES.M) + var keycolor: Int = context.resources.getColor(R.color.white, null) + + private val sp: SharedPreferences = context.getSharedPreferences( + AppVal.SHARE_NAME, + Context.MODE_PRIVATE + ) + + private fun getbgic(con: Context, filePath: String): Drawable? { + if (!File(filePath).exists()) { + return null + } + return BitmapDrawable(con.resources, BitmapFactory.decodeFile(filePath)) + } + + private fun getStatus(draw: Drawable, drawPress: Drawable): StateListDrawable { + return StateListDrawable().apply { + addState(intArrayOf(android.R.attr.state_pressed), drawPress) + addState(intArrayOf(), draw) + } + } + + @RequiresApi(Build.VERSION_CODES.M) + private fun gettextcolor(colorXmlPath: String) { + val file = File(colorXmlPath) + if (!file.exists()) return + val xmlP = Xml.newPullParser() + + xmlP.setInput(StringReader(file.readText())) + xmlP.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false) + + var eventT = xmlP.eventType + while (eventT != XmlPullParser.END_DOCUMENT) { + if (eventT == XmlPullParser.START_TAG && (xmlP.name == "color" || xmlP.name == "item")) { + val value = xmlP.getAttributeValue(null, "name") + if (value != null && value == AppVal.title_color) { + keycolor = Color.parseColor(xmlP.nextText()) + } + } + eventT = xmlP.next() + } + + + } + + + init { + val default = + ContextCompat.getDrawable(context, R.drawable.png_keybg) + val press = ContextCompat.getDrawable( + context, + R.drawable.png_keybg_press + ) + if (press != null) { + if (default != null) { + val listDrawable = StateListDrawable().apply { + addState(intArrayOf(android.R.attr.state_pressed), press) + addState(intArrayOf(), default) + } + functionBackgroundDraw = listDrawable + normalBackgroundDraw = listDrawable + spBackgroundDraw = listDrawable + } + } + } + + @RequiresApi(Build.VERSION_CODES.M) + fun updateConfig(con: Context) { + sp.getString(AppVal.KEY_ALL_PATH, "")?.let { + getbgic( + con, + it.plus(AppVal.parent_path).plus(AppVal.title_nor_Bg) + )?.let { drawBG -> + getbgic( + con, + it.plus(AppVal.parent_path).plus(AppVal.title_nor_Bg_press) + )?.let { drawPressBG -> + normalBackgroundDraw = getStatus(drawBG, drawPressBG) + } + + } + gettextcolor(it.plus(AppVal.color_path)) + getbgic(con, it.plus(AppVal.parent_path).plus(AppVal.title_sp_Bg))?.let { drawBG -> + getbgic( + con, + it.plus(AppVal.parent_path).plus(AppVal.title_sp_Bg_press) + )?.let { drawPressBG -> + spBackgroundDraw = getStatus(drawBG, drawPressBG) + } + + } + getbgic(con, it.plus(AppVal.xx_path).plus(AppVal.title_bg))?.run { + allBg = this + } + + getbgic( + con, + it.plus(AppVal.parent_path).plus(AppVal.title_fun_Bg) + )?.let { drawBG -> + getbgic( + con, + it.plus(AppVal.parent_path).plus(AppVal.title_func_bg_press) + )?.let { drawPressBG -> + functionBackgroundDraw = getStatus(drawBG, drawPressBG) + } + + } + + + getbgic(con, it.plus(AppVal.parent_path).plus(AppVal.title_shitf_ic))?.let { + icSshift = it + icBshift = it + } + getbgic( + con, + it.plus(AppVal.parent_path).plus(AppVal.title_del_ic) + )?.let { drawBG -> + icDel = getStatus(drawBG, drawBG) + + + } + getbgic(con, it.plus(AppVal.parent_path).plus(AppVal.title_shitf_ic_lock))?.let { + icShittLock = it + } + + } + } + } + + var config = MyConfig() + var shiftStatus = AppVal.Shift_S + var xmlMode = AppVal.xml0 + + @RequiresApi(Build.VERSION_CODES.M) + private var myPaint: Paint = Paint().apply { + isAntiAlias = true + textAlign = Paint.Align.CENTER + textSize = myContext.resources.displayMetrics.scaledDensity * 16f + color = config.keycolor + } + + @RequiresApi(Build.VERSION_CODES.M) + @SuppressLint("SuspiciousIndentation") + private fun andDraw( + myKey: Keyboard.Key, + keyBG: Drawable, + icon: Drawable?, + canvas: Canvas, + ) { + myKey.run { + keyBG.run { + bounds = Rect( + x.plus(paddingLeft), + y.plus(paddingTop), + width.plus(x.plus(paddingLeft)), + height.plus(y.plus(paddingTop)) + ) + state = currentDrawableState + draw(canvas) + } + } + myKey.run { + icon?.apply { + myKey.icon = this + + var icon_w = myKey.icon.intrinsicWidth.toFloat() + var icon_wr = icon_w / myKey.width.toFloat() + var icon_h = myKey.icon.intrinsicHeight.toFloat() + var icon_hr = icon_h / myKey.height.toFloat() + + + var tep1 = 0f + var tep2 = 0f + if (icon_wr > icon_hr) { + tep2 = icon_wr + tep1 = icon_wr.coerceAtLeast(0.5f) + + } else { + tep2 = icon_hr + tep1 = icon_hr.coerceAtLeast(0.5f) + + } + icon_h = (icon_h / tep2) * tep1 + icon_w = (icon_w / tep2) * tep1 + myKey.icon.let { + it.bounds = Rect().apply { + + top = + (myKey.y + paddingTop + (myKey.height - icon_h) / 2f).toInt() + left = + (myKey.x + paddingLeft + (myKey.width - icon_w) / 2f).toInt() + bottom = (top + icon_h).toInt() + right = (left + icon_w).toInt() + + } + it.draw(canvas) + } + } + + myPaint.color = config.keycolor + if (!label.isNullOrEmpty()) { + val y1 = y.plus(paddingRight).plus((height.div(2f))) + .plus((myPaint.textSize.minus(myPaint.descent())).div(2f)) + val x1 = x.plus(paddingLeft).plus((width.div(2f))) + canvas.drawText(label.toString(), x1, y1, myPaint) + } + } + } + + private fun getCurIc(): Drawable? { + return when (shiftStatus) { + AppVal.Shift_B_lo -> config.icShittLock + AppVal.Shift_B -> config.icBshift + AppVal.Shift_S -> config.icSshift + else -> config.icSshift + } + } + + @RequiresApi(Build.VERSION_CODES.M) + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + keyboard.keys.forEach { + when (it.codes[0]) { + Keyboard.KEYCODE_SHIFT -> { + andDraw( + it, + config.functionBackgroundDraw, + getCurIc(), + canvas + ) + } + + AppVal.SHIFT_NUMBER, AppVal.SHIFT_SYMBOL -> { + andDraw(it, config.functionBackgroundDraw, null, canvas) + } + + Keyboard.KEYCODE_DELETE -> { + andDraw( + it, + config.functionBackgroundDraw, + config.icDel, + canvas + ) + } + + Keyboard.KEYCODE_MODE_CHANGE, Keyboard.KEYCODE_DONE -> { + andDraw( + it, + config.functionBackgroundDraw, + null, + canvas + ) + } + + else -> { + andDraw(it, config.normalBackgroundDraw, null, canvas) + } + } + } + } + + @RequiresApi(Build.VERSION_CODES.M) + fun upUi(con: Context) { + config.updateConfig(con) + background = config.allBg + invalidate() + } + +} \ No newline at end of file diff --git a/app/src/main/res/drawable/png_keybg.9.png b/app/src/main/res/drawable/png_keybg.9.png new file mode 100644 index 0000000..fcf5166 Binary files /dev/null and b/app/src/main/res/drawable/png_keybg.9.png differ diff --git a/app/src/main/res/drawable/png_keybg_press.9.png b/app/src/main/res/drawable/png_keybg_press.9.png new file mode 100644 index 0000000..b3f2727 Binary files /dev/null and b/app/src/main/res/drawable/png_keybg_press.9.png differ diff --git a/app/src/main/res/drawable/shape_white_keyboard.xml b/app/src/main/res/drawable/shape_white_keyboard.xml new file mode 100644 index 0000000..1e7a91a --- /dev/null +++ b/app/src/main/res/drawable/shape_white_keyboard.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/svg_dele.xml b/app/src/main/res/drawable/svg_dele.xml new file mode 100644 index 0000000..1c653c8 --- /dev/null +++ b/app/src/main/res/drawable/svg_dele.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/svg_shift_lit.xml b/app/src/main/res/drawable/svg_shift_lit.xml new file mode 100644 index 0000000..858c5ef --- /dev/null +++ b/app/src/main/res/drawable/svg_shift_lit.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/view_input.xml b/app/src/main/res/layout/view_input.xml new file mode 100644 index 0000000..cbc1091 --- /dev/null +++ b/app/src/main/res/layout/view_input.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-xxxhdpi/main_bg.png b/app/src/main/res/mipmap-xxxhdpi/main_bg.png new file mode 100644 index 0000000..22eb3bf Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/main_bg.png differ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 415f48c..510b12c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -11,4 +11,5 @@ Step 2: Enable Application successful Application failed, please try again + For normal use, please enter the setting to complete the setting steps. \ No newline at end of file diff --git a/app/src/main/res/xml/key_view.xml b/app/src/main/res/xml/key_view.xml new file mode 100644 index 0000000..16a78b2 --- /dev/null +++ b/app/src/main/res/xml/key_view.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/keyboard_letter.xml b/app/src/main/res/xml/keyboard_letter.xml new file mode 100644 index 0000000..c810e6c --- /dev/null +++ b/app/src/main/res/xml/keyboard_letter.xml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/keyboard_number.xml b/app/src/main/res/xml/keyboard_number.xml new file mode 100644 index 0000000..23117d4 --- /dev/null +++ b/app/src/main/res/xml/keyboard_number.xml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/keyboard_symbol.xml b/app/src/main/res/xml/keyboard_symbol.xml new file mode 100644 index 0000000..7470b49 --- /dev/null +++ b/app/src/main/res/xml/keyboard_symbol.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file