V1.0.1(1) 集成firebase

This commit is contained in:
litingting 2024-11-20 16:29:09 +08:00
commit 11f29c628a
99 changed files with 9344 additions and 0 deletions

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

1
app/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

BIN
app/KeyboardThemes.jks Normal file

Binary file not shown.

BIN
app/KeyboardThemestest.jks Normal file

Binary file not shown.

80
app/build.gradle.kts Normal file
View File

@ -0,0 +1,80 @@
import java.util.Date
import java.text.SimpleDateFormat
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.gms.google-services")
id("com.google.firebase.crashlytics")
}
val timestamp = SimpleDateFormat("MM_dd_HH_mm").format(Date())
android {
namespace = "com.keyboard.theme.app.keyboard"
compileSdk = 34
defaultConfig {
//com.key.keyboard.theme.keyboardapp
applicationId = "com.key.keyboard.theme"
minSdk = 23
targetSdk = 34
versionCode = 2
versionName = "1.0.1"
setProperty("archivesBaseName", "Keyboard Themes_V" + versionName + "(${versionCode})_$timestamp")
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.3"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
buildFeatures{
compose = false
viewBinding = true
}
}
dependencies {
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.11.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.activity:activity-compose:1.8.2")
implementation ("com.github.bumptech.glide:glide:4.16.0")
implementation ("jp.wasabeef:glide-transformations:4.3.0")
// //Glide支持webp动图的库
// implementation ("com.github.zjupure:webpdecoder:2.0.4.12.0")
implementation("com.github.omicronapps:7-Zip-JBinding-4Android:Release-16.02-2.02")
// implementation ("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
//------------------firebase
implementation(platform("com.google.firebase:firebase-bom:33.1.1"))
implementation("com.google.firebase:firebase-crashlytics")
implementation("com.google.firebase:firebase-analytics")
implementation("com.google.firebase:firebase-config")
}

29
app/google-services.json Normal file
View File

@ -0,0 +1,29 @@
{
"project_info": {
"project_number": "873603172415",
"project_id": "keyboard-theme-f27fc",
"storage_bucket": "keyboard-theme-f27fc.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:873603172415:android:a8867e36ce43caf670d08a",
"android_client_info": {
"package_name": "com.key.keyboard.theme"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyCffR-Wg8Ci5yRi0nA9s45M5Vyu5kinrEk"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

25
app/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,25 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-keep class com.omicronapplications.** { *; }
-keep class net.sf.sevenzipjbinding.** { *; }
-keep class com.keyboard.theme.app.keyboard.data.InfoChild { *; }

View File

@ -0,0 +1,24 @@
package com.keyboard.theme.app.keyboard
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.exam.theme.test.keyboard", appContext.packageName)
}
}

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MyAppllication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/logo"
android:roundIcon="@mipmap/logo"
android:label="@string/text_app_name"
android:supportsRtl="true"
android:theme="@style/Theme.KeyboardSkinApplication"
tools:targetApi="31">
<activity
android:name=".ui.SuccessActivity"
android:screenOrientation="portrait"
android:exported="false" />
<activity
android:name=".ui.ClassActivity"
android:exported="false"
android:screenOrientation="portrait" />
<activity
android:name=".ui.ActivityLauncher"
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.ActivityApply"
android:exported="false"
android:screenOrientation="portrait" />
<service
android:name=".myservice.InputService"
android:exported="true"
android:permission="android.permission.BIND_INPUT_METHOD">
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
<meta-data
android:name="android.view.im"
android:resource="@xml/view_key" />
</service>
<activity
android:name=".ui.MainActivity"
android:exported="false"
android:screenOrientation="portrait" />
</application>
</manifest>

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,38 @@
package com.keyboard.theme.app.keyboard
import android.app.Application
import android.graphics.Typeface
import android.util.Log
import com.google.firebase.FirebaseApp
import com.keyboard.theme.app.keyboard.data.Info
import com.keyboard.theme.app.keyboard.utils.FileManager
class MyAppllication : Application() {
override fun onCreate() {
super.onCreate()
instance = this
FileManager.getFileStr(assets.open("data.json")) {
if (it != null) {
requireNotNull(it.isNotEmpty())
data = FileManager.getDataBean(it)
}
}
font = Typeface.createFromAsset(assets,"myfont.ttf")
if (FirebaseApp.getApps(this).isNotEmpty()) {
// Log.d("TAG", "Firebase 初始化成功");
} else {
// Log.e("TAG", "Firebase 初始化失败");
}
}
companion object {
var data: List<Info> = mutableListOf()
lateinit var instance: MyAppllication
lateinit var font:Typeface
}
}

View File

@ -0,0 +1,95 @@
package com.keyboard.theme.app.keyboard.adapter
import android.content.Context
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.keyboard.theme.app.keyboard.R
import com.keyboard.theme.app.keyboard.api.OnHomeApi
import com.keyboard.theme.app.keyboard.data.Info
import com.keyboard.theme.app.keyboard.databinding.ItemClassBinding
import com.keyboard.theme.app.keyboard.utils.Common
class HomeClassAdapter(var con: Context, var data: List<Info>) :
RecyclerView.Adapter<HomeClassAdapter.TabViewHolder>() {
private var old = -4
private var cur = 0
private lateinit var mListener: OnHomeApi
inner class TabViewHolder(var viewbing: ItemClassBinding) :
RecyclerView.ViewHolder(viewbing.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TabViewHolder {
val inflate = ItemClassBinding.inflate(LayoutInflater.from(con), parent, false)
return TabViewHolder(inflate)
}
fun setListener(listener: OnHomeApi) {
mListener = listener
}
fun updateCurPos(pos: Int) {
old = cur
cur = pos
notifyItemChanged(old)
notifyItemChanged(pos)
}
override fun getItemCount(): Int {
return data.size
}
override fun onBindViewHolder(holder: TabViewHolder, position: Int) {
data[position].run {
holder.viewbing.classTile.apply {
Common.setFont(this)
text = className
}
val ims = listOf<ImageView>(
holder.viewbing.preview1,
holder.viewbing.preview2,
holder.viewbing.preview3,
holder.viewbing.preview4
)
list?.forEachIndexed { index, infoChild ->
val imageView = ims[index]
Glide.with(con).load(infoChild.preview)
.transform(RoundedCorners(Common.dpToUnitPx(10f)))
.placeholder(ContextCompat.getDrawable(con, R.mipmap.placholder))
.into(imageView)
imageView.setOnClickListener {
mListener.onHomeClick(infoChild)
}
}
holder.viewbing.btnMore.setOnClickListener {
mListener.onHomeClickMore(this)
}
}
}
private fun setView(holder: TabViewHolder, boolean: Boolean) {
holder.viewbing.classTile.let {
it.isSelected = boolean
if (boolean) {
it.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18F)
} else {
it.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15F)
}
}
}
}

View File

@ -0,0 +1,50 @@
package com.keyboard.theme.app.keyboard.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.keyboard.theme.app.keyboard.MyAppllication
import com.keyboard.theme.app.keyboard.R
import com.keyboard.theme.app.keyboard.api.OnHomeApi
import com.keyboard.theme.app.keyboard.data.InfoChild
import com.keyboard.theme.app.keyboard.databinding.ItemSingeClassBinding
import com.keyboard.theme.app.keyboard.utils.Common
class SingeClassAdapter(private var mContext: Context, private var data: List<InfoChild> = emptyList()) :
RecyclerView.Adapter<SingeClassAdapter.ClassHolder>() {
private lateinit var mListener: OnHomeApi
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ClassHolder {
val inflate = ItemSingeClassBinding.inflate(LayoutInflater.from(mContext), parent, false)
return ClassHolder(inflate)
}
fun setListener(listener: OnHomeApi) {
mListener = listener
}
override fun onBindViewHolder(holder: ClassHolder, position: Int) {
val infoChild = data[position]
holder.viewbing.run {
Glide.with(MyAppllication.instance).load(infoChild.preview)
.transform(RoundedCorners(Common.dpToUnitPx(10f)))
.placeholder(ContextCompat.getDrawable(MyAppllication.instance, R.mipmap.placholder))
.into(preview)
preview.setOnClickListener {
mListener.onHomeClick(infoChild)
}
}
}
override fun getItemCount(): Int = data.size
inner class ClassHolder( var viewbing: ItemSingeClassBinding) :
RecyclerView.ViewHolder(viewbing.root)
}

View File

@ -0,0 +1,6 @@
package com.keyboard.theme.app.keyboard.api;
public interface OnApplyApi {
void applyListener(Boolean isSuccess,String str);
}

View File

@ -0,0 +1,11 @@
package com.keyboard.theme.app.keyboard.api;
import com.keyboard.theme.app.keyboard.data.Info;
import com.keyboard.theme.app.keyboard.data.InfoChild;
public interface OnHomeApi {
void onHomeClick(InfoChild infoChild);
void onHomeClickMore(Info info);
}

View File

@ -0,0 +1,8 @@
package com.keyboard.theme.app.keyboard.api;
import com.keyboard.theme.app.keyboard.data.InfoChild;
public interface OnPreApi {
void onListener(InfoChild infoChild);
}

View File

@ -0,0 +1,6 @@
package com.keyboard.theme.app.keyboard.api;
public interface OnUpdateApi {
void onRefreshResult();
}

View File

@ -0,0 +1,5 @@
package com.keyboard.theme.app.keyboard.data
class Info(var className:String?= null, var list:List<InfoChild>? = null) {
}

View File

@ -0,0 +1,6 @@
package com.keyboard.theme.app.keyboard.data
import java.io.Serializable
class InfoChild(var title:String, var thumb:String, var zipUrl:String, var preview:String):Serializable {
}

View File

@ -0,0 +1,200 @@
package com.keyboard.theme.app.keyboard.myservice
import android.inputmethodservice.InputMethodService
import android.inputmethodservice.Keyboard
import android.inputmethodservice.KeyboardView.OnKeyboardActionListener
import android.os.SystemClock
import android.view.View
import android.view.inputmethod.EditorInfo
import com.keyboard.theme.app.keyboard.R
import com.keyboard.theme.app.keyboard.databinding.ViewKeyboradBinding
import com.keyboard.theme.app.keyboard.utils.StaticValue
class InputService : InputMethodService() ,OnKeyboardActionListener{
private var mouble = false
private var views = intArrayOf(R.xml.a_xml, R.xml.b_xml, R.xml.c_xml)
private var la_Time = -3L
private lateinit var viewBinding: ViewKeyboradBinding
override fun onCreateInputView(): View {
viewBinding = ViewKeyboradBinding.inflate(layoutInflater, null, false)
viewBinding.idCustomInput.setOnKeyboardActionListener(this)
initInputView()
return viewBinding.root
}
private fun changeXml(mode: Int) {
viewBinding.idCustomInput.run {
when (mode) {
0 -> {
xmlMode = StaticValue.xml0
keyboard = Keyboard(mContext, views[0])
}
2 -> {
xmlMode = StaticValue.xml2
keyboard = Keyboard(mContext, views[2])
}
1 -> {
xmlMode = StaticValue.xml1
keyboard = Keyboard(mContext, views[1])
}
}
}
}
override fun onWindowShown() {
super.onWindowShown()
viewBinding.idCustomInput.upUi(this)
}
private fun keySB(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 initInputView() {
viewBinding.idCustomInput.run {
keyboard = Keyboard(this@InputService, views[0])
isEnabled = true
}
}
override fun onPress(primaryCode: Int) {
mouble = false
if (primaryCode == Keyboard.KEYCODE_SHIFT) {
if (300 > SystemClock.elapsedRealtime() - la_Time) {
mouble = true
}
la_Time = SystemClock.elapsedRealtime()
}
}
override fun onRelease(primaryCode: Int) {
}
override fun onKey(primaryCode: Int, keyCodes: IntArray?) {
when (primaryCode) {
Keyboard.KEYCODE_SHIFT -> {
viewBinding.idCustomInput.run {
val myKeyboard = keyboard
when (shift_status) {
StaticValue.Shift_S -> {
shift_status = if (mouble) {
StaticValue.Shift_B_lo
} else {
StaticValue.Shift_B
}
keySB(true, myKeyboard)
keyboard = myKeyboard
}
StaticValue.Shift_B_lo -> {
shift_status = StaticValue.Shift_S
keySB(false, myKeyboard)
keyboard = myKeyboard
}
StaticValue.Shift_B -> {
shift_status = if (mouble) {
StaticValue.Shift_B_lo
} else {
keySB(false, myKeyboard)
StaticValue.Shift_S
}
keyboard = myKeyboard
}
}
}
}
Keyboard.KEYCODE_DONE -> {
currentInputConnection.performEditorAction(EditorInfo.IME_ACTION_DONE)
}
Keyboard.KEYCODE_MODE_CHANGE -> {
viewBinding.idCustomInput.run {
if (xmlMode == StaticValue.xml0) {
changeXml(1)
} else {
changeXml(0)
}
}
}
StaticValue.SHIFT_NUMBER -> {
changeXml(2)
}
Keyboard.KEYCODE_DELETE -> {
currentInputConnection.deleteSurroundingText(1, 0)
}
StaticValue.SHIFT_SYMBOL -> {
changeXml(1)
}
else -> {
currentInputConnection.commitText(primaryCode.toChar().toString(), 1)
viewBinding.idCustomInput.keyboard = viewBinding.idCustomInput.apply {
if (shift_status == StaticValue.Shift_B) {
shift_status = StaticValue.Shift_S
keySB(false, viewBinding.idCustomInput.keyboard)
}
}.keyboard
}
}
}
override fun onText(text: CharSequence?) {
}
override fun swipeLeft() {
}
override fun swipeRight() {
}
override fun swipeDown() {
}
override fun swipeUp() {
}
}

View File

@ -0,0 +1,159 @@
package com.keyboard.theme.app.keyboard.myservice
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.inputmethodservice.Keyboard
import android.inputmethodservice.KeyboardView
import android.util.AttributeSet
import com.keyboard.theme.app.keyboard.utils.KeyBoardManager
import com.keyboard.theme.app.keyboard.utils.Common
import com.keyboard.theme.app.keyboard.utils.StaticValue
@Suppress("DEPRECATION")
class MyCustomView @JvmOverloads constructor(
var mContext: Context,
attributeSet: AttributeSet? = null,
style: Int = 0
) : KeyboardView(mContext, attributeSet, style) {
var keyBoardManager = KeyBoardManager.myKeyBoardManager
var shift_status = StaticValue.Shift_S
var xmlMode = StaticValue.xml0
private var mPaint: Paint = Paint().apply {
isAntiAlias = true
textAlign = Paint.Align.CENTER
textSize = Common.spToUnitPx(16f, mContext)
color = keyBoardManager.keycolor
}
override fun onDraw(canvas: Canvas) {
keyboard.keys.forEach {
when (it.codes[0]) {
Keyboard.KEYCODE_SHIFT -> {
andDraw(
it,
keyBoardManager.functionBackgroundDraw,
getCurIc(),
canvas
)
}
StaticValue.SHIFT_NUMBER, StaticValue.SHIFT_SYMBOL -> {
andDraw(it, keyBoardManager.functionBackgroundDraw, null, canvas)
}
Keyboard.KEYCODE_DELETE -> {
andDraw(
it,
keyBoardManager.functionBackgroundDraw,
keyBoardManager.icDel,
canvas
)
}
Keyboard.KEYCODE_MODE_CHANGE, Keyboard.KEYCODE_DONE -> {
andDraw(it, keyBoardManager.functionBackgroundDraw, null, canvas)
}
else -> {
andDraw(it, keyBoardManager.normalBackgroundDraw, null, canvas)
}
}
}
}
fun upUi(con: Context) {
keyBoardManager.uodateConfig(con)
background = keyBoardManager.allBg
invalidate()
}
private fun getCurIc(): Drawable? {
return when (shift_status) {
StaticValue.Shift_B_lo -> keyBoardManager.icShittLock
StaticValue.Shift_B -> keyBoardManager.icBshift
StaticValue.Shift_S -> keyBoardManager.icSshift
else -> keyBoardManager.icSshift
}
}
@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)
}
}
mPaint.color = keyBoardManager.keycolor
if (!label.isNullOrEmpty()) {
val y1 = y.plus(paddingRight).plus((height.div(2f))).plus((mPaint.textSize.minus(mPaint.descent())).div(2f))
val x1 = x.plus(paddingLeft).plus((width.div(2f)))
canvas.drawText(label.toString(), x1, y1, mPaint)
}
}
}
}

