V1.0.0(1)

This commit is contained in:
litingting 2025-03-12 17:28:36 +08:00
commit 4a22189193
108 changed files with 10330 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/Versatilekeyboard.jks Normal file

Binary file not shown.

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

@ -0,0 +1,71 @@
import java.util.Date
import java.text.SimpleDateFormat
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("io.objectbox")
}
val timestamp = SimpleDateFormat("MM_dd_HH_mm").format(Date())
android {
namespace = "com.photo.keyboard.themes"
compileSdk = 34
defaultConfig {
//com.photo.keyboard.themes
applicationId = "com.photo.keyboard.themes"
minSdk = 23
targetSdk = 34
versionCode =1
versionName = "1.0.0"
setProperty("archivesBaseName", "Versatile keyboard_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_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
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")
implementation("com.github.omicronapps:7-Zip-JBinding-4Android:Release-16.02-2.02")
}

View File

@ -0,0 +1,57 @@
{
"_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.",
"_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.",
"_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
"entities": [
{
"id": "1:6597622615148802647",
"lastPropertyId": "6:4725819822394935315",
"name": "ThemeData",
"properties": [
{
"id": "1:3320077785000934058",
"name": "id",
"type": 6,
"flags": 1
},
{
"id": "2:5156279433272225632",
"name": "title",
"type": 9
},
{
"id": "3:2005999534028876786",
"name": "thumb",
"type": 9
},
{
"id": "4:2477186871953598949",
"name": "zipUrl",
"type": 9
},
{
"id": "5:7503354719257450298",
"name": "preview",
"type": 9
},
{
"id": "6:4725819822394935315",
"name": "resId",
"type": 9
}
],
"relations": []
}
],
"lastEntityId": "1:6597622615148802647",
"lastIndexId": "0:0",
"lastRelationId": "0:0",
"lastSequenceId": "0:0",
"modelVersion": 5,
"modelVersionParserMinimum": 5,
"retiredEntityUids": [],
"retiredIndexUids": [],
"retiredPropertyUids": [],
"retiredRelationUids": [],
"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.photo.keyboard.themes.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,63 @@
<?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="com.photo.keyboard.themes.App"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/logo"
android:label="@string/text_app_name"
android:roundIcon="@mipmap/logo"
android:supportsRtl="true"
android:theme="@style/Theme.KeyboardSkinApplication"
tools:targetApi="31">
<activity
android:name="com.photo.keyboard.themes.pager.LikeActivity"
android:exported="false" />
<activity
android:name="com.photo.keyboard.themes.pager.SuccessActivity"
android:exported="false"
android:screenOrientation="portrait" />
<activity
android:name="com.photo.keyboard.themes.pager.ClassActivity"
android:exported="false"
android:screenOrientation="portrait" />
<activity
android:name="com.photo.keyboard.themes.pager.WelcomeActivity"
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="com.photo.keyboard.themes.pager.SetThemesActivity"
android:exported="false"
android:screenOrientation="portrait" />
<service
android:name="com.photo.keyboard.themes.mykeyboard.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="com.photo.keyboard.themes.pager.MainActivity"
android:exported="false"
android:screenOrientation="portrait" />
</application>
</manifest>

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
package com.photo.keyboard.themes
import android.app.Application
import android.graphics.Typeface
import com.photo.keyboard.themes.data.Parent
import com.photo.keyboard.themes.manager.FileDeal
class App : Application() {
override fun onCreate() {
super.onCreate()
instance = this
FileDeal.getFileStr(assets.open("themes.json")) {
if (it != null) {
requireNotNull(it.isNotEmpty())
data = FileDeal.getDataBean(it)
}
}
font = Typeface.createFromAsset(assets, "myfont.ttf")
com.photo.keyboard.themes.manager.DbManager.init(this)
}
companion object {
var data: List<Parent> = mutableListOf()
lateinit var instance: App
lateinit var font: Typeface
}
}

View File

@ -0,0 +1,67 @@
package com.photo.keyboard.themes.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.photo.keyboard.themes.App
import com.photo.keyboard.themes.R
import com.photo.keyboard.themes.data.ThemeData
import com.photo.keyboard.themes.databinding.ItemClassBinding
import com.photo.keyboard.themes.listener.MainListener
import com.photo.keyboard.themes.manager.Utils
class ClassAdapter(
private var mContext: Context,
private var data: List<ThemeData> = emptyList()
) :
RecyclerView.Adapter<ClassAdapter.ClassHolder>() {
private lateinit var mListener: MainListener
fun updateData(newData: List<ThemeData>) {
data = newData
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ClassHolder {
val inflate = ItemClassBinding.inflate(LayoutInflater.from(mContext), parent, false)
return ClassHolder(inflate)
}
fun setListener(listener: MainListener) {
mListener = listener
}
override fun onBindViewHolder(holder: ClassHolder, position: Int) {
val infoChild = data[position]
holder.viewbing.run {
Glide.with(App.instance).load(infoChild.preview)
.transform(RoundedCorners(Utils.dpToUnitPx(10f)))
.placeholder(
ContextCompat.getDrawable(
App.instance,
R.mipmap.placholder
)
)
.into(preview)
preview.setOnClickListener {
mListener.onHomeClick(infoChild)
}
}
}
override fun getItemCount(): Int = data.size
inner class ClassHolder(var viewbing: ItemClassBinding) :
RecyclerView.ViewHolder(viewbing.root)
}

View File

@ -0,0 +1,95 @@
package com.photo.keyboard.themes.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.photo.keyboard.themes.R
import com.photo.keyboard.themes.data.Parent
import com.photo.keyboard.themes.databinding.ItemMainBinding
import com.photo.keyboard.themes.listener.MainListener
import com.photo.keyboard.themes.manager.Utils
class MainAdapter(var con: Context, var data: List<Parent>) :
RecyclerView.Adapter<MainAdapter.TabViewHolder>() {
private var old = -4
private var cur = 0
private lateinit var mListener: MainListener
inner class TabViewHolder(var viewbing: ItemMainBinding) :
RecyclerView.ViewHolder(viewbing.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TabViewHolder {
val inflate = ItemMainBinding.inflate(LayoutInflater.from(con), parent, false)
return TabViewHolder(inflate)
}
fun setListener(listener: MainListener) {
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 {
Utils.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(Utils.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,5 @@
package com.photo.keyboard.themes.data
class Parent(var className:String?= null, var list:List<ThemeData>? = null) {
}

View File

@ -0,0 +1,14 @@
package com.photo.keyboard.themes.data
import io.objectbox.annotation.Entity
import io.objectbox.annotation.Id
import java.io.Serializable
@Entity
class ThemeData(
@Id
var id: Long = 0,
var resId:String,
var title: String, var thumb: String, var zipUrl: String, var preview: String
) : Serializable {
}

View File

@ -0,0 +1,6 @@
package com.photo.keyboard.themes.listener;
public interface ApplyListener {
void applyListener(Boolean isSuccess,String str);
}

View File

@ -0,0 +1,11 @@
package com.photo.keyboard.themes.listener;
import com.photo.keyboard.themes.data.Parent;
import com.photo.keyboard.themes.data.ThemeData;
public interface MainListener {
void onHomeClick(ThemeData themeData);
default void onHomeClickMore(Parent parent){}
}

View File

@ -0,0 +1,41 @@
package com.photo.keyboard.themes.manager
object ConstValue {
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_bg_new = "keyboard_background.png"
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 KEYTheme = "key_theme"
}

View File

@ -0,0 +1,117 @@
package com.photo.keyboard.themes.manager;
import android.content.Context;
import com.photo.keyboard.themes.data.MyObjectBox;
import com.photo.keyboard.themes.data.ThemeData;
import com.photo.keyboard.themes.data.ThemeData_;
import java.util.List;
import io.objectbox.Box;
import io.objectbox.BoxStore;
import io.objectbox.query.QueryBuilder;
import io.objectbox.reactive.DataSubscription;
public class DbManager {
private static BoxStore boxStore;
private static Box<ThemeData> dataBox;
private static DataSubscription observer;
// private static List<OnUpdateListener> list = new ArrayList<>();
//
// public static void addOnAddOrRemoveListener(OnUpdateListener listener) {
// list.add(listener);
// }
public static void init(Context context) {
boxStore = MyObjectBox.builder().androidContext(context).build();
}
public static Box<ThemeData> getObjectBox() {
if (dataBox == null) {
dataBox = boxStore.boxFor(ThemeData.class);
}
return dataBox;
}
// public static DataSubscription setLikeDataListener(OnLikeListener listener) {
// Query<ThemeData> build = getObjectBox().query()
// .build();
// return build.subscribe(new DataSubscriptionList())
// .on(AndroidScheduler.mainThread())
// .observer(new DataObserver<List<ThemeData>>() {
// @Override
// public void onData(@NonNull List<ThemeData> data) {
// listener.onLikeList(data);
// }
// });
//
// }
public static void addLike(ThemeData boxLike) {
Box<ThemeData> objectBoxLike = getObjectBox();
String imId = boxLike.getResId();
ThemeData first = objectBoxLike.query()
.equal(ThemeData_.resId, imId, QueryBuilder.StringOrder.CASE_SENSITIVE)
.build()
.findFirst();
if (first == null) {
objectBoxLike.put(boxLike);
// for (OnUpdateListener listener : list) {
// listener.onAdd(boxLike);
// }
}
}
public static void deleteLike(ThemeData likeData) {
Box<ThemeData> objectBoxLike = getObjectBox();
String imId = likeData.getResId();
ThemeData boxLike = objectBoxLike.query()
.equal(ThemeData_.resId, imId, QueryBuilder.StringOrder.CASE_SENSITIVE)
.build()
.findFirst();
if (boxLike != null) {
objectBoxLike.remove(boxLike);
// for (OnUpdateListener listener : list) {
// listener.onRemove(boxLike);
// }
}
}
public static boolean queryIsLike(String resId) {
Box<ThemeData> objectBoxLike = getObjectBox();
ThemeData first = objectBoxLike.query()
.equal(ThemeData_.resId, resId, QueryBuilder.StringOrder.CASE_SENSITIVE)
.build()
.findFirst();
if (first != null) {
return true;
} else return false;
}
public static List<ThemeData> searchAllLike() {
Box<ThemeData> objectBoxLike = getObjectBox();
List<ThemeData> data = objectBoxLike.query()
.build()
.find();
return data;
}
}

View File

@ -0,0 +1,44 @@
package com.photo.keyboard.themes.manager
import android.content.Context
import android.content.Intent
import android.provider.Settings
import android.view.inputmethod.InputMethodInfo
import android.view.inputmethod.InputMethodManager
import com.photo.keyboard.themes.App
object EnableActive {
val inputMan =
App.instance.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
fun onsetInput(): Boolean {
App.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(App.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,213 @@
package com.photo.keyboard.themes.manager
import android.content.Context
import android.util.Log
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.photo.keyboard.themes.App
import com.photo.keyboard.themes.data.Parent
import com.photo.keyboard.themes.data.ThemeData
import com.photo.keyboard.themes.listener.ApplyListener
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 FileDeal {
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<Parent> {
var skinList = mutableListOf<Parent>()
JSONArray(str).let {
for (i in 0 until it.length()) {
it.getJSONObject(i).apply {
val name = getString("className")
var skin = mutableListOf<ThemeData>()
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")
val lastIndexOf = mzipUrl.lastIndexOf("/")
val substring = mzipUrl.substring(lastIndexOf+1, mzipUrl.length - 3)
Log.d("--TAG--","-------------substring=${substring}")
skin.add(
ThemeData(
resId = substring,
title = mtitle,
thumb = mthumb,
zipUrl = mzipUrl,
preview = mpreview
)
)
}
}
}
skinList.add(Parent(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: ApplyListener) {
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: ApplyListener
) {
val zipPath = "${App.instance.cacheDir}/${title}_ZIP"
val unPath = "${App.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.photo.keyboard.themes.manager;
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,94 @@
package com.photo.keyboard.themes.manager
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.photo.keyboard.themes.App
import java.io.File
object Utils {
fun dpToUnitPx(dp: Float): Int {
val scale = App.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 = App.instance.getSharedPreferences(
ConstValue.SHARE_NAME,
Context.MODE_PRIVATE
)
private val edit = sp.edit()
fun putCurPath(path: String) {
edit.run {
putString(ConstValue.KEY_ALL_PATH, path)
apply()
}
}
fun getCurPath(): String? {
return sp.getString(ConstValue.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 = App.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,200 @@
package com.photo.keyboard.themes.mykeyboard
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.photo.keyboard.themes.R
import com.photo.keyboard.themes.databinding.ViewKeyboradBinding
import com.photo.keyboard.themes.manager.ConstValue
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 = ConstValue.xml0
keyboard = Keyboard(mContext, views[0])
}
2 -> {
xmlMode = ConstValue.xml2
keyboard = Keyboard(mContext, views[2])
}
1 -> {
xmlMode = ConstValue.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) {
ConstValue.Shift_S -> {
shift_status = if (mouble) {
ConstValue.Shift_B_lo
} else {
ConstValue.Shift_B
}
keySB(true, myKeyboard)
keyboard = myKeyboard
}
ConstValue.Shift_B_lo -> {
shift_status = ConstValue.Shift_S
keySB(false, myKeyboard)
keyboard = myKeyboard
}
ConstValue.Shift_B -> {
shift_status = if (mouble) {
ConstValue.Shift_B_lo
} else {
keySB(false, myKeyboard)
ConstValue.Shift_S
}
keyboard = myKeyboard
}
}
}
}
Keyboard.KEYCODE_DONE -> {
currentInputConnection.performEditorAction(EditorInfo.IME_ACTION_DONE)
}
Keyboard.KEYCODE_MODE_CHANGE -> {
viewBinding.idCustomInput.run {
if (xmlMode == ConstValue.xml0) {
changeXml(1)
} else {
changeXml(0)
}
}
}
ConstValue.SHIFT_NUMBER -> {
changeXml(2)
}
Keyboard.KEYCODE_DELETE -> {
currentInputConnection.deleteSurroundingText(1, 0)
}
ConstValue.SHIFT_SYMBOL -> {
changeXml(1)
}
else -> {
currentInputConnection.commitText(primaryCode.toChar().toString(), 1)
viewBinding.idCustomInput.keyboard = viewBinding.idCustomInput.apply {
if (shift_status == ConstValue.Shift_B) {
shift_status = ConstValue.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,186 @@
package com.photo.keyboard.themes.mykeyboard
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.util.Xml
import androidx.core.content.ContextCompat
import com.photo.keyboard.themes.App
import com.photo.keyboard.themes.R
import com.photo.keyboard.themes.manager.ConstValue
import com.photo.keyboard.themes.manager.Utils
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(App.instance, R.drawable.im_shift)
var icDel: Drawable? =
ContextCompat.getDrawable(App.instance, R.drawable.im_del)
var allBg: Drawable? =
ContextCompat.getDrawable(App.instance, R.mipmap.bg)
var icBshift: Drawable? =
ContextCompat.getDrawable(App.instance, R.drawable.im_shift)
var keycolor: Int = App.instance.resources.getColor(R.color.white, null)
var icSshift: Drawable? =
ContextCompat.getDrawable(App.instance, R.drawable.im_shift)
init {
val default =
ContextCompat.getDrawable(App.instance, R.drawable.default_keybg)
val press = ContextCompat.getDrawable(
App.instance,
R.drawable.default_keybg_press
)
if (press != null) {
if (default != null) {
val listDrawable = Utils.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 == ConstValue.title_color) {
keycolor = Color.parseColor(xmlP.nextText())
}
}
eventT = xmlP.next()
}
}
fun uodateConfig(con: Context) {
Utils.getCurPath()?.let {
Utils.getbgic(
con,
it.plus(ConstValue.parent_path).plus(ConstValue.title_nor_Bg)
)?.let { drawBG ->
Utils.getbgic(
con,
it.plus(ConstValue.parent_path).plus(ConstValue.title_nor_Bg_press)
)?.let { drawPressBG ->
normalBackgroundDraw = Utils.getStatus(drawBG, drawPressBG)
}
}
gettextcolor(it.plus(ConstValue.color_path))
Utils.getbgic(con, it.plus(ConstValue.parent_path).plus(ConstValue.title_sp_Bg))
?.let { drawBG ->
Utils.getbgic(
con,
it.plus(ConstValue.parent_path).plus(ConstValue.title_sp_Bg_press)
)?.let { drawPressBG ->
spBackgroundDraw = Utils.getStatus(drawBG, drawPressBG)
}
}
Utils.getbgic(con, it.plus(ConstValue.xx_path).plus(ConstValue.title_bg))?.run {
allBg = this
}
Utils.getbgic(con, it.plus(ConstValue.xx_path).plus(ConstValue.title_bg_new))?.run {
allBg = this
}
Utils.getbgic(
con,
it.plus(ConstValue.parent_path).plus(ConstValue.title_fun_Bg)
)?.let { drawBG ->
Utils.getbgic(
con,
it.plus(ConstValue.parent_path).plus(ConstValue.title_func_bg_press)
)?.let { drawPressBG ->
functionBackgroundDraw = Utils.getStatus(drawBG, drawPressBG)
}
}
Utils.getbgic(con, it.plus(ConstValue.parent_path).plus(ConstValue.title_shitf_ic))?.let {
icSshift = it
icBshift = it
}
Utils.getbgic(
con,
it.plus(ConstValue.parent_path).plus(ConstValue.title_del_ic)
)?.let { drawBG ->
icDel = Utils.getStatus(drawBG, drawBG)
}
Utils.getbgic(
con,
it.plus(ConstValue.parent_path).plus(ConstValue.title_shitf_ic_lock)
)?.let {
icShittLock = it
}
}
}
fun getConfigBg(contetx:Context,name: String): Drawable? {
Utils.getCurPath()?.let { resPath ->
val pPath = "${resPath}/drawable-xhdpi-v4/"
return Utils.getbgic(
contetx,
pPath + name
)
}
return null
}
fun getConfig(): com.photo.keyboard.themes.resconfig.KeyboardConfig? {
val skinPath = Utils.getCurPath()
val substringBefore = skinPath?.substringBefore("res")
val configFilePath = substringBefore + "assets/keyboard.conf"
val file = File(configFilePath)
return if (file.exists()) {
com.photo.keyboard.themes.resconfig.KeyboardConfigParser.initConfig(configFilePath)
} else {
null
}
}
}

View File

@ -0,0 +1,252 @@
package com.photo.keyboard.themes.mykeyboard
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 android.util.Log
import com.photo.keyboard.themes.manager.Utils
import com.photo.keyboard.themes.manager.ConstValue
@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 = ConstValue.Shift_S
var xmlMode = ConstValue.xml0
private var mPaint: Paint = Paint().apply {
isAntiAlias = true
textAlign = Paint.Align.CENTER
textSize = Utils.spToUnitPx(16f, mContext)
color = keyBoardManager.keycolor
}
override fun onDraw(canvas: Canvas) {
val config: com.photo.keyboard.themes.resconfig.KeyboardConfig? = keyBoardManager.getConfig()
var keys: List<com.photo.keyboard.themes.resconfig.Key> = ArrayList<com.photo.keyboard.themes.resconfig.Key>()
var i = 0
for (curKey in keyboard.keys) {
val code = curKey.codes[0]
if (config != null) {
if (code == 113 || code == 81 || code == 49 || code == 126) {
i = 0
val keyboardLayout: com.photo.keyboard.themes.resconfig.KeyboardLayout = config.getLayouts().get(0)
keys = keyboardLayout.getKeys()
} else if (code == 97 || code == 65 || code == 64 || code == 163) {
i = 0
val keyboardLayout: com.photo.keyboard.themes.resconfig.KeyboardLayout = config.getLayouts().get(1)
keys = keyboardLayout.getKeys()
} else if (code == -1 || code == -300 || code == -301) {
i = 0
val keyboardLayout: com.photo.keyboard.themes.resconfig.KeyboardLayout = config.getLayouts().get(2)
keys = keyboardLayout.getKeys()
} else if (code == -2 || code == -102) {
i = 0
val keyboardLayout: com.photo.keyboard.themes.resconfig.KeyboardLayout = config.getLayouts().get(3)
keys = keyboardLayout.getKeys()
}
var background: String = keys[i].background + ".9.png"
i++
if (code == 32) {
config.keyList.forEach {
if(it.name.equals("KeySpace")){
background = "${it.background}.9.png"
}
}
}
Log.d("----TAG----", "-----code=${code}---background=${background}")
val configBg: Drawable? = keyBoardManager.getConfigBg(mContext, background)
if (configBg != null) {
Log.d("----TAG----", "--------background=1")
drawKeySuperTheme(configBg, canvas, code, curKey)
} else {
drawKey(canvas, code, curKey)
}
} else {
drawKey(canvas, code, curKey)
}
}
}
private fun drawKeySuperTheme(bgdraw: Drawable, canvas: Canvas, code: Int, key: Keyboard.Key) {
key.let {
when (code) {
Keyboard.KEYCODE_SHIFT -> {
andDraw(
it,
bgdraw,
getCurIc(),
canvas
)
}
ConstValue.SHIFT_NUMBER, ConstValue.SHIFT_SYMBOL -> {
andDraw(it, bgdraw, null, canvas)
}
Keyboard.KEYCODE_DELETE -> {
andDraw(
it,
bgdraw,
keyBoardManager.icDel,
canvas
)
}
Keyboard.KEYCODE_MODE_CHANGE, Keyboard.KEYCODE_DONE -> {
andDraw(it, bgdraw, null, canvas)
}
else -> {
andDraw(it, bgdraw, null, canvas)
}
}
}
}
private fun drawKey(canvas: Canvas, code: Int, key: Keyboard.Key) {
key.let {
when (code) {
32->{
andDraw(it, keyBoardManager.spBackgroundDraw, null, canvas)
}
Keyboard.KEYCODE_SHIFT -> {
andDraw(
it,
keyBoardManager.functionBackgroundDraw,
getCurIc(),
canvas
)
}
ConstValue.SHIFT_NUMBER, ConstValue.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) {
ConstValue.Shift_B_lo -> keyBoardManager.icShittLock
ConstValue.Shift_B -> keyBoardManager.icBshift
ConstValue.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,22 @@
package com.photo.keyboard.themes.pager
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,87 @@
package com.photo.keyboard.themes.pager;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import com.photo.keyboard.themes.App;
import com.photo.keyboard.themes.adapter.ClassAdapter;
import com.photo.keyboard.themes.databinding.ActivityClassBinding;
import com.photo.keyboard.themes.listener.MainListener;
import com.photo.keyboard.themes.data.Parent;
import com.photo.keyboard.themes.data.ThemeData;
import com.photo.keyboard.themes.manager.Utils;
import com.photo.keyboard.themes.manager.ItemSpace;
import com.photo.keyboard.themes.manager.ConstValue;
import java.util.List;
import java.util.Objects;
public class ClassActivity extends BaseActivity<ActivityClassBinding> implements MainListener {
public static final String KEY = "KEY_class_name";
private ActivityClassBinding binding;
private Parent classParent;
@NonNull
@Override
public ActivityClassBinding returnViewbinding() {
Utils.INSTANCE.initFull(this, false);
return ActivityClassBinding.inflate(getLayoutInflater());
}
@Override
public void onInit() {
binding = getVb();
String className = getIntent().getStringExtra(KEY);
Utils.INSTANCE.setFont(binding.classTitle);
binding.classTitle.setText(className);
for (Parent datum : App.Companion.getData()) {
if(Objects.equals(datum.getClassName(), className)){
classParent = 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<ThemeData> list = classParent.getList();
if(list == null){
return;
}
ClassAdapter ClassAdapter = new ClassAdapter(this, list);
ClassAdapter.setListener(this);
ItemSpace itemSpace = new ItemSpace(Utils.INSTANCE.dpToUnitPx(8), Utils.INSTANCE.dpToUnitPx(8), Utils.INSTANCE.dpToUnitPx(8));
GridLayoutManager gridLayoutManager =
new GridLayoutManager(this, 2);
binding.recycler.setLayoutManager(gridLayoutManager);
binding.recycler.setAdapter(ClassAdapter);
binding.recycler.addItemDecoration(itemSpace);
// ClassAdapter.setListener(this);
}
@Override
public void onHomeClick(ThemeData themeData) {
Intent setIntent = new Intent(this, SetThemesActivity.class);
setIntent.putExtra(ConstValue.KEYTheme, themeData);
startActivity(setIntent);
}
}

View File

@ -0,0 +1,115 @@
package com.photo.keyboard.themes.pager;
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.photo.keyboard.themes.databinding.DialogEnableBinding;
import com.photo.keyboard.themes.manager.EnableActive;
public class DialogEnable extends DialogFragment implements View.OnClickListener {
private BroadcastReceiver receiver;
private DialogEnableBinding binding;
private Context context;
@Override
public void onClick(View v) {
if (v.equals(binding.idStep2)) {
EnableActive.INSTANCE.onSetEnab();
} else if (v.equals(binding.idStep1)) {
EnableActive.INSTANCE.toSet(context);
}
}
public DialogEnable(Context context) {
this.context = context;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = DialogEnableBinding.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(EnableActive.INSTANCE.toEnable());
binding.idStep2.setSelected(EnableActive.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,94 @@
package com.photo.keyboard.themes.pager;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import android.content.Intent;
import android.view.View;
import com.photo.keyboard.themes.adapter.ClassAdapter;
import com.photo.keyboard.themes.databinding.ActivityLikeBinding;
import com.photo.keyboard.themes.listener.MainListener;
import com.photo.keyboard.themes.data.ThemeData;
import com.photo.keyboard.themes.manager.Utils;
import com.photo.keyboard.themes.manager.DbManager;
import com.photo.keyboard.themes.manager.ItemSpace;
import com.photo.keyboard.themes.manager.ConstValue;
import java.util.List;
public class LikeActivity extends BaseActivity<ActivityLikeBinding> implements View.OnClickListener, MainListener {
private ActivityLikeBinding bind;
private ClassAdapter ClassAdapter;
@NonNull
@Override
public ActivityLikeBinding returnViewbinding() {
Utils.INSTANCE.initFull(this, false);
return ActivityLikeBinding.inflate(getLayoutInflater());
}
@Override
public void onInit() {
bind = getVb();
Utils.INSTANCE.setFont(bind.idTheme);
bind.idBack.setOnClickListener(this);
update();
}
@Override
protected void onResume() {
super.onResume();
update();
}
private void update() {
bind.loadingPb.setVisibility(View.VISIBLE);
List<ThemeData> themeData = DbManager.searchAllLike();
if (themeData.size() == 0) {
bind.loadingPb.setVisibility(View.GONE);
bind.recycler.setVisibility(View.GONE);
bind.emptyLayout.setVisibility(View.VISIBLE);
} else {
initAdapter(themeData);
bind.loadingPb.setVisibility(View.GONE);
bind.recycler.setVisibility(View.VISIBLE);
bind.emptyLayout.setVisibility(View.GONE);
}
}
private void initAdapter(List<ThemeData> themeData) {
if (ClassAdapter == null) {
ClassAdapter = new ClassAdapter(this, themeData);
ClassAdapter.setListener(this);
ItemSpace itemSpace = new ItemSpace(Utils.INSTANCE.dpToUnitPx(8), Utils.INSTANCE.dpToUnitPx(8), Utils.INSTANCE.dpToUnitPx(8));
GridLayoutManager gridLayoutManager =
new GridLayoutManager(this, 2);
bind.recycler.setLayoutManager(gridLayoutManager);
bind.recycler.setAdapter(ClassAdapter);
bind.recycler.addItemDecoration(itemSpace);
}else {
ClassAdapter.updateData(themeData);
}
}
@Override
public void onClick(View v) {
if (v.equals(bind.idBack)) {
finish();
}
}
@Override
public void onHomeClick(ThemeData themeData) {
Intent setIntent = new Intent(this, SetThemesActivity.class);
setIntent.putExtra(ConstValue.KEYTheme, themeData);
startActivity(setIntent);
}
}

View File

@ -0,0 +1,112 @@
package com.photo.keyboard.themes.pager;
import android.content.Intent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.photo.keyboard.themes.App;
import com.photo.keyboard.themes.adapter.MainAdapter;
import com.photo.keyboard.themes.databinding.ActivityHomeBinding;
import com.photo.keyboard.themes.listener.MainListener;
import com.photo.keyboard.themes.data.Parent;
import com.photo.keyboard.themes.data.ThemeData;
import com.photo.keyboard.themes.manager.Utils;
import com.photo.keyboard.themes.manager.ConstValue;
import com.photo.keyboard.themes.manager.EnableActive;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MainActivity extends BaseActivity<ActivityHomeBinding> implements MainListener {
private MainAdapter mainAdapter;
private DialogEnable dialogStep;
private ActivityHomeBinding VB;
@NonNull
@Override
public ActivityHomeBinding returnViewbinding() {
Utils.INSTANCE.initFull(this, false);
return ActivityHomeBinding.inflate(getLayoutInflater());
}
@Override
public void onInit() {
VB = getVb();
checkPermission();
Utils.INSTANCE.setFont(VB.title);
initAdapter();
VB.imCollection.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent setIntent = new Intent(MainActivity.this, LikeActivity.class);
startActivity(setIntent);
}
});
}
private void initAdapter() {
List<Parent> tempList = new ArrayList<>();
List<Parent> data = App.Companion.getData();
for (Parent datum : data) {
Parent parent = new Parent();
List<ThemeData> list = datum.getList();
parent.setClassName(datum.getClassName());
Collections.shuffle(list);
List<ThemeData> themeData = list.subList(0, 4);
parent.setList(themeData);
tempList.add(parent);
}
mainAdapter = new MainAdapter(this, tempList);
LinearLayoutManager linearLayoutManager =
new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
VB.categoryRecycler.setLayoutManager(linearLayoutManager);
VB.categoryRecycler.setAdapter(mainAdapter);
mainAdapter.setListener(this);
}
@Override
public void onHomeClick(ThemeData themeData) {
Intent setIntent = new Intent(this, SetThemesActivity.class);
setIntent.putExtra(ConstValue.KEYTheme, themeData);
startActivity(setIntent);
}
@Override
public void onHomeClickMore(Parent parent) {
Intent setIntent = new Intent(this, ClassActivity.class);
setIntent.putExtra(ClassActivity.KEY, parent.getClassName());
startActivity(setIntent);
}
@Override
protected void onResume() {
super.onResume();
if(dialogStep!= null){
dialogStep.updateUi();
}
}
private void checkPermission(){
if (!EnableActive.INSTANCE.toEnable() || !EnableActive.INSTANCE.onsetInput()) {
if(dialogStep == null){
dialogStep = new DialogEnable(this);
}
if(!dialogStep.isAdded()){
dialogStep.show(getSupportFragmentManager(),"");
}
}
}
}

View File

@ -0,0 +1,183 @@
package com.photo.keyboard.themes.pager;
import static com.photo.keyboard.themes.manager.ConstValue.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.photo.keyboard.themes.App;
import com.photo.keyboard.themes.R;
import com.photo.keyboard.themes.data.ThemeData;
import com.photo.keyboard.themes.databinding.ActivitySetThemesBinding;
import com.photo.keyboard.themes.manager.ConstValue;
import com.photo.keyboard.themes.manager.DbManager;
import com.photo.keyboard.themes.manager.EnableActive;
import com.photo.keyboard.themes.manager.FileDeal;
import com.photo.keyboard.themes.manager.Utils;
import java.io.File;
public class SetThemesActivity extends BaseActivity<ActivitySetThemesBinding> implements View.OnClickListener {
private ThemeData themeData;
private String unZipPath;
private ActivitySetThemesBinding bind;
private DialogEnable dialogStep;
@NonNull
@Override
public ActivitySetThemesBinding returnViewbinding() {
Utils.INSTANCE.initFull(this, false);
return ActivitySetThemesBinding.inflate(getLayoutInflater());
}
@Override
public void onInit() {
bind = getVb();
Utils.INSTANCE.setFont(bind.idSet);
Utils.INSTANCE.setFont(bind.idTheme);
Intent intent = getIntent();
themeData = (ThemeData) intent.getSerializableExtra(KEYTheme);
File cacheDir = App.instance.getCacheDir();
String unZip = FileDeal.INSTANCE.getUnZip(themeData.getTitle());
unZipPath = cacheDir + "/" + unZip;
bind.idTheme.setText(themeData.getTitle());
bind.btnLike.setSelected(DbManager.queryIsLike(themeData.getResId()));
initText();
initListener();
loadPreview();
}
private void initListener() {
bind.idBack.setOnClickListener(this);
bind.idSet.setOnClickListener(this);
bind.btnLike.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(SetThemesActivity.this).load(themeData.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(Utils.INSTANCE.dpToUnitPx(10f)))
.into(bind.idImage);
}
@Override
protected void onResume() {
super.onResume();
if (dialogStep != null) {
dialogStep.updateUi();
}
}
private void onapply() {
if (!EnableActive.INSTANCE.toEnable() || !EnableActive.INSTANCE.onsetInput()) {
if (dialogStep == null) {
dialogStep = new DialogEnable(this);
}
if (!dialogStep.isAdded()) {
dialogStep.show(getSupportFragmentManager(), "");
}
return;
}
bind.idProgressbar.setVisibility(View.VISIBLE);
File file = new File(unZipPath);
if (file.exists()) {
String allThemePath = Utils.INSTANCE.getAllThemePath(themeData.getTitle());
if (allThemePath != null) {
Utils.INSTANCE.putCurPath(allThemePath);
}
bind.idProgressbar.setVisibility(View.GONE);
Toast.makeText(this, getString(R.string.text_succ_apply), Toast.LENGTH_LONG).show();
goSuccess();
finish();
} else {
FileDeal.INSTANCE.getZipData(themeData.getTitle(), themeData.getZipUrl(), this, this::onResult);
}
}
private void onResult(Boolean isSuccess, String path) {
bind.idProgressbar.setVisibility(View.GONE);
if (isSuccess) {
int lastIndexOf = path.lastIndexOf(ConstValue.INSTANCE.getRes_path());
String substring = path.subSequence(0, lastIndexOf + ConstValue.INSTANCE.getRes_path().length()).toString();
Utils.INSTANCE.putCurPath(substring);
Utils.INSTANCE.putAllThemePath(themeData.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, themeData.getTitle());
startActivity(intent);
}
@Override
public void onClick(View v) {
if (v.equals(bind.idBack)) {
finish();
} else if (v.equals(bind.idSet)) {
onapply();
} else if (v.equals(bind.btnLike)) {
bind.btnLike.setSelected(!bind.btnLike.isSelected());
if (bind.btnLike.isSelected()) {
DbManager.addLike(themeData);
} else {
DbManager.deleteLike(themeData);
}
}
}
}

View File

@ -0,0 +1,113 @@
package com.photo.keyboard.themes.pager;
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.photo.keyboard.themes.databinding.ActivitySuccessBinding;
import com.photo.keyboard.themes.manager.Utils;
import com.photo.keyboard.themes.manager.ConstValue;
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() {
Utils.INSTANCE.initFull(this, false);
return ActivitySuccessBinding.inflate(getLayoutInflater());
}
@Override
public void onInit() {
vb = getVb();
String stringExtra = getIntent().getStringExtra(key_name);
vb.title.setText(stringExtra);
Utils.INSTANCE.setFont(vb.title);
String curPath = Utils.INSTANCE.getCurPath();
vb.idBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
if (curPath == null) {
return;
}
String stringBuilder = curPath + ConstValue.INSTANCE.getXx_path() +
ConstValue.INSTANCE.getPreview_bg();
Drawable bgDraw = Utils.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,59 @@
package com.photo.keyboard.themes.pager;
import android.content.Intent;
import android.os.CountDownTimer;
import androidx.annotation.NonNull;
import com.photo.keyboard.themes.databinding.ActvityWelcomeBinding;
import com.photo.keyboard.themes.manager.Utils;
public class WelcomeActivity extends BaseActivity<ActvityWelcomeBinding> {
private long count = 2000L;
private CountDownTimer countDownTimer;
private ActvityWelcomeBinding binding;
@NonNull
@Override
public ActvityWelcomeBinding returnViewbinding() {
Utils.INSTANCE.initFull(this, true);
return ActvityWelcomeBinding.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,33 @@
package com.photo.keyboard.themes.resconfig;
// 按键对象模型
public class Key {
private String name;
private String background;
private String label;
public Key(String name) {
this.name = name;
}
// Getters and Setters
public String getName() {
return name;
}
public String getBackground() {
return background;
}
public void setBackground(String background) {
this.background = background;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}

View File

@ -0,0 +1,168 @@
package com.photo.keyboard.themes.resconfig;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
public class KeyboardConfig {
private String version;
private String supportLayouts;
private int hideHint;
private String layoutStyle;
private List<KeyboardLayout> layouts = new ArrayList<>();
private List<Key> keyList = new ArrayList<>();
private LinkedHashMap<String, String> maps = new LinkedHashMap<>();
private String KeyDefault;
private String KeyMarkDefault;
private String KeyFuncDefault;
private String KeyShift;
private String KeyDelete;
private String KeyAlphaSymbol;
private String KeyEmoji;
private String KeyMark;
private String KeySpace;
private String KeyEnter;
// Getters and Setters
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getSupportLayouts() {
return supportLayouts;
}
public void setSupportLayouts(String supportLayouts) {
this.supportLayouts = supportLayouts;
}
public int getHideHint() {
return hideHint;
}
public void setHideHint(int hideHint) {
this.hideHint = hideHint;
}
public String getLayoutStyle() {
return layoutStyle;
}
public void setLayoutStyle(String layoutStyle) {
this.layoutStyle = layoutStyle;
}
public List<KeyboardLayout> getLayouts() {
return layouts;
}
public void addLayout(KeyboardLayout layout) {
this.layouts.add(layout);
}
public List<Key> getKeyList() {
return keyList;
}
public Key getLastKeyList() {
return keyList.isEmpty() ? null : keyList.get(keyList.size() - 1);
}
public void addKey(Key key) {
this.keyList.add(key);
}
public LinkedHashMap<String, String> getMaps() {
return maps;
}
public void setMaps(LinkedHashMap<String, String> maps) {
this.maps = maps;
}
public String getKeyDefault() {
return KeyDefault;
}
public void setKeyDefault(String keyDefault) {
KeyDefault = keyDefault;
}
public String getKeyMarkDefault() {
return KeyMarkDefault;
}
public void setKeyMarkDefault(String keyMarkDefault) {
KeyMarkDefault = keyMarkDefault;
}
public String getKeyFuncDefault() {
return KeyFuncDefault;
}
public void setKeyFuncDefault(String keyFuncDefault) {
KeyFuncDefault = keyFuncDefault;
}
public String getKeyShift() {
return KeyShift;
}
public void setKeyShift(String keyShift) {
KeyShift = keyShift;
}
public String getKeyDelete() {
return KeyDelete;
}
public void setKeyDelete(String keyDelete) {
KeyDelete = keyDelete;
}
public String getKeyAlphaSymbol() {
return KeyAlphaSymbol;
}
public void setKeyAlphaSymbol(String keyAlphaSymbol) {
KeyAlphaSymbol = keyAlphaSymbol;
}
public String getKeyEmoji() {
return KeyEmoji;
}
public void setKeyEmoji(String keyEmoji) {
KeyEmoji = keyEmoji;
}
public String getKeyMark() {
return KeyMark;
}
public void setKeyMark(String keyMark) {
KeyMark = keyMark;
}
public String getKeySpace() {
return KeySpace;
}
public void setKeySpace(String keySpace) {
KeySpace = keySpace;
}
public String getKeyEnter() {
return KeyEnter;
}
public void setKeyEnter(String keyEnter) {
KeyEnter = keyEnter;
}
}

View File

@ -0,0 +1,126 @@
package com.photo.keyboard.themes.resconfig;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
public class KeyboardConfigParser {
public static KeyboardConfig initConfig(String path) {
String filePath = "keyboard.conf"; // 文件路径
KeyboardConfig config = parseConfig(path);
// System.out.println("Version: " + config.getVersion());
// System.out.println("SupportLayouts: " + config.getSupportLayouts());
// System.out.println("HideHint: " + config.getHideHint());
// System.out.println("LayoutStyle: " + config.getLayoutStyle());
//
// for (KeyboardLayout layout : config.getLayouts()) {
// System.out.println("\nLayout: " + layout.getName());
// for (Key key : layout.getKeys()) {
// System.out.println("Key: " + key.getName() + ", Background: " + key.getBackground() + ", Label: " + key.getLabel());
// }
// }
// for (Map.Entry<String, String> stringStringEntry : config.getMaps().entrySet()) {
// System.out.println("Map Key= " + stringStringEntry.getKey() + ", value= " + stringStringEntry.getValue());
// }
for (Key funcationKey : config.getKeyList()) {
System.out.println("Key: " + funcationKey.getName()+" Background= " + funcationKey.getBackground() + ", Label= " + funcationKey.getLabel());
}
return config;
}
public static KeyboardConfig parseConfig(String filePath) {
// InputStream open = AppThemes.appThemesInstance.getAssets().open(filePath);
KeyboardConfig config = new KeyboardConfig();
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
KeyboardLayout currentLayout = null;
while ((line = br.readLine()) != null) {
line = line.trim();
if (line.isEmpty()) {
continue; // 跳过空行
}
if (line.startsWith("Version:")) {
config.setVersion(line.split(":")[1].trim());
} else if (line.startsWith("SupportLayouts:")) {
config.setSupportLayouts(line.split(":")[1].trim());
} else if (line.startsWith("HideHint:")) {
config.setHideHint(Integer.parseInt(line.split(":")[1].trim()));
} else if (line.startsWith("LayoutStyle:")) {
config.setLayoutStyle(line.split(":")[1].trim());
} else if (line.equals("KeyDefault") || line.equals("KeyMarkDefault") || line.equals("KeyFuncDefault")) {
LinkedHashMap<String, String> maps = config.getMaps();
maps.put(line, "");
} else if (line.contains(":") && currentLayout == null) {
String[] parts = line.split(":");
String keyName = parts[0].trim();
String keyValue = parts[1].trim();
String latestKey = null;
LinkedHashMap<String, String> maps = config.getMaps();
for (Map.Entry<String, String> entry : maps.entrySet()) {
latestKey = entry.getKey();
}
if (latestKey != null) {
maps.put(latestKey, keyValue);
}
} else if (line.startsWith("Row")) {
currentLayout = new KeyboardLayout(line.split(":")[0].trim());
config.addLayout(currentLayout);
} else if (currentLayout != null) {
if (line.equals("Key")) {
String[] parts = line.split(":");
String keyName = parts[0].trim();
Key key = new Key(keyName);
currentLayout.addKey(key);
} else if (line.contains(":") && currentLayout.getLastKey().getBackground() == null) {
// 解析按键的其他属性 Label
String[] parts = line.split(":");
String keyName = parts[0].trim();
String keyValue = parts[1].trim();
Key key = currentLayout.getLastKey();
if (keyName.equals("Label")) {
key.setLabel(keyValue);
}
if (keyName.equals("Background")) {
key.setBackground(keyValue);
}
} else {
if (line.equals("KeyShift") || line.equals("KeyDelete") || line.equals("KeyAlphaSymbol") || line.equals("KeyEmoji")
|| line.equals("KeyMark")
|| line.equals("KeySpace")
|| line.equals("KeyEnter")) {
Key funcationKey = new Key(line);
config.addKey(funcationKey);
} else if (line.contains(":")) {
String[] parts = line.split(":");
String keyName = parts[0].trim();
String keyValue = parts[1].trim();
Key lastKey = config.getLastKeyList();
if (keyName.equals("Label")) {
lastKey.setLabel(keyValue);
}
if (keyName.equals("Background")) {
lastKey.setBackground(keyValue);
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return config;
}
}
// 配置文件对象模型
// 键盘布局对象模型

View File

@ -0,0 +1,35 @@
package com.photo.keyboard.themes.resconfig;
import java.util.ArrayList;
import java.util.List;
public class KeyboardLayout {
private String name;
private List<Key> keys = new ArrayList<>();
public KeyboardLayout(String name) {
this.name = name;
}
// Getters and Setters
public String getName() {
return name;
}
public List<Key> getKeys() {
return keys;
}
public void addKey(Key key) {
this.keys.add(key);
}
public Key getLastKey() {
return keys.isEmpty() ? null : keys.get(keys.size() - 1);
}
}

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/theme_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>

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>

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,39 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="72.7dp"
android:height="64dp"
android:viewportWidth="1163"
android:viewportHeight="1024">
<path
android:pathData="M1103.8,383.2h-15a15,15 0,0 0,0 30h15v15a15,15 0,0 0,30 0v-15h15a15,15 0,0 0,0 -30h-15v-15a15,15 0,0 0,-30 0v15z"
android:fillColor="#F4F4F4"/>
<path
android:pathData="M0,151.7a25.3,25.3 0,1 0,50.6 0,25.3 25.3,0 0,0 -50.6,0z"
android:fillColor="#F4F4F4"/>
<path
android:pathData="M970,763.9L839.8,455.1H310.6L180.4,763.9H177V1024h796.4V763.9z"
android:fillColor="#F8F8F8"/>
<path
android:pathData="M973.4,1024H177V763.9h3.4L310.6,455.1h529.1L970,763.9h2.5l0.9,7.3V1024h-0zM191.9,1009.4h766.6l-0.4,-235.3 -128.3,-304.3H320.6L191.9,774.9v234.5z"
android:fillColor="#CCCCCC"/>
<path
android:pathData="M309.8,657.4L189.6,1005.9l15.5,5.5 120.2,-348.5L309.8,657.4zM828,657.4L948.1,1005.9 932.7,1011.4 812.5,662.9 828,657.4z"
android:fillColor="#CCCCCC"/>
<path
android:pathData="M492.3,758.5H177v265.5h796.4V758.5H658.2a83,83 0,1 1,-165.9 0z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M973.4,1024H177V758.5h315l0.6,6.9c3.5,42.7 39.8,76.1 82.7,76.1 42.9,0 79.2,-33.4 82.7,-76.1l0.6,-6.9H973.4v265.5h-0zM191.9,1009.1h766.6V773.4H671.9c-7.2,47 -48.5,83 -96.7,83 -48.3,0 -89.5,-35.9 -96.8,-83H191.9V1009.1z"
android:fillColor="#CCCCCC"/>
<path
android:pathData="M303.4,455.1h531v227.6H303.4z"
android:fillColor="#F4F4F4"/>
<path
android:pathData="M834.4,682.7L303.4,682.7L303.4,455.1h531v227.6zM318.3,668L819.5,668L819.5,469.7L318.3,469.7v198.3z"
android:fillColor="#CCCCCC"/>
<path
android:pathData="M506.3,593.1c11,-5.9 21.9,-12.1 32.7,-18.4 4.3,-2.7 5.8,-8.6 3.4,-13.3 -2.4,-4.7 -7.8,-6.5 -12.2,-4.1 -10.3,6.1 -21.1,12.1 -32.2,18.1a9.9,9.9 0,0 0,-5 8.3,10.2 10.2,0 0,0 4.1,8.8 8.6,8.6 0,0 0,9.1 0.6zM570.3,555.1a764,764 0,0 0,32.3 -19.9,9 9,0 0,0 2.6,-12.8 9.6,9.6 0,0 0,-13.1 -2.5,754.3 754.3,0 0,1 -31.5,19.4 9.1,9.1 0,0 0,-3 12.5,9.6 9.6,0 0,0 12.7,3.3zM635.2,516.8a519,519 0,0 0,31.5 -21.8c4.1,-3.1 4.5,-8.4 0.8,-11.9 -3.7,-3.5 -10,-3.7 -14.1,-0.7a500.2,500.2 0,0 1,-30.3 20.9c-4.1,2.9 -4.8,8 -1.5,11.5 3.2,3.6 9.3,4.4 13.7,1.8zM684.7,477.2c7.9,-10.1 15.2,-20.8 22,-32 2.4,-4.5 1.4,-10.4 -2.3,-13.5 -3.7,-3.1 -8.7,-2.2 -11.5,1.9 -6.3,10.5 -13.2,20.5 -20.6,30a11.3,11.3 0,0 0,0.5 14.1c3.5,3.7 8.8,3.5 11.9,-0.6zM734.8,399.8c-1.9,4.2 -6.3,6 -9.9,3.9 -3.7,-2.1 -5.3,-7.2 -3.6,-11.6 4.3,-10.5 7.6,-21 9.9,-31.7 1.1,-4.6 5.2,-7.3 9.1,-6.2 3.9,1.2 6.4,5.9 5.5,10.6 -2.6,12 -6.3,23.8 -10.9,35zM745.9,332.3a80.2,80.2 0,0 0,-11.3 -37.8c-2.4,-4 -7.2,-5 -10.7,-2.2 -3.5,2.8 -4.3,8.3 -1.9,12.2 5,8.3 8,17.9 8.6,28.8 0.4,4.7 4,8.2 8.1,7.9 4.1,-0.3 7.3,-4.3 7.2,-9zM703,263.3a123.8,123.8 0,0 0,-35.6 -10.3,9.1 9.1,0 0,0 -8.1,2.8 7.2,7.2 0,0 0,-1.3 7.8c1.1,2.6 3.7,4.5 6.8,4.9 10.5,1.4 20.7,4.3 30.2,8.7 2.7,1.4 6.1,1.4 8.8,-0.1a7.6,7.6 0,0 0,4.1 -7.1,7.8 7.8,0 0,0 -4.9,-6.6zM621.6,253c-15.3,3.1 -28.3,9.8 -37.3,19.8a11.6,11.6 0,0 0,-2.5 10c0.7,3.6 3.1,6.5 6.1,7.6 3.1,1.1 6.4,0.1 8.7,-2.4 6.2,-6.8 16,-11.9 28.1,-14.4 4.9,-1 8.1,-6.4 7.3,-12.1 -0.9,-5.7 -5.5,-9.5 -10.4,-8.5zM581.9,315.4c3.3,11.3 10.4,23.1 21.3,35.5a9.3,9.3 0,0 0,13.1 0.8,9.4 9.4,0 0,0 0.8,-13.2c-9.2,-10.4 -14.9,-20 -17.4,-28.3a9.3,9.3 0,1 0,-15.6 -3.8,9.4 9.4,0 0,0 -2.2,9.1zM623.1,372.6a118.4,118.4 0,0 0,35.4 18.9c3.1,1 6.4,0.1 8.8,-2.5a11.3,11.3 0,0 0,2.5 -9.9c-0.8,-3.6 -3.2,-6.4 -6.3,-7.4a101.3,101.3 0,0 1,-30.2 -16.2c-4.1,-2.8 -9.5,-1.5 -12.2,3.1 -2.7,4.6 -1.7,10.8 2.1,14.1zM704.2,391.9a8.3,8.3 0,0 1,-7.5 -4.3,10.1 10.1,0 0,1 -0.4,-9.3 8.5,8.5 0,0 1,7.2 -5c10.6,-0.6 21.1,-2.7 31.3,-6.1a7.9,7.9 0,0 1,8.4 2c2.3,2.3 3.2,5.8 2.5,9.1a9,9 0,0 1,-6 6.8c-11.5,4 -23.4,6.3 -35.5,6.9zM785.3,378c11.4,-6 22.4,-12.8 32.9,-20.2a9.1,9.1 0,0 0,1.8 -12.6,9.5 9.5,0 0,0 -12.8,-2.4 276.6,276.6 0,0 1,-30.8 18.9,9.2 9.2,0 0,0 -5.2,7.9 9.2,9.2 0,0 0,4.5 8.3c2.9,1.7 6.6,1.8 9.6,0.1zM838.7,326.9a498.7,498.7 0,0 0,30.8 -22.6c3.8,-3.2 3.7,-8.2 -0.4,-11.3a12.7,12.7 0,0 0,-14.5 0c-9.5,7.5 -19.4,14.8 -29.6,21.7 -4.1,3 -4.4,7.9 -0.7,11.2 3.7,3.3 10.1,3.7 14.4,1zM887.1,287.6c7.5,-10.3 14.7,-20.9 21.6,-31.7 2.6,-4.4 1.8,-10.5 -1.9,-13.7 -3.7,-3.2 -8.9,-2.5 -11.8,1.7 -6.7,10.5 -13.7,20.7 -21,30.7 -2.8,4.2 -2.3,10.3 1.2,13.8 3.5,3.5 8.7,3.1 11.8,-0.8zM939.8,223.1a748.9,748.9 0,0 0,19.7 -31.9,9.5 9.5,0 0,0 0.1,-9.4 9.1,9.1 0,0 0,-7.8 -4.8,9.1 9.1,0 0,0 -8,4.6 740,740 0,0 1,-19.3 31.2,9.5 9.5,0 0,0 -0.9,9.5 9.1,9.1 0,0 0,7.8 5.3,9.1 9.1,0 0,0 8.2,-4.5zM976,159.6c3.2,-6.7 6.3,-13.5 9.4,-20.3 1.7,-4.4 0.1,-9.6 -3.8,-11.8 -3.9,-2.2 -8.6,-0.6 -10.7,3.6a795.9,795.9 0,0 1,-9.1 19.9c-2.1,4.4 -0.6,10 3.3,12.4 3.9,2.4 8.8,0.7 11,-3.7z"
android:fillColor="#CCCCCC"/>
<path
android:pathData="M651.1,88.5C626.7,88.5 606.8,68.6 606.8,44.2S626.7,0 651.1,0 695.3,19.8 695.3,44.2 675.5,88.5 651.1,88.5zM651.1,16.3A28,28 0,0 0,623.1 44.2c0,15.4 12.5,28 28,28A28,28 0,0 0,679.1 44.2,28 28,0 0,0 651.1,16.3z"
android:fillColor="#D8D8D8"/>
</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="16dp"/>
</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,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256.3dp"
android:height="256dp"
android:viewportWidth="1025"
android:viewportHeight="1024">
<path
android:pathData="M0,512a513,512 0,1 0,1026 0,513 512,0 1,0 -1026,0Z"
android:fillColor="@color/theme_color"/>
<path
android:pathData="M1024,563.4c-15.8,163.1 -108.5,303.8 -241.5,385.5 -8.8,-29.4 -13.6,-60.9 -13.6,-93.7 0,-160.2 114,-290.3 255,-291.8z"
android:strokeAlpha="0.3"
android:fillColor="#FFFFFF"
android:fillAlpha="0.3"/>
<path
android:pathData="M340,31.6c-26.6,134.4 -141,228 -262.9,211.6C137.8,146.3 230.3,71 340,31.6z"
android:fillColor="#FFFFFF"
android:fillAlpha="0.4"/>
<path
android:pathData="M635.8,731.4c-5,0 -10.7,-1.6 -15.6,-4.1l-107.1,-53.5 -107.9,53.5a32.8,32.8 0,0 1,-34.6 -2.5c-9.9,-7.4 -15.6,-20.6 -13.2,-32.9l22.2,-115.3 -84.8,-79a36.3,36.3 0,0 1,-9.1 -34.6c4.1,-12.4 14,-21.4 27.2,-23l117.7,-21.4 52.7,-107c5.7,-11.5 17.3,-18.9 29.6,-18.9 12.4,0 24.7,7.4 29.7,18.9l52.7,107 117.7,20.6c12.4,1.6 23,10.7 26.3,23.1 4.1,12.4 0.8,25.5 -8.2,34.6l-84.8,79.9 21.4,115.3c2.5,13.2 -3.3,25.5 -13.2,32.9a29.6,29.6 0,0 1,-18.9 6.6z"
android:fillColor="#FFFFFF"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="@color/unselected_Color"
android:pathData="M885.8,404.5c-5.1,-17.9 -23,-30.7 -41,-33.3l-186.9,-28.2 -81.9,-169c-7.7,-17.9 -25.6,-28.2 -46.1,-28.2s-38.4,10.2 -46.1,28.2l-81.9,169 -186.9,28.2c-17.9,2.6 -35.8,15.4 -41,33.3 -5.1,17.9 -2.6,38.4 12.8,51.2l135.7,135.7 -30.7,189.4c-2.6,17.9 5.1,38.4 20.5,48.6 7.7,5.1 20.5,10.2 30.7,10.2 7.7,0 17.9,-2.6 25.6,-5.1l163.8,-87 163.8,87c7.7,5.1 15.4,5.1 25.6,5.1s20.5,-2.6 30.7,-10.2c15.4,-10.2 25.6,-30.7 20.5,-48.6L742.4,591.4l135.7,-135.7c7.7,-12.8 12.8,-33.3 7.7,-51.2z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="@color/theme_color"
android:pathData="M885.8,404.5c-5.1,-17.9 -23,-30.7 -41,-33.3l-186.9,-28.2 -81.9,-169c-7.7,-17.9 -25.6,-28.2 -46.1,-28.2s-38.4,10.2 -46.1,28.2l-81.9,169 -186.9,28.2c-17.9,2.6 -35.8,15.4 -41,33.3 -5.1,17.9 -2.6,38.4 12.8,51.2l135.7,135.7 -30.7,189.4c-2.6,17.9 5.1,38.4 20.5,48.6 7.7,5.1 20.5,10.2 30.7,10.2 7.7,0 17.9,-2.6 25.6,-5.1l163.8,-87 163.8,87c7.7,5.1 15.4,5.1 25.6,5.1s20.5,-2.6 30.7,-10.2c15.4,-10.2 25.6,-30.7 20.5,-48.6L742.4,591.4l135.7,-135.7c7.7,-12.8 12.8,-33.3 7.7,-51.2z"/>
</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/icon_star_selected"/>
<item android:state_selected="false" android:drawable="@drawable/icon_star"/>
</selector>

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_16"/>
</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:radius="10dp"/>
<solid android:color="@color/top" />
</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: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/top"/>
</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">
<gradient
android:angle="45"
android:centerColor="@color/color2"
android:endColor="@color/color3"
android:startColor="@color/color1" />
</shape>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="16dp"/>
<gradient
android:angle="45"
android:centerColor="@color/color2"
android:endColor="@color/color3"
android:startColor="@color/color1" />
</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/sub_main"
android:endColor="@color/color1"
android:startColor="@color/sub_main" />
</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,41 @@
<?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:paddingTop="10dp"
android:background="@color/page_color"
tools:context="com.photo.keyboard.themes.pager.ClassActivity">
<RelativeLayout
android:id="@+id/imBack"
android:layout_width="match_parent"
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/black_direction_left" />
<TextView
android:id="@+id/class_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_centerHorizontal="true"
android:text="@string/text_app_name"
android:textColor="@color/black"
android:textSize="18sp" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@ -0,0 +1,47 @@
<?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"
android:id="@+id/id_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/page_color"
android:paddingTop="10dp"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_marginTop="30dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="22dp"
android:gravity="center"
android:text="@string/text_app_name"
android:textColor="@color/black"
android:textSize="18sp" />
<ImageView
android:id="@+id/im_collection"
android:layout_width="55dp"
android:layout_height="25dp"
android:layout_alignParentEnd="true"
android:layout_marginEnd="15dp"
android:gravity="end"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:src="@drawable/icon_collection" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/category_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/title" />
</LinearLayout>

View File

@ -0,0 +1,72 @@
<?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:background="@color/page_color"
android:paddingTop="10dp"
tools:context="com.photo.keyboard.themes.pager.LikeActivity">
<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/black_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/favorite"
android:textColor="@color/black"
android:textSize="18sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/id_theme" />
<ProgressBar
android:id="@+id/loading_pb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminateTint="@color/theme_color" />
<LinearLayout
android:id="@+id/empty_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:layout_width="95dp"
android:layout_height="95dp"
android:src="@drawable/empty_favorite" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="@string/empty_favorite"
android:textColor="@color/wel_pb_bg"
android:textSize="15sp" />
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,115 @@
<?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:background="@drawable/shape_main"
android:paddingStart="12dp"
android:paddingTop="10dp"
android:paddingEnd="12dp"
tools:context="com.photo.keyboard.themes.pager.SetThemesActivity">
<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/black_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" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/btn_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/id_image"
android:layout_marginTop="26dp"
android:gravity="center_horizontal"
android:orientation="horizontal">
<ProgressBar
android:id="@+id/id_progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="@color/color1"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="@id/id_set"
app:layout_constraintRight_toRightOf="@id/id_set"
app:layout_constraintTop_toTopOf="@id/id_set" />
<View
android:id="@+id/view1"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/id_set"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/id_set"
android:layout_width="180dp"
android:layout_height="43dp"
android:layout_marginEnd="15dp"
android:background="@drawable/shape_collection"
android:gravity="center"
android:text="@string/text_text_download_apply"
android:textColor="@color/black"
android:textSize="15sp"
app:layout_constraintLeft_toRightOf="@id/view1"
app:layout_constraintRight_toLeftOf="@id/btn_like"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/btn_like"
android:layout_width="43dp"
android:layout_height="43dp"
android:background="@drawable/shape_collection"
android:padding="5dp"
android:src="@drawable/selector_collection"
app:layout_constraintLeft_toRightOf="@id/id_set"
app:layout_constraintRight_toLeftOf="@id/view2"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view2"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@id/btn_like"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<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,70 @@
<?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:paddingTop="10dp"
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/black_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/bg_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="@color/wel_bg"
tools:context="com.photo.keyboard.themes.pager.WelcomeActivity">
<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="100"
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="95dp"
android:layout_height="95dp"
android:src="@mipmap/logo" />
</androidx.cardview.widget.CardView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="14dp"
android:gravity="center"
android:lineSpacingExtra="3dp"
android:text="@string/text_app_name"
android:textColor="@color/black"
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="com.photo.keyboard.themes.pager.DialogEnable">
<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,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,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_app_name"
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/black_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,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.photo.keyboard.themes.mykeyboard.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: 132 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

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="theme_color">#A88EFA</color>
<color name="set_step_complete">#DCDCDC</color>
<color name="wel_pb_bg">#ACA8A8</color>
<!-- <color name="home_more_color">#E1D9EB</color>-->
<color name="page_color">#DAD2E6</color>
<color name="black_view">#66000000</color>
<color name="test_color">#0D082C</color>
<color name="color1">#A88EFA</color>
<color name="color2">#EFE9E7</color>
<color name="color3">#ccebec</color>
<color name="unselected_Color">#33A88EFA</color>
<color name="top">#66FFFFFF</color>
<color name="sub_main">#C3B8E6</color>
<color name="wel_bg">#66DAD2E6</color>
</resources>

View File

@ -0,0 +1,14 @@
<resources>
<string name="text_app_name">Versatile keyboard</string>
<string name="text_step1_select">Step 1: Select</string>
<string name="text_step1_eanble">Step 2: Enable</string>
<string name="text_text_download_apply">Download &amp; Apply</string>
<string name="text_text_apply">Apply</string>
<string name="text_more_feature">Activate Versatile keyboard</string>
<string name="text_succ_apply">Application successful</string>
<string name="text_fail_apply">Application failed, please try again</string>
<string name="et_hint">Type a Message</string>
<string name="favorite">Favorite</string>
<string name="empty_favorite">Go add your favorite keyboard themes !</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)
}
}

Some files were not shown because too many files have changed in this diff Show More