View File

@ -0,0 +1,172 @@
package com.keyboard.theme.app.keyboard.ui;
import static com.keyboard.theme.app.keyboard.utils.StaticValue.KEYTheme;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.keyboard.theme.app.keyboard.MyAppllication;
import com.keyboard.theme.app.keyboard.R;
import com.keyboard.theme.app.keyboard.data.InfoChild;
import com.keyboard.theme.app.keyboard.databinding.ActivityApplyBinding;
import com.keyboard.theme.app.keyboard.utils.Common;
import com.keyboard.theme.app.keyboard.utils.FileManager;
import com.keyboard.theme.app.keyboard.utils.StaticValue;
import com.keyboard.theme.app.keyboard.utils.StepManager;
import java.io.File;
public class ActivityApply extends BaseActivity<ActivityApplyBinding> implements View.OnClickListener {
private InfoChild infoChild;
private String unZipPath;
private ActivityApplyBinding bind;
private ActivityStep dialogStep;
@NonNull
@Override
public ActivityApplyBinding returnViewbinding() {
Common.INSTANCE.initFull(this, false);
return ActivityApplyBinding.inflate(getLayoutInflater());
}
@Override
public void onInit() {
bind = getVb();
Common.INSTANCE.setFont(bind.idSet);
Common.INSTANCE.setFont( bind.idTheme);
Intent intent = getIntent();
infoChild = (InfoChild) intent.getSerializableExtra(KEYTheme);
File cacheDir = MyAppllication.instance.getCacheDir();
String unZip = FileManager.INSTANCE.getUnZip(infoChild.getTitle());
unZipPath = cacheDir + "/" + unZip;
bind.idTheme.setText(infoChild.getTitle());
initText();
initListener();
loadPreview();
}
private void initListener() {
bind.idBack.setOnClickListener(this);
bind.idSet.setOnClickListener(this);
}
private void initText() {
File file = new File(unZipPath);
if (!file.exists()) {
bind.idSet.setText(getString(R.string.text_text_download_apply));
} else {
bind.idSet.setText(getString(R.string.text_text_apply));
}
}
private void loadPreview() {
bind.idPreloading.setVisibility(View.VISIBLE);
Glide.with(ActivityApply.this).load(infoChild.getPreview())
.placeholder(ContextCompat.getDrawable(this, R.mipmap.placholder))
.addListener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
bind.idPreloading.setVisibility(View.GONE);
return false;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
bind.idPreloading.setVisibility(View.GONE);
return false;
}
})
.transform(new RoundedCorners(Common.INSTANCE.dpToUnitPx(10f)))
.into(bind.idImage);
}
@Override
protected void onResume() {
super.onResume();
if(dialogStep!= null){
dialogStep.updateUi();
}
}
private void onapply() {
if (!StepManager.INSTANCE.toEnable() || !StepManager.INSTANCE.onsetInput()) {
if(dialogStep == null){
dialogStep = new ActivityStep(this);
}
if(!dialogStep.isAdded()){
dialogStep.show(getSupportFragmentManager(),"");
}
return;
}
bind.idProgressbar.setVisibility(View.VISIBLE);
File file = new File(unZipPath);
if (file.exists()) {
String allThemePath = Common.INSTANCE.getAllThemePath(infoChild.getTitle());
if(allThemePath != null){
Common.INSTANCE.putCurPath(allThemePath);
}
bind.idProgressbar.setVisibility(View.GONE);
Toast.makeText(this, getString(R.string.text_succ_apply), Toast.LENGTH_LONG).show();
goSuccess();
finish();
} else {
FileManager.INSTANCE.getZipData(infoChild.getTitle(), infoChild.getZipUrl(), this, this::onResult) ;
}
}
private void onResult(Boolean isSuccess, String path){
bind.idProgressbar.setVisibility(View.GONE);
if (isSuccess) {
int lastIndexOf = path.lastIndexOf(StaticValue.INSTANCE.getRes_path());
String substring = path.subSequence(0, lastIndexOf + StaticValue.INSTANCE.getRes_path().length()).toString();
Common.INSTANCE.putCurPath(substring);
Common.INSTANCE.putAllThemePath(infoChild.getTitle(), substring);
Toast.makeText(this, getString(R.string.text_succ_apply), Toast.LENGTH_LONG).show();
goSuccess();
finish();
} else {
Toast.makeText(this, getString(R.string.text_fail_apply), Toast.LENGTH_LONG).show();
}
}
private void goSuccess(){
Intent intent = new Intent(this, SuccessActivity.class);
intent.putExtra(SuccessActivity.key_name,infoChild.getTitle());
startActivity(intent);
}
@Override
public void onClick(View v) {
if (v.equals(bind.idBack)) {
finish();
} else if (v.equals(bind.idSet)) {
onapply();
}
}
}

View File

@ -0,0 +1,59 @@
package com.keyboard.theme.app.keyboard.ui;
import android.content.Intent;
import android.os.CountDownTimer;
import androidx.annotation.NonNull;
import com.keyboard.theme.app.keyboard.databinding.ActvityLaunBinding;
import com.keyboard.theme.app.keyboard.utils.Common;
public class ActivityLauncher extends BaseActivity<ActvityLaunBinding> {
private long count = 2000L;
private CountDownTimer countDownTimer;
private ActvityLaunBinding binding;
@NonNull
@Override
public ActvityLaunBinding returnViewbinding() {
Common.INSTANCE.initFull(this, true);
return ActvityLaunBinding.inflate(getLayoutInflater());
}
@Override
public void onInit() {
binding = getVb();
countDownTimer = new CountDownTimer(count, 100) {
@Override
public void onTick(long millisUntilFinished) {
int progressPercentage = (int) ((100 * millisUntilFinished) / count);
// 或者从 100% 0% 的倒计时
int Percentage = 100 - progressPercentage;
binding.progress.setProgress(Percentage);
}
@Override
public void onFinish() {
binding.progress.setProgress(100);
goHome();
}
}.start();
}
private void goHome(){
Intent setIntent = new Intent(this, MainActivity.class);
startActivity(setIntent);
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
if(countDownTimer!= null){
countDownTimer.cancel();
}
}
}

View File

@ -0,0 +1,117 @@
package com.keyboard.theme.app.keyboard.ui;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import com.keyboard.theme.app.keyboard.databinding.DialogStepBinding;
import com.keyboard.theme.app.keyboard.utils.StepManager;
public class ActivityStep extends DialogFragment implements View.OnClickListener {
private BroadcastReceiver receiver;
private DialogStepBinding binding;
private Context context;
@Override
public void onClick(View v) {
if (v.equals(binding.idStep2)) {
StepManager.INSTANCE.onSetEnab();
} else if (v.equals(binding.idStep1)) {
StepManager.INSTANCE.toSet(context);
}
}
public ActivityStep(Context context) {
this.context = context;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = DialogStepBinding.inflate(getLayoutInflater());
onInit();
return binding.getRoot();
}
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
dialog.setCanceledOnTouchOutside(true);
Window window = dialog.getWindow();
if (window != null) {
window.setGravity(Gravity.BOTTOM);
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
}
}
}
public void onInit() {
updateUi();
receiver = new myReceive();
register();
binding.idStep1.setOnClickListener(this);
binding.idStep2.setOnClickListener(this);
}
class myReceive extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
updateUi();
}
}
private void register() {
context.registerReceiver(receiver, new IntentFilter(Intent.ACTION_INPUT_METHOD_CHANGED));
}
@Override
public void onDestroyView() {
super.onDestroyView();
context.unregisterReceiver(receiver);
}
public void updateUi() {
binding.idStep1.setSelected(StepManager.INSTANCE.toEnable());
binding.idStep2.setSelected(StepManager.INSTANCE.onsetInput());
boolean selected = binding.idStep1.isSelected();
boolean selected1 = binding.idStep2.isSelected();
if(selected){
binding.idStep1.setEnabled(false);
}
if(selected1){
binding.idStep2.setEnabled(false);
}
if(selected&&selected1){
dismiss();
}
}
}

View File

@ -0,0 +1,22 @@
package com.keyboard.theme.app.keyboard.ui
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
abstract class BaseActivity<viewbinding: ViewBinding> : AppCompatActivity() {
protected val Vb by lazy { returnViewbinding() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(Vb.root)
onInit()
}
abstract fun returnViewbinding():viewbinding
abstract fun onInit()
}

View File

@ -0,0 +1,90 @@
package com.keyboard.theme.app.keyboard.ui;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import com.keyboard.theme.app.keyboard.MyAppllication;
import com.keyboard.theme.app.keyboard.adapter.SingeClassAdapter;
import com.keyboard.theme.app.keyboard.api.OnHomeApi;
import com.keyboard.theme.app.keyboard.data.Info;
import com.keyboard.theme.app.keyboard.data.InfoChild;
import com.keyboard.theme.app.keyboard.databinding.ActivityClassBinding;
import com.keyboard.theme.app.keyboard.utils.Common;
import com.keyboard.theme.app.keyboard.utils.ItemSpace;
import com.keyboard.theme.app.keyboard.utils.StaticValue;
import java.util.List;
import java.util.Objects;
public class ClassActivity extends BaseActivity<ActivityClassBinding> implements OnHomeApi {
public static final String KEY = "KEY_class_name";
private ActivityClassBinding binding;
private Info classInfo;
@NonNull
@Override
public ActivityClassBinding returnViewbinding() {
Common.INSTANCE.initFull(this, false);
return ActivityClassBinding.inflate(getLayoutInflater());
}
@Override
public void onInit() {
binding = getVb();
String className = getIntent().getStringExtra(KEY);
Common.INSTANCE.setFont(binding.classTitle);
binding.classTitle.setText(className);
for (Info datum : MyAppllication.Companion.getData()) {
if(Objects.equals(datum.getClassName(), className)){
classInfo = datum;
Log.d("-----","---datum.getClassName()="+datum.getClassName()+"----className="+className);
break;
}
}
binding.imBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
initList();
}
private void initList(){
List<InfoChild> list = classInfo.getList();
if(list == null){
return;
}
SingeClassAdapter SingeClassAdapter = new SingeClassAdapter(this, list);
SingeClassAdapter.setListener(this);
ItemSpace itemSpace = new ItemSpace(Common.INSTANCE.dpToUnitPx(8), Common.INSTANCE.dpToUnitPx(8), Common.INSTANCE.dpToUnitPx(8));
GridLayoutManager gridLayoutManager =
new GridLayoutManager(this, 2);
binding.recycler.setLayoutManager(gridLayoutManager);
binding.recycler.setAdapter(SingeClassAdapter);
binding.recycler.addItemDecoration(itemSpace);
// SingeClassAdapter.setListener(this);
}
@Override
public void onHomeClick(InfoChild infoChild) {
Intent setIntent = new Intent(this, ActivityApply.class);
setIntent.putExtra(StaticValue.KEYTheme, infoChild);
startActivity(setIntent);
}
@Override
public void onHomeClickMore(Info info) {
}
}

View File

@ -0,0 +1,83 @@
package com.keyboard.theme.app.keyboard.ui;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.keyboard.theme.app.keyboard.MyAppllication;
import com.keyboard.theme.app.keyboard.adapter.HomeClassAdapter;
import com.keyboard.theme.app.keyboard.api.OnHomeApi;
import com.keyboard.theme.app.keyboard.data.Info;
import com.keyboard.theme.app.keyboard.data.InfoChild;
import com.keyboard.theme.app.keyboard.databinding.ActivityHomeBinding;
import com.keyboard.theme.app.keyboard.utils.Common;
import com.keyboard.theme.app.keyboard.utils.StaticValue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MainActivity extends BaseActivity<ActivityHomeBinding> implements OnHomeApi {
private HomeClassAdapter homeClassAdapter;
private int index = 0;
private ActivityHomeBinding VB;
@NonNull
@Override
public ActivityHomeBinding returnViewbinding() {
Common.INSTANCE.initFull(this, false);
return ActivityHomeBinding.inflate(getLayoutInflater());
}
@Override
public void onInit() {
VB = getVb();
Common.INSTANCE.setFont(VB.title);
initAdapter();
}
private void initAdapter() {
List<Info> tempList = new ArrayList<>();
List<Info> data = MyAppllication.Companion.getData();
for (Info datum : data) {
Info info = new Info();
List<InfoChild> list = datum.getList();
info.setClassName(datum.getClassName());
Collections.shuffle(list);
List<InfoChild> infoChildren = list.subList(0, 4);
info.setList(infoChildren);
tempList.add(info);
}
homeClassAdapter = new HomeClassAdapter(this, tempList);
LinearLayoutManager linearLayoutManager =
new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
VB.categoryRecycler.setLayoutManager(linearLayoutManager);
VB.categoryRecycler.setAdapter(homeClassAdapter);
homeClassAdapter.setListener(this);
}
@Override
public void onHomeClick(InfoChild infoChild) {
Intent setIntent = new Intent(this, ActivityApply.class);
setIntent.putExtra(StaticValue.KEYTheme, infoChild);
startActivity(setIntent);
}
@Override
public void onHomeClickMore(Info info) {
Intent setIntent = new Intent(this, ClassActivity.class);
setIntent.putExtra(ClassActivity.KEY,info.getClassName());
startActivity(setIntent);
}
}

View File

@ -0,0 +1,114 @@
package com.keyboard.theme.app.keyboard.ui;
import static com.bumptech.glide.request.RequestOptions.bitmapTransform;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.keyboard.theme.app.keyboard.R;
import com.keyboard.theme.app.keyboard.databinding.ActivitySuccessBinding;
import com.keyboard.theme.app.keyboard.utils.Common;
import com.keyboard.theme.app.keyboard.utils.StaticValue;
import jp.wasabeef.glide.transformations.BlurTransformation;
public class SuccessActivity extends BaseActivity<ActivitySuccessBinding> {
private ActivitySuccessBinding vb;
public static String key_name = "key_name";
private int mPreviousKeyboardHeight = -1;
@NonNull
@Override
public ActivitySuccessBinding returnViewbinding() {
Common.INSTANCE.initFull(this, false);
return ActivitySuccessBinding.inflate(getLayoutInflater());
}
@Override
public void onInit() {
vb = getVb();
String stringExtra = getIntent().getStringExtra(key_name);
vb.title.setText(stringExtra);
Common.INSTANCE.setFont(vb.title);
String curPath = Common.INSTANCE.getCurPath();
vb.idBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
if (curPath == null) {
return;
}
String stringBuilder = curPath + StaticValue.INSTANCE.getXx_path() +
StaticValue.INSTANCE.getPreview_bg();
Drawable bgDraw = Common.INSTANCE.getbgic(this, stringBuilder);
if (bgDraw != null) {
Glide.with(this)
.load(bgDraw)
.apply(bitmapTransform(new BlurTransformation(15, 3))) // 设置模糊半径和模糊采样
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
vb.relayout.setBackground(resource);
return false;
}
})
.preload();
}
keyboardheight();
vb.et.requestFocus();
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
private void keyboardheight() {
final View rootView = getWindow().getDecorView();
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int screenHeight = rootView.getRootView().getHeight();
int keypadHeight = screenHeight - r.bottom;
if (keypadHeight != mPreviousKeyboardHeight) {
// 软键盘高度发生变化时的处理逻辑
Log.d("KeyboardSize", "Keyboard Height is: " + keypadHeight);
if (mPreviousKeyboardHeight < keypadHeight) {
Log.d("KeyboardSize", " 11111111111");
mPreviousKeyboardHeight = keypadHeight;
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) vb.et.getLayoutParams();
params.bottomMargin = mPreviousKeyboardHeight;
vb.et.setLayoutParams(params);
}
}
}
});
}
}

View File

@ -0,0 +1,94 @@
package com.keyboard.theme.app.keyboard.utils
import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.StateListDrawable
import android.view.View
import android.view.WindowManager
import android.widget.TextView
import com.keyboard.theme.app.keyboard.MyAppllication
import java.io.File
object Common {
fun dpToUnitPx(dp: Float): Int {
val scale = MyAppllication.instance.resources.displayMetrics.density
return (dp * scale + 0.5f).toInt()
}
fun spToUnitPx(sp: Float, con: Context): Float {
val scale = con.resources.displayMetrics.scaledDensity
return sp * scale
}
fun getStatus(draw: Drawable, drawPress: Drawable): StateListDrawable {
return StateListDrawable().apply {
addState(intArrayOf(android.R.attr.state_pressed), drawPress)
addState(intArrayOf(), draw)
}
}
private val sp: SharedPreferences = MyAppllication.instance.getSharedPreferences(
StaticValue.SHARE_NAME,
Context.MODE_PRIVATE
)
private val edit = sp.edit()
fun putCurPath(path: String) {
edit.run {
putString(StaticValue.KEY_ALL_PATH, path)
apply()
}
}
fun getCurPath(): String? {
return sp.getString(StaticValue.KEY_ALL_PATH, "")
}
fun putAllThemePath(title: String, path: String) {
edit.run {
putString(title, path)
apply()
}
}
fun getAllThemePath(zip: String): String? {
return sp.getString(zip, "")
}
fun initFull(activity: Activity, light: Boolean) {
val window = activity.window
val decorView = window.decorView
val rootView = decorView.rootView
if (light) {
} else {
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
}
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
fun setFont(text: TextView) {
text.typeface = MyAppllication.font
}
fun getbgic(con: Context, filePath: String): Drawable? {
if (!File(filePath).exists()) {
return null
}
return BitmapDrawable(con.resources, BitmapFactory.decodeFile(filePath))
}
}

View File

@ -0,0 +1,208 @@
package com.keyboard.theme.app.keyboard.utils
import android.content.Context
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.keyboard.theme.app.keyboard.MyAppllication
import com.keyboard.theme.app.keyboard.data.Info
import com.keyboard.theme.app.keyboard.data.InfoChild
import com.keyboard.theme.app.keyboard.api.OnApplyApi
import net.sf.sevenzipjbinding.ArchiveFormat
import net.sf.sevenzipjbinding.SevenZip
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream
import net.sf.sevenzipjbinding.impl.RandomAccessFileOutStream
import org.json.JSONArray
import java.io.BufferedReader
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.InputStream
import java.io.InputStreamReader
import java.io.RandomAccessFile
import java.io.StringWriter
object FileManager {
fun getFileStr(stream: InputStream, callback: (String?) -> Unit) {
try {
var leng = 0
val writer = StringWriter()
val charArrayOf = CharArray(stream.available())
val reader = BufferedReader(InputStreamReader(stream))
while (reader.read(charArrayOf).also {
leng = it
} != -1) {
writer.write(charArrayOf, 0, leng)
}
callback.invoke(writer.toString())
} catch (ex: Exception) {
callback.invoke(null)
}
}
fun getDataBean(str: String): List<Info> {
var skinList = mutableListOf<Info>()
JSONArray(str).let {
for (i in 0 until it.length()) {
it.getJSONObject(i).apply {
val name = getString("className")
var skin = mutableListOf<InfoChild>()
getJSONArray("list").let { keyList ->
for (j in 0 until keyList.length()) {
keyList.getJSONObject(j).let { listStr ->
val mpreview = listStr.getString("preview")
val mthumb = listStr.getString("thumb")
val mtitle = listStr.getString("title")
val mzipUrl = listStr.getString("zipUrl")
skin.add(
InfoChild(
title = mtitle,
thumb = mthumb,
zipUrl = mzipUrl,
preview = mpreview
)
)
}
}
}
skinList.add(Info(name, skin))
}
}
}
return skinList
}
fun writeNewFile(input: InputStream, filePath: String): Boolean {
var stream: FileOutputStream? = null
var outStream: ByteArrayOutputStream? = null
try {
val outStream = ByteArrayOutputStream()
val bytes = ByteArray(4096)
var length = 0
while (input.read(bytes).also {
length = it
} != -1) {
outStream.write(bytes, 0, length)
}
val file = File(filePath)
if (!file.exists()) {
file.createNewFile()
}
stream = FileOutputStream(file)
stream.run {
write(outStream.toByteArray())
}
outStream.close()
stream.close()
return true
} catch (ex: Exception) {
outStream?.close()
stream?.close()
return false
}
}
private fun getZipName(url: String): String {
return url.substring(url.lastIndexOf("/") + 1)
}
fun getUnZip(url: String): String {
val fileName = getZipName(url)
return fileName.substringBefore(".")
}
fun getZipData(title: String, url: String, con: Context, listener: OnApplyApi) {
Glide.with(con)
.asFile()
.load(url)
.addListener(object : RequestListener<File> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<File>,
isFirstResource: Boolean
): Boolean {
listener.applyListener(false, "")
return false
}
override fun onResourceReady(
resource: File,
model: Any,
target: Target<File>?,
dataSource: DataSource,
isFirstResource: Boolean
): Boolean {
val fileInputStream = FileInputStream(resource)
dealFile(title, url, fileInputStream, listener)
return false
}
}).preload()
}
private fun dealFile(
title: String,
url: String,
input: FileInputStream,
listener: OnApplyApi
) {
val zipPath = "${MyAppllication.instance.cacheDir}/${title}_ZIP"
val unPath = "${MyAppllication.instance.cacheDir}/${title}"
val zipBoolean = writeNewFile(input, zipPath)
val randomAccessFileInStream =
RandomAccessFileInStream(RandomAccessFile(File(zipPath), "r"))
val openInArchive = SevenZip.openInArchive(
ArchiveFormat.SEVEN_ZIP,
randomAccessFileInStream
)
var out: RandomAccessFileOutStream? = null
if (zipBoolean) {
try {
var filePath: String = ""
openInArchive.simpleInterface.archiveItems.forEach { item ->
if (!item.isFolder) {
val file = File(unPath, item.path)
out = RandomAccessFileOutStream(RandomAccessFile(file, "rw"))
item.extractSlow(out)
filePath = file.path
} else {
File(unPath, item.path).mkdirs()
}
}
listener.applyListener(true, filePath)
} catch (ex: Exception) {
listener.applyListener(false, "")
} finally {
openInArchive.close()
randomAccessFileInStream.close()
out?.close()
}
}
}
}

View File

@ -0,0 +1,56 @@
package com.keyboard.theme.app.keyboard.utils;
import android.graphics.Rect;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class ItemSpace extends RecyclerView.ItemDecoration {
private int ex_space = 0;
private int v_space = 0;
private int h_space = 0;
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view);
int spanSize = 1;
int spanIndex = 0;
int spanCount = 1;
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
GridLayoutManager layoutManager1 = (GridLayoutManager) layoutManager;
GridLayoutManager.LayoutParams layoutParams = (GridLayoutManager.LayoutParams) view.getLayoutParams();
spanCount = layoutManager1.getSpanCount();
spanSize = layoutManager1.getSpanSizeLookup().getSpanSize(position);
spanIndex = layoutParams.getSpanIndex();
}
if (spanSize == spanCount) {
outRect.left = v_space + ex_space;
outRect.right = v_space + ex_space;
outRect.bottom = h_space;
} else {
int itemAllSpacing = (v_space * (spanCount + 1) + ex_space * 2) / spanCount;
int left = v_space * (spanIndex + 1) - itemAllSpacing * spanIndex + ex_space;
int right = itemAllSpacing - left;
outRect.left = left;
outRect.right = right;
outRect.bottom = h_space;
}
}
public ItemSpace(int v_space, int h_space, int ex_space) {
this.ex_space = ex_space;
this.h_space = h_space;
this.v_space = v_space;
}
}

View File

@ -0,0 +1,152 @@
package com.keyboard.theme.app.keyboard.utils
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.util.Xml
import androidx.core.content.ContextCompat
import com.keyboard.theme.app.keyboard.MyAppllication
import com.keyboard.theme.app.keyboard.R
import org.xmlpull.v1.XmlPullParser
import java.io.File
import java.io.StringReader
class KeyBoardManager {
companion object {
val myKeyBoardManager by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
KeyBoardManager()
}
}
lateinit var functionBackgroundDraw: Drawable
lateinit var spBackgroundDraw: Drawable
lateinit var normalBackgroundDraw: Drawable
var icShittLock: Drawable? =
ContextCompat.getDrawable(MyAppllication.instance, R.drawable.im_shift)
var icDel: Drawable? =
ContextCompat.getDrawable(MyAppllication.instance, R.drawable.im_del)
var allBg: Drawable? =
ContextCompat.getDrawable(MyAppllication.instance, R.mipmap.bg)
var icBshift: Drawable? =
ContextCompat.getDrawable(MyAppllication.instance, R.drawable.im_shift)
var keycolor: Int = MyAppllication.instance.resources.getColor(R.color.white, null)
var icSshift: Drawable? =
ContextCompat.getDrawable(MyAppllication.instance, R.drawable.im_shift)
init {
val default =
ContextCompat.getDrawable(MyAppllication.instance, R.drawable.default_keybg)
val press = ContextCompat.getDrawable(
MyAppllication.instance,
R.drawable.default_keybg_press
)
if (press != null) {
if (default != null) {
val listDrawable = Common.getStatus(default, press)
functionBackgroundDraw = listDrawable
normalBackgroundDraw = listDrawable
spBackgroundDraw = listDrawable
}
}
}
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 == StaticValue.title_color) {
keycolor = Color.parseColor(xmlP.nextText())
}
}
eventT = xmlP.next()
}
}
fun uodateConfig(con: Context) {
Common.getCurPath()?.let {
Common.getbgic(
con,
it.plus(StaticValue.parent_path).plus(StaticValue.title_nor_Bg)
)?.let { drawBG ->
Common. getbgic(
con,
it.plus(StaticValue.parent_path).plus(StaticValue.title_nor_Bg_press)
)?.let { drawPressBG ->
normalBackgroundDraw = Common.getStatus(drawBG, drawPressBG)
}
}
gettextcolor(it.plus(StaticValue.color_path))
Common.getbgic(con, it.plus(StaticValue.parent_path).plus(StaticValue.title_sp_Bg))?.let { drawBG ->
Common.getbgic(
con,
it.plus(StaticValue.parent_path).plus(StaticValue.title_sp_Bg_press)
)?.let { drawPressBG ->
spBackgroundDraw = Common.getStatus(drawBG, drawPressBG)
}
}
Common. getbgic(con, it.plus(StaticValue.xx_path).plus(StaticValue.title_bg))?.run {
allBg = this
}
Common.getbgic(
con,
it.plus(StaticValue.parent_path).plus(StaticValue.title_fun_Bg)
)?.let { drawBG ->
Common.getbgic(
con,
it.plus(StaticValue.parent_path).plus(StaticValue.title_func_bg_press)
)?.let { drawPressBG ->
functionBackgroundDraw = Common.getStatus(drawBG, drawPressBG)
}
}
Common.getbgic(con, it.plus(StaticValue.parent_path).plus(StaticValue.title_shitf_ic))?.let {
icSshift = it
icBshift = it
}
Common.getbgic(
con,
it.plus(StaticValue.parent_path).plus(StaticValue.title_del_ic)
)?.let { drawBG ->
icDel = Common.getStatus(drawBG, drawBG)
}
Common.getbgic(con, it.plus(StaticValue.parent_path).plus(StaticValue.title_shitf_ic_lock))?.let {
icShittLock = it
}
}
}
}

View File

@ -0,0 +1,39 @@
package com.keyboard.theme.app.keyboard.utils
object StaticValue {
const val SHIFT_NUMBER = -300
const val SHIFT_SYMBOL = -301
const val SHARE_NAME = "sp_name"
const val KEY_ALL_PATH = "all_path"
const val xml0 = 24
const val xml1 = 25
const val xml2 = 26
const val Shift_B_lo = 2
const val Shift_S = 0
const val Shift_B = 1
val title_fun_Bg = "btn_keyboard_key_functional_normal.9.png"
val title_del_ic= "sym_keyboard_delete_normal.png"
val title_shitf_ic = "sym_keyboard_shift.png"
val title_func_bg_press = "btn_keyboard_key_functional_pressed.9.png"
val title_nor_Bg = "btn_keyboard_key_normal_normal.9.png"
val res_path = "/res"
val parent_path = "/drawable-xhdpi-v4/"
val xx_path = "/drawable-xxhdpi-v4/"
val color_path = "/colors.xml"
val title_shitf_ic_lock = "sym_keyboard_shift_locked.png"
val title_bg = "keyboard_background.jpg"
val title_color = "key_text_color_normal"
val title_nor_Bg_press = "btn_keyboard_key_normal_pressed.9.png"
val title_sp_Bg = "btn_keyboard_spacekey_normal_normal.9.png"
val title_sp_Bg_press = "btn_keyboard_spacekey_normal_pressed.9.png"
val preview_bg="keyboard_preview_screenshot.jpg"
const val KEY_POS: String = "key_pos"
const val KEYTheme = "key_theme"
}

View File

@ -0,0 +1,44 @@
package com.keyboard.theme.app.keyboard.utils
import android.content.Context
import android.content.Intent
import android.provider.Settings
import android.view.inputmethod.InputMethodInfo
import android.view.inputmethod.InputMethodManager
import com.keyboard.theme.app.keyboard.MyAppllication
object StepManager {
val inputMan =
MyAppllication.instance.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
fun onsetInput(): Boolean {
MyAppllication.instance.run {
Settings.Secure.getString(contentResolver, Settings.Secure.DEFAULT_INPUT_METHOD)
?.let { id ->
return id.startsWith(packageName)
} ?: return false
}
}
fun toEnable(): Boolean {
for (info: InputMethodInfo in inputMan.enabledInputMethodList) {
if (info.id.startsWith(MyAppllication.instance.packageName)) {
return true
}
}
return false
}
fun toSet(context: Context) {
Intent(Settings.ACTION_INPUT_METHOD_SETTINGS).apply {
context.startActivity(this)
}
}
fun onSetEnab() {
inputMan.showInputMethodPicker()
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/skin_keyboard_color" android:state_selected="true"/>
<item android:color="@color/black" android:state_selected="false"/>
</selector>

View File

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:width="2dp" />
<solid android:color="@color/color1" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M15.207,5.293C15.598,5.683 15.598,6.317 15.207,6.707L9.914,12L15.207,17.293C15.598,17.683 15.598,18.317 15.207,18.707C14.817,19.098 14.183,19.098 13.793,18.707L7.793,12.707C7.402,12.317 7.402,11.683 7.793,11.293L13.793,5.293C14.183,4.902 14.817,4.902 15.207,5.293Z"
android:fillColor="#000000"
android:fillType="evenOdd"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="18dp"
android:viewportWidth="18"
android:viewportHeight="18">
<path
android:pathData="M6.595,3.97C6.302,4.263 6.302,4.737 6.595,5.03L10.564,9L6.595,12.97C6.302,13.263 6.302,13.737 6.595,14.03C6.888,14.323 7.362,14.323 7.655,14.03L12.155,9.53C12.448,9.237 12.448,8.763 12.155,8.47L7.655,3.97C7.362,3.677 6.888,3.677 6.595,3.97Z"
android:fillColor="#000000"
android:fillType="evenOdd"/>
</vector>

View File

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

View File

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

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M830.3,170.3H437.6A178.3,178.3 0,0 0,310.7 223L58.2,475.3a61.5,61.5 0,0 0,0 86.9l252.3,252.3a178.3,178.3 0,0 0,127.1 52.7h392.7A152.9,152.9 0,0 0,983 714.5V323a152.9,152.9 0,0 0,-152.7 -152.7zM760.2,628.8a25.6,25.6 0,0 1,-36.1 36.1L614.1,554.8 504,664.9a25.6,25.6 0,1 1,-36.1 -36.1L578,518.7 467.9,408.5A25.6,25.6 0,1 1,504 372.4l110.1,110.3L724.1,372.4a25.6,25.6 0,0 1,36.1 0,25.6 25.6,0 0,1 0,36.3L650.1,518.7z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M459.7,155.7l-5.5,4.1 -2.4,2 -3.8,3.5 -2.2,2.2 -3.5,3.8 -258.1,305.9 -4.2,5.4c-28.1,40.2 -20.7,93.3 16,123.6l5.9,4.4 3,2 4.9,2.9 5.6,2.8c13,6.1 26.2,8.9 39.5,8.9l58.6,-0 0,142.6 0.2,6.1c4,48.9 44,85.3 91.9,85.3h212.4l6.1,-0.2 2.7,-0.2 4.8,-0.6 4.7,-0.9c43.4,-9.4 73.7,-46.3 73.7,-89.5l-0,-142.6h58.8l6.1,-0.2c35.6,-2.9 65.4,-24.3 78.7,-55.7a90.9,90.9 0,0 0,-14.2 -94.1L582.4,172.4l-4.6,-5 -1.1,-1.1a92.6,92.6 0,0 0,-117.1 -10.6zM525.3,213.9l2.1,1.8 2.7,2.9 255.9,303.5a21,21 0,0 1,3.4 21.9,22.2 22.2,0 0,1 -18.7,13.3l-3.3,0.1 -127.1,-0v212.4l-0.2,2.6a21.9,21.9 0,0 1,-18.3 18.7l-1.5,0.2 -3.7,0.2L405.6,791.3a22,22 0,0 1,-22.2 -19.9l-0.1,-3.2v-210.9h-128.5l-2.8,-0.2a22.8,22.8 0,0 1,-8 -2.5l-1.7,-1 -3.3,-2.4c-7.4,-6.1 -9.1,-18.4 -2.7,-27.5l2.2,-2.9L494.6,217.4l1.4,-1.5 1.5,-1.3 2.9,-2.2c6.8,-4.6 17.3,-4.1 24.9,1.5z"
android:fillColor="#FFFFFF"/>
</vector>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/gray_bg"/>
<item android:state_selected="false" android:drawable="@drawable/shape_main"/>
</selector>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:topRightRadius="10dp" android:topLeftRadius="10dp"/>
<solid android:color="@color/white"/>
</shape>

View File

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

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/home_more_color"/>
</shape>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="10dp"/>
<gradient
android:centerColor="@color/color1"
android:endColor="@color/color2"
android:startColor="@color/color3" />
</shape>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="10dp" />
<solid android:color="@color/wel_pb_bg" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="10dp" />
<gradient
android:angle="0"
android:centerColor="@color/color1"
android:endColor="@color/color1"
android:startColor="@color/color1" />
</shape>
</clip>
</item>
</layer-list>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape android:shape="rectangle">
<solid android:color="@color/white"/>
<corners android:radius="5dp"/>
</shape>
</item>
<item android:state_pressed="false">
<shape android:shape="rectangle">
<solid android:color="@color/white"/>
<corners android:radius="5dp"/>
</shape>
</item>
</selector>

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="12dp"
android:paddingEnd="12dp"
tools:context=".ui.ActivityApply">
<ImageView
android:id="@+id/id_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:padding="10dp"
android:src="@drawable/direction_left" />
<TextView
android:id="@+id/id_theme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/id_back"
android:layout_alignBottom="@id/id_back"
android:layout_centerHorizontal="true"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="@string/text_app_name"
android:textColor="@color/black"
android:textSize="16sp" />
<ImageView
android:id="@+id/id_image"
android:layout_width="match_parent"
android:layout_height="260dp"
android:layout_below="@id/id_back"
android:layout_marginTop="25dp" />
<TextView
android:id="@+id/id_set"
android:layout_width="match_parent"
android:layout_height="43dp"
android:layout_below="@id/id_image"
android:layout_marginStart="15dp"
android:layout_marginTop="26dp"
android:layout_marginEnd="15dp"
android:background="@drawable/shape_main"
android:gravity="center"
android:text="@string/text_text_download_apply"
android:textColor="@color/black"
android:textSize="15sp" />
<ProgressBar
android:id="@+id/id_progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/id_set"
android:layout_centerHorizontal="true"
android:indeterminateTint="@color/color3"
android:visibility="gone" />
<ProgressBar
android:id="@+id/id_preloading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/id_image"
android:layout_alignBottom="@id/id_image"
android:layout_centerHorizontal="true"
android:indeterminateTint="@color/color1" />
</RelativeLayout>

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/page_color"
tools:context=".ui.ClassActivity">
<LinearLayout
android:id="@+id/imBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:padding="10dp"
android:src="@drawable/direction_left" />
<TextView
android:id="@+id/class_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:text="@string/text_app_name"
android:textColor="@color/black"
android:textSize="18sp" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/id_drawer"
android:background="@color/page_color"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="22dp"
android:layout_marginTop="30dp"
android:gravity="center"
android:paddingTop="10dp"
android:id="@+id/title"
android:text="@string/text_app_name"
android:textColor="@color/black"
android:textSize="18sp" />
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:id="@+id/category_recycler"
android:layout_below="@id/title"
android:layout_height="match_parent"/>
</RelativeLayout>

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?><!--<ScrollView 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:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- tools:context=".ui.SuccessActivity">-->
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/id_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:padding="10dp"
android:src="@drawable/direction_left" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/id_back"
android:layout_alignBottom="@id/id_back"
android:layout_centerHorizontal="true"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="@string/text_app_name"
android:textColor="@color/black"
android:textSize="16sp" />
<RelativeLayout
android:id="@+id/relayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/title">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black_view" />
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_marginStart="5dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="5dp"
android:background="@drawable/shape_et"
android:focusable="true"
android:focusableInTouchMode="true"
android:hint="@string/et_hint"
android:paddingStart="15dp"
android:textCursorDrawable="@drawable/cursor_color"
android:textColor="@color/test_color" />
</RelativeLayout>
</RelativeLayout>
<!--</ScrollView>-->

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/welcome_bg"
tools:context=".ui.ActivityLauncher">
<ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="6dp"
android:layout_marginStart="25dp"
android:layout_marginTop="120dp"
android:layout_marginEnd="25dp"
android:layout_marginBottom="40dp"
android:progress="10"
android:progressDrawable="@drawable/wel_progress_bar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="10dp"
app:cardElevation="0dp"
android:id="@+id/logo"
android:layout_marginTop="240dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="75dp"
android:layout_height="75dp"
android:src="@mipmap/logo" />
</androidx.cardview.widget.CardView>
<TextView
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="14dp"
android:gravity="center"
android:lineSpacingExtra="3dp"
android:text="@string/text_app_name"
android:textColor="@color/white"
android:textSize="20sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/logo" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="22dp"
android:layout_marginEnd="22dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:background="@drawable/shape_dialog_step"
android:paddingStart="12dp"
android:paddingEnd="12dp"
tools:context=".ui.ActivityStep">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:drawablePadding="5dp"
android:gravity="center"
android:lineSpacingExtra="5dp"
android:text="@string/text_more_feature"
android:textColor="@color/black"
android:textSize="17sp"
app:drawableStartCompat="@mipmap/smaile_left"
app:drawableEndCompat="@mipmap/smaile_right" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_marginTop="26dp"
android:orientation="horizontal"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingBottom="8dp">
<TextView
android:id="@+id/id_step1"
android:layout_width="0dp"
android:layout_height="43dp"
android:layout_weight="1"
android:background="@drawable/selector_key"
android:gravity="center"
android:text="@string/text_step1_select"
android:textColor="@color/black"
android:textSize="15sp" />
<TextView
android:id="@+id/id_step2"
android:layout_width="0dp"
android:layout_height="43dp"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:background="@drawable/selector_key"
android:gravity="center"
android:text="@string/text_step1_eanble"
android:textColor="@color/black"
android:textSize="15sp" />
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="vertical"
android:paddingStart="12dp"
android:paddingEnd="12dp">
<TextView
android:id="@+id/class_tile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="@string/text_rate"
android:textColor="@color/selector_text_color"
android:textSize="18sp" />
<FrameLayout
android:id="@+id/btn_more"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:paddingEnd="5dp"
android:paddingStart="5dp"
android:layout_alignTop="@id/class_tile"
android:layout_alignBottom="@id/class_tile"
android:layout_alignParentEnd="true">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="5dp"
android:background="@drawable/shape_home_more"
android:src="@drawable/direction_right" />
</FrameLayout>
<LinearLayout
android:id="@+id/layout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/class_tile"
android:orientation="horizontal">
<ImageView
android:id="@+id/preview1"
android:layout_width="wrap_content"
android:layout_height="120dp"
android:scaleType="fitXY"
android:layout_weight="1" />
<ImageView
android:id="@+id/preview2"
android:layout_width="wrap_content"
android:layout_height="120dp"
android:layout_marginStart="8dp"
android:scaleType="fitXY"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/layout1"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/preview3"
android:layout_width="wrap_content"
android:layout_height="120dp"
android:scaleType="fitXY"
android:layout_weight="1" />
<ImageView
android:id="@+id/preview4"
android:layout_width="wrap_content"
android:layout_height="120dp"
android:layout_marginStart="8dp"
android:scaleType="fitXY"
android:layout_weight="1" />
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/preview"
android:layout_width="match_parent"
android:layout_height="120dp"
android:scaleType="fitXY" />
</LinearLayout>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/id_thum"
android:layout_width="match_parent"
android:layout_height="130dp"
android:layout_marginEnd="12dp"
android:layout_marginTop="9dp"
android:scaleType="fitXY" />
</FrameLayout>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.keyboard.theme.app.keyboard.myservice.MyCustomView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/id_custom_input"
android:animateLayoutChanges="true"
android:focusable="true"
android:paddingTop="3dp"
android:paddingBottom="3dp"
android:focusableInTouchMode="true"
android:labelTextSize="15sp"
android:keyTextSize="15sp"
android:keyBackground="@drawable/white_background"/>
</FrameLayout>

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 KiB

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- <color name="purple_200">#FFBB86FC</color>-->
<!-- <color name="purple_500">#FF6200EE</color>-->
<!-- <color name="purple_700">#FF3700B3</color>-->
<!-- <color name="teal_200">#FF03DAC5</color>-->
<!-- <color name="teal_700">#FF018786</color>-->
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="skin_keyboard_color">#F98736</color>
<!-- <color name="hint_text_color">#FF4500</color>-->
<color name="set_step_complete">#DCDCDC</color>
<color name="wel_pb_bg">#ACA8A8</color>
<!-- <color name="wel_pb_bg1">#FFABAB</color>-->
<!-- <color name="wel_pb_bg2">#F15A5A</color>-->
<color name="home_more_color">#E1D9EB</color>
<color name="page_color">#Efebf4</color>
<color name="black_view">#66000000</color>
<color name="test_color">#0D082C</color>
<color name="color1">#f2c3eb</color>
<color name="color2">#fdfcf1</color>
<color name="color3">#ccebec</color>
<!-- <color name="text_color">#ABC2D3</color>-->
</resources>

View File

@ -0,0 +1,19 @@
<resources>
<string name="text_app_name">Keyboard Themes</string>
<!-- <string name="text_setting">setting</string>-->
<string name="text_rate">Rate Us</string>
<!-- <string name="text_privacy">Privacy</string>-->
<!-- <string name="text_google_link">https://play.google.com/store/apps/details?id=</string>-->
<string name="text_step1_select">Step 1: Select</string>
<string name="text_step1_eanble">Step 2: Enable</string>
<!-- <string name="text_set_succ">Skin application successful</string>-->
<string name="text_text_download_apply">Download &amp; Apply</string>
<string name="text_text_apply">Apply</string>
<string name="text_more_feature">Activate Keyboard Themes</string>
<!-- <string name="text_text_promote">For normal use, please enter the setting to complete the setting steps.</string>-->
<string name="text_succ_apply">Application successful</string>
<string name="text_fail_apply">Application failed, please try again</string>
<!-- <string name="text_welcome">Enter together Keyboard Themes</string>-->
<string name="et_hint">Type a Message</string>
</resources>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.KeyboardSkinApplication" parent="Theme.AppCompat.Light.NoActionBar" >
<item name="android:statusBarColor">@color/white</item>
</style>
</resources>

View File

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:verticalGap="3dp"
android:keyHeight="46dp">
<Row
android:keyWidth="9.45%"
android:keyHeight="46dp"
android:horizontalGap="0.5%"
android:rowEdgeFlags="top">
<Key
android:codes="113"
android:keyEdgeFlags="left"
android:keyLabel="q" />
<Key
android:codes="119"
android:keyLabel="w" />
<Key
android:codes="101"
android:keyLabel="e" />
<Key
android:codes="114"
android:keyLabel="r" />
<Key
android:codes="116"
android:keyLabel="t" />
<Key
android:codes="121"
android:keyLabel="y" />
<Key
android:codes="117"
android:keyLabel="u" />
<Key
android:codes="105"
android:keyLabel="i" />
<Key
android:codes="111"
android:keyLabel="o" />
<Key
android:codes="112"
android:keyEdgeFlags="right"
android:keyLabel="p" />
</Row>
<Row
android:keyWidth="9.444444%"
android:keyHeight="46dp"
android:horizontalGap="0.5%">
<Key
android:codes="97"
android:horizontalGap="5.5%"
android:keyLabel="a" />
<Key
android:codes="115"
android:keyLabel="s" />
<Key
android:codes="100"
android:keyLabel="d" />
<Key
android:codes="102"
android:keyLabel="f" />
<Key
android:codes="103"
android:keyLabel="g" />
<Key
android:codes="104"
android:keyLabel="h" />
<Key
android:codes="106"
android:keyLabel="j" />
<Key
android:codes="107"
android:keyLabel="k" />
<Key
android:codes="108"
android:keyLabel="l" />
</Row>
<Row
android:keyHeight="46dp"
android:keyWidth="9.5%"
android:horizontalGap="0.5%">
<!--shift-->
<Key
android:codes="-1"
android:isModifier="true"
android:isSticky="true"
android:keyWidth="14.25%"
android:keyEdgeFlags="left" />
<Key
android:codes="122"
android:keyLabel="z" />
<Key
android:codes="120"
android:keyLabel="x" />
<Key
android:codes="99"
android:keyLabel="c" />
<Key
android:codes="118"
android:keyLabel="v" />
<Key
android:codes="98"
android:keyLabel="b" />
<Key
android:codes="110"
android:keyLabel="n" />
<Key
android:codes="109"
android:keyLabel="m" />
<!--delete-->
<Key
android:codes="-5"
android:isModifier="true"
android:isRepeatable="true"
android:keyWidth="14.25%"
android:keyEdgeFlags="right" />
</Row>
<Row
android:horizontalGap="0.5%"
android:keyHeight="46dp"
android:rowEdgeFlags="bottom"
android:keyWidth="9.5%">
<!--mode change 切到模式2-->
<Key
android:codes="-2"
android:keyWidth="14.25%"
android:keyEdgeFlags="left"
android:keyLabel="\?123" />
<Key
android:codes="44"
android:keyLabel="," />
<Key
android:codes="32"
android:keyWidth="49.5%"
android:keyLabel="English" />
<Key
android:codes="46"
android:keyLabel="." />
<!--Done-->
<Key
android:codes="-4"
android:keyWidth="14.25%"
android:keyLabel="Done"
android:keyEdgeFlags="right" />
</Row>
</Keyboard>

View File

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:verticalGap="3dp">
<Row
android:keyWidth="9.45%"
android:keyHeight="46dp"
android:horizontalGap="0.5%"
android:rowEdgeFlags="top">
<Key
android:codes="49"
android:keyEdgeFlags="left"
android:keyLabel="1" />
<Key android:keyLabel="2"
android:codes="50"/>
<Key android:keyLabel="3"
android:codes="51"/>
<Key android:keyLabel="4"
android:codes="52"/>
<Key android:keyLabel="5"
android:codes="53"/>
<Key android:keyLabel="6"
android:codes="54"/>
<Key android:keyLabel="7"
android:codes="55"/>
<Key android:keyLabel="8"
android:codes="56"/>
<Key android:keyLabel="9"
android:codes="57"/>
<Key
android:keyEdgeFlags="right"
android:codes="48"
android:keyLabel="0" />
</Row>
<Row
android:keyWidth="9.444444%"
android:keyHeight="46dp"
android:horizontalGap="0.5%">
<Key
android:keyEdgeFlags="left"
android:keyLabel="\@"
android:horizontalGap="5.5%"
android:codes="64"/>
<Key android:keyLabel="#"
android:codes="35"/>
<Key android:keyLabel="\$"
android:codes="36"/>
<Key android:keyLabel="%"
android:codes="37"/>
<Key android:keyLabel="&amp;"
android:codes="38"/>
<Key android:keyLabel="-"
android:codes="45"/>
<Key android:keyLabel="+"
android:codes="43"/>
<Key android:keyLabel="("
android:codes="40"/>
<Key
android:keyEdgeFlags="right"
android:codes="41"
android:keyLabel=")" />
</Row>
<Row
android:keyHeight="46dp"
android:keyWidth="9.5%"
android:horizontalGap="0.5%">
<!--more 切换到符号键盘模式-->
<Key
android:codes="-300"
android:isModifier="true"
android:keyWidth="14.25%"
android:keyLabel="more"
android:keyEdgeFlags="left" />
<Key android:keyLabel="*"
android:codes="42" />
<!-- "-->
<Key android:keyLabel="&#034;"
android:codes="34" />
<Key android:keyLabel="'"
android:codes="39" />
<Key android:keyLabel=":"
android:codes="58" />
<Key android:keyLabel=";"
android:codes="59" />
<Key android:keyLabel="!"
android:codes="33" />
<Key android:keyLabel="\?"
android:codes="63" />
<!--delete-->
<Key
android:codes="-5"
android:keyWidth="14.25%"
android:isModifier="true"
android:isRepeatable="true"
android:keyEdgeFlags="right" />
</Row>
<Row
android:horizontalGap="0.5%"
android:keyHeight="46dp"
android:rowEdgeFlags="bottom"
android:keyWidth="9.5%">
<!-- 返回模式1 -->
<Key
android:codes="-2"
android:keyWidth="14.25%"
android:keyEdgeFlags="left"
android:keyLabel="ABC" />
<Key android:keyLabel=","
android:codes="44" />
<Key android:keyLabel="_"
android:codes="95" />
<Key
android:codes="32"
android:keyWidth="29.5%"
android:keyLabel="English" />
<Key android:keyLabel="/"
android:codes="47" />
<Key android:keyLabel="."
android:codes="46" />
<!--Done-->
<Key
android:codes="-4"
android:keyLabel="Done"
android:keyWidth="14.25%"
android:keyEdgeFlags="right" />
</Row>
</Keyboard>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older that API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>

View File

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:verticalGap="3dp">
<Row
android:keyWidth="9.45%"
android:keyHeight="46dp"
android:horizontalGap="0.5%"
android:rowEdgeFlags="top">
<Key
android:codes="126"
android:keyEdgeFlags="left"
android:keyLabel="~" />
<Key android:keyLabel="`"
android:codes="96"/>
<Key android:keyLabel="|"
android:codes="124"/>
<Key android:keyLabel="•"
android:codes="149"/>
<Key android:keyLabel="✔"
android:codes="10004"/>
<Key android:keyLabel="π"
android:codes="960"/>
<Key android:keyLabel="÷"
android:codes="247"/>
<Key android:keyLabel="×"
android:codes="215"/>
<Key android:keyLabel="¶"
android:codes="182"/>
<Key
android:keyEdgeFlags="right"
android:codes="8710"
android:keyLabel="∆" />
</Row>
<Row
android:keyWidth="9.444444%"
android:keyHeight="46dp"
android:horizontalGap="0.5%">
<Key
android:keyEdgeFlags="left"
android:keyLabel="£"
android:horizontalGap="5.5%"
android:codes="163"/>
<Key android:keyLabel="¢"
android:codes="65504"/>
<Key android:keyLabel="€"
android:codes="8364"/>
<Key android:keyLabel="¥"
android:codes="165"/>
<Key android:keyLabel="^"
android:codes="94"/>
<Key android:keyLabel="°"
android:codes="176"/>
<Key android:keyLabel="="
android:codes="61"/>
<Key android:keyLabel="{"
android:codes="123"/>
<Key
android:keyEdgeFlags="right"
android:codes="125"
android:keyLabel="}" />
</Row>
<Row
android:keyHeight="46dp"
android:keyWidth="9.5%"
android:horizontalGap="0.5%">
<!-- shift-->
<Key
android:codes="-301"
android:isModifier="true"
android:keyWidth="14.25%"
android:keyLabel="\?123"
android:keyEdgeFlags="left" />
<Key android:keyLabel="\\"
android:codes="92" />
<Key android:keyLabel="Ⓒ"
android:codes="9400" />
<Key android:keyLabel="®"
android:codes="174" />
<Key android:keyLabel="™"
android:codes="8482" />
<Key android:keyLabel="℅"
android:codes="8453" />
<Key android:keyLabel="["
android:codes="91" />
<Key android:keyLabel="]"
android:codes="93" />
<!--delete-->
<Key
android:codes="-5"
android:keyWidth="14.25%"
android:isModifier="true"
android:isRepeatable="true"
android:keyEdgeFlags="right" />
</Row>
<Row
android:horizontalGap="0.5%"
android:keyHeight="46dp"
android:rowEdgeFlags="bottom"
android:keyWidth="9.5%">
<!--mode change 回到模式1-->
<Key
android:codes="-2"
android:keyWidth="14.25%"
android:keyEdgeFlags="left"
android:keyLabel="ABC" />
<Key android:keyLabel=","
android:codes="46" />
<Key android:keyLabel="&lt;"
android:codes="60" />
<Key
android:codes="32"
android:keyWidth="29.5%"
android:keyLabel="English" />
<Key android:keyLabel="&gt;"
android:codes="62" />
<Key android:keyLabel="."
android:codes="46" />
<!--Done-->
<Key
android:codes="-4"
android:keyLabel="Done"
android:keyWidth="14.25%"
android:keyEdgeFlags="right" />
</Row>
</Keyboard>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample data extraction rules file; uncomment and customize as necessary.
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
for details.
-->
<data-extraction-rules>
<cloud-backup>
<!-- TODO: Use <include> and <exclude> to control what is backed up.
<include .../>
<exclude .../>
-->
</cloud-backup>
<!--
<device-transfer>
<include .../>
<exclude .../>
</device-transfer>
-->
</data-extraction-rules>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android">
<subtype
android:icon="@drawable/ic_launcher_background"
android:imeSubtypeLocale="en_US"
android:imeSubtypeMode = "keyboard"
android:label="@string/text_app_name" />
</input-method>

View File

@ -0,0 +1,17 @@
package com.keyboard.theme.app.keyboard
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)
}
}

7
build.gradle.kts Normal file
View File

@ -0,0 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application") version "8.1.3" apply false
id("org.jetbrains.kotlin.android") version "1.8.10" apply false
id("com.google.gms.google-services") version "4.3.15" apply false
id ("com.google.firebase.crashlytics") version "2.9.2" apply false
}

23
gradle.properties Normal file
View File

@ -0,0 +1,23 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,6 @@
#Tue Jan 30 11:08:41 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
gradlew vendored Normal file
View File

@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file
View File

@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

6
keystore.properties Normal file
View File

@ -0,0 +1,6 @@
app_name=Keyboard Themes
package_name=com.key.keyboard.theme.keyboardapp
keystoreFile=app/KeyboardThemes.jks
key_alias=KeyboardThemeskey0
key_store_password=KeyboardThemes
key_password=KeyboardThemes

19
settings.gradle.kts Normal file
View File

@ -0,0 +1,19 @@
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven("https://jitpack.io")
}
}
rootProject.name = "Keyboard Themes"
include(":app")