commit 2c88732787aa2d3dabb8ec2f2a127ea12ac7229a Author: litingting Date: Thu Oct 10 10:01:10 2024 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9228696 --- /dev/null +++ b/.gitignore @@ -0,0 +1,89 @@ +# Built application files +*.apk +*.aar +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ +# Uncomment the following line in case you need and you don't have the release build type files in your app +# release/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml + +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +#*.jks +#*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild +.cxx/ + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ + +# Android Profiling +*.hprof +gradle/wrapper/ diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000..14d6854 --- /dev/null +++ b/README.en.md @@ -0,0 +1,36 @@ +# 谷歌输入法项目 + +#### Description +{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md new file mode 100644 index 0000000..3bbd35c --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# 谷歌输入法项目 + +#### 介绍 +{**以下是 Gitee 平台说明,您可以替换此简介** +Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 +无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} + +#### 软件架构 +软件架构说明 + + +#### 安装教程 + +1. xxxx +2. xxxx +3. xxxx + +#### 使用说明 + +1. xxxx +2. xxxx +3. xxxx + +#### 参与贡献 + +1. Fork 本仓库 +2. 新建 Feat_xxx 分支 +3. 提交代码 +4. 新建 Pull Request + + +#### 特技 + +1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md +2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) +3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 +4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 +5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) +6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..5b40834 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,151 @@ +plugins { + + id 'com.android.application' + id 'org.jetbrains.kotlin.android' + id 'com.google.gms.google-services' + id 'com.google.firebase.crashlytics' + id 'kotlin-kapt' +} +static def releaseTime() { + return new Date().format("MM.dd.HH.mm", TimeZone.getTimeZone("GMT+8")) +} + +android { + namespace 'com.colorful.keyboard.theme' + compileSdk 34 + + defaultConfig { + applicationId "com.colorful.keyboard.theme" + minSdk 21 + targetSdk 34 + versionCode 3 + versionName "1.0.3" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + multiDexEnabled= true + setProperty("archivesBaseName", "ColorfulKeyboard_V" + defaultConfig.versionName + "(${defaultConfig.versionCode})"+"-"+releaseTime()) + } + + buildTypes { + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + debug { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = "17" + } + buildFeatures { + viewBinding true + buildConfig = true + } +} + +dependencies { + + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.8.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + testImplementation 'junit:junit:4.13.2' + + implementation"androidx.recyclerview:recyclerview:1.3.0" + implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" + implementation "de.hdodenhof:circleimageview:3.1.0" + implementation"androidx.lifecycle:lifecycle-process:2.6.1" + implementation "com.android.support:multidex:1.0.3" + implementation "io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.1.2" + implementation ("com.github.bumptech.glide:glide:4.11.0") + annotationProcessor ("com.github.bumptech.glide:compiler:4.11.0") + implementation ("com.android.support:multidex:1.0.3") + implementation ("com.squareup.retrofit2:retrofit:2.6.1") + implementation ("com.squareup.retrofit2:converter-gson:2.5.0") + implementation ("com.squareup.retrofit2:adapter-rxjava:2.1.0") + implementation ("io.reactivex.rxjava2:rxandroid:2.1.1") + implementation ("io.reactivex:rxjava:1.2.7") + implementation ("io.reactivex:rxjava:1.2.7") + implementation ("io.reactivex:rxandroid:1.2.0") + + implementation("androidx.room:room-ktx:2.6.1") + implementation("androidx.room:room-runtime:2.6.1") + //noinspection KaptUsageInsteadOfKsp + kapt("androidx.room:room-compiler:2.6.1") + + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1" + + implementation ("com.squareup.okhttp3:okhttp:4.9.0") + implementation ("com.squareup.okhttp3:logging-interceptor:3.12.2") + implementation 'jp.wasabeef:glide-transformations:4.3.0' + //7z + implementation 'com.github.omicronapps:7-Zip-JBinding-4Android:Release-16.02-2.02' + //沉浸式 + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' + implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.2' + // firebase + implementation(platform("com.google.firebase:firebase-bom:33.1.2"))// Import the Firebase BoM + implementation("com.google.firebase:firebase-analytics") + implementation("com.google.firebase:firebase-crashlytics") + implementation("com.google.firebase:firebase-config") + implementation("com.google.firebase:firebase-analytics-ktx") + implementation("com.google.firebase:firebase-crashlytics-ktx") + + + + //Anythink (Necessary) + implementation("com.anythink.sdk:core-tpn:6.3.68") + implementation("com.anythink.sdk:nativead-tpn:6.3.68") + implementation("com.anythink.sdk:banner-tpn:6.3.68") + implementation("com.anythink.sdk:interstitial-tpn:6.3.68") + implementation("com.anythink.sdk:rewardedvideo-tpn:6.3.68") + implementation("com.anythink.sdk:splash-tpn:6.3.68") + + //Androidx (Necessary) + implementation("androidx.appcompat:appcompat:1.1.0") + implementation("androidx.browser:browser:1.4.0") + + //Vungle + implementation("com.anythink.sdk:adapter-tpn-vungle:6.3.68") + implementation("com.vungle:vungle-ads:7.3.2") + implementation("com.google.android.gms:play-services-basement:18.1.0") + implementation("com.google.android.gms:play-services-ads-identifier:18.0.1") + + //UnityAds + implementation("com.anythink.sdk:adapter-tpn-unityads:6.3.68") + implementation("com.unity3d.ads:unity-ads:4.9.3") + + //Ironsource + implementation("com.anythink.sdk:adapter-tpn-ironsource:6.3.68") + implementation("com.ironsource.sdk:mediationsdk:8.1.0") + implementation("com.google.android.gms:play-services-appset:16.0.2") + implementation("com.google.android.gms:play-services-ads-identifier:18.0.1") + implementation("com.google.android.gms:play-services-basement:18.1.0") + + //Bigo + implementation("com.anythink.sdk:adapter-tpn-bigo:6.3.68") + implementation("com.bigossp:bigo-ads:4.7.4") + + //Pangle + implementation("com.anythink.sdk:adapter-tpn-pangle-nonchina:6.3.68.1") + implementation("com.pangle.global:ads-sdk:6.0.0.3") + implementation("com.google.android.gms:play-services-ads-identifier:18.0.1") + + //Mintegral + implementation("com.anythink.sdk:adapter-tpn-mintegral-nonchina:6.3.68") + implementation("com.mbridge.msdk.oversea:reward:16.7.51") + implementation("com.mbridge.msdk.oversea:newinterstitial:16.7.51") + implementation("com.mbridge.msdk.oversea:mbnative:16.7.51") + implementation("com.mbridge.msdk.oversea:mbnativeadvanced:16.7.51") + implementation("com.mbridge.msdk.oversea:mbsplash:16.7.51") + implementation("com.mbridge.msdk.oversea:mbbanner:16.7.51") + implementation("com.mbridge.msdk.oversea:mbbid:16.7.51") + implementation("androidx.recyclerview:recyclerview:1.1.0") +} \ No newline at end of file diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..ebd2dba --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "987938744902", + "project_id": "colorful-keyboard-de3d4", + "storage_bucket": "colorful-keyboard-de3d4.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:987938744902:android:d05e8cf3ac15ff540bb847", + "android_client_info": { + "package_name": "com.colorful.keyboard.theme" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyAS_P0_s948qN8GMPoXnWeWvlD2G_yChCQ" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/key.properties b/app/key.properties new file mode 100644 index 0000000..9ade669 --- /dev/null +++ b/app/key.properties @@ -0,0 +1,9 @@ +# ????? +storePassword=theme123 +# key???? +keyPassword=theme1 +# key?? +keyAlias=theme +# key?? +storeFile=..\\themes.jks + diff --git a/app/private_key.pepk b/app/private_key.pepk new file mode 100644 index 0000000..3750d25 Binary files /dev/null and b/app/private_key.pepk differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..016d169 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,137 @@ +# 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 + + +#---------------------------------TopOn 聚合 +# Vungle +-dontwarn com.vungle.ads.** +-keepclassmembers class com.vungle.ads.** { + *; +} + + + + +# Google +-keep class com.google.android.gms.** { *; } +-dontwarn com.google.android.gms.** + + + + +# START OkHttp + Okio +# JSR 305 annotations are for embedding nullability information. +-dontwarn javax.annotation.** + + +# A resource is loaded with a relative path so the package of this class must be preserved. +-adaptresourcefilenames okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz + + +# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. +-dontwarn org.codehaus.mojo.animal_sniffer.* + + +# OkHttp platform used only on JVM and when Conscrypt and other security providers are available. +-dontwarn okhttp3.internal.platform.** +-dontwarn org.conscrypt.** +-dontwarn org.bouncycastle.** +-dontwarn org.openjsse.** + + +# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. +-dontwarn org.codehaus.mojo.animal_sniffer.* + + +# END OkHttp + Okio + + +# START Protobuf +-dontwarn com.google.protobuf.** +-keepclassmembers class com.google.protobuf.** { + *; +} +-keep class * extends com.google.protobuf.GeneratedMessageLite { *; } + + +# END Protobuf +-keepattributes Signature +-keepattributes *Annotation* +-keep class com.mbridge.** {*; } +-keep interface com.mbridge.** {*; } +-keep class android.support.v4.** { *; } +-dontwarn com.mbridge.** +-keep class **.R$* { public static final int mbridge*; } +-keep public class com.mbridge.* extends androidx.** { *; } +-keep public class androidx.viewpager.widget.PagerAdapter{ *; } +-keep public class androidx.viewpager.widget.ViewPager.OnPageChangeListener{ *; } +-keep interface androidx.annotation.IntDef{ *; } +-keep interface androidx.annotation.Nullable{ *; } +-keep interface androidx.annotation.CheckResult{ *; } +-keep interface androidx.annotation.NonNull{ *; } +-keep public class androidx.fragment.app.Fragment{ *; } +-keep public class androidx.core.content.FileProvider{ *; } +-keep public class androidx.core.app.NotificationCompat{ *; } +-keep public class androidx.appcompat.widget.AppCompatImageView { *; } +-keep public class androidx.recyclerview.*{ *; } + +#---------------------------------TopOn 聚合 + +-keep class org.libpag.** {*;} +-keep class androidx.exifinterface.** {*;} +-keep class com.omicronapplications.** { *; } +-keep class net.sf.sevenzipjbinding.** { *; } + + +# Retrofit +-dontnote retrofit2.Platform +-dontnote retrofit2.Platform$IOS$MainThreadExecutor +-dontwarn retrofit2.Platform$Java8 +-keepattributes Signature +-keepattributes Exceptions + +# okhttp +-dontwarn okio.** + +# 保留RxJava相关的类和方法 +-keep class rx.** { *; } +-keepclassmembers class rx.** { *; } + +# 保留Retrofit相关的类和方法 +-keep class retrofit2.** { *; } +-keep class okhttp3.** { *; } +-keep interface retrofit2.** { *; } +-keepclasseswithmembers class * { + @retrofit2.http.* ; +} + +# 保留RxJava的CallAdapter +-keep class retrofit2.adapter.rxjava2.** { *; } + +# 保留返回Observable的Retrofit接口方法 +-keepclassmembers,allowobfuscation interface * { + @retrofit2.http.* ; + rx.Observable *; +} + +-keep class com.colorful.keyboard.theme.net.** { *; } +-keep class com.colorful.keyboard.theme.model.** { *; } \ No newline at end of file diff --git a/app/src/androidTest/java/com/colorful/keyboard/theme/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/colorful/keyboard/theme/ExampleInstrumentedTest.java new file mode 100644 index 0000000..bdbde03 --- /dev/null +++ b/app/src/androidTest/java/com/colorful/keyboard/theme/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.colorful.keyboard.theme; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.colorful.keyboard.theme", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a6a5b01 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/PrivacyPolicy.html b/app/src/main/assets/PrivacyPolicy.html new file mode 100644 index 0000000..f598a0b --- /dev/null +++ b/app/src/main/assets/PrivacyPolicy.html @@ -0,0 +1,111 @@ + + + + + + Privacy Policy + + + + Privacy Policy +

+ +

+ This page is used to inform visitors regarding our + policies with the collection, use, and disclosure of Personal + Information if anyone decided to use our Service. +

+ If you choose to use our Service, then you agree to + the collection and use of information in relation to this + policy. The Personal Information that We collect is + used for providing and improving the Service. We will not use or share your information with + anyone except as described in this Privacy Policy. +

+ The terms used in this Privacy Policy have the same meanings + as in our Terms and Conditions, which are accessible at + unless otherwise defined in this Privacy Policy. +

Information Collection and Use

+ For a better experience, while using our Service, We + may require you to provide us with certain personally + identifiable information add whatever else you collect here, e.g. users name, address, location, pictures The information that + We request will be retained on your device and is not collected in any way retained by us and used as described in this privacy policy. +

+ The app does use third-party services that may collect + information used to identify you. +

+ Link to the privacy policy of third-party service providers used + by the app +

Log Data

+ We want to inform you that whenever you + use our Service, in a case of an error in the app + We collect data and information (through third-party + products) on your phone called Log Data. This Log Data may + include information such as your device Internet Protocol + (“IP”) address, device name, operating system version, the + configuration of the app when utilizing our Service, + the time and date of your use of the Service, and other + statistics. +

Cookies

+ Cookies are files with a small amount of data that are + commonly used as anonymous unique identifiers. These are sent + to your browser from the websites that you visit and are + stored on your device's internal memory. + +

+ This Service does not use these “cookies” explicitly. However, + the app may use third-party code and libraries that use + “cookies” to collect information and improve their services. + You have the option to either accept or refuse these cookies + and know when a cookie is being sent to your device. If you + choose to refuse our cookies, you may not be able to use some + portions of this Service. +

Service Providers

+ We may employ third-party companies and + individuals due to the following reasons: +

  • To facilitate our Service;
  • To provide the Service on our behalf;
  • To perform Service-related services; or
  • To assist us in analyzing how our Service is used.

+ We want to inform users of this Service + that these third parties have access to their Personal + Information. The reason is to perform the tasks assigned to + them on our behalf. However, they are obligated not to + disclose or use the information for any other purpose. +

Security

+ We value your trust in providing us your + Personal Information, thus we are striving to use commercially + acceptable means of protecting it. But remember that no method + of transmission over the internet, or method of electronic + storage is 100% secure and reliable, and We cannot + guarantee its absolute security. +

Links to Other Sites

+ This Service may contain links to other sites. If you click on + a third-party link, you will be directed to that site. Note + that these external sites are not operated by us. + Therefore, We strongly advise you to review the + Privacy Policy of these websites. We have + no control over and assume no responsibility for the content, + privacy policies, or practices of any third-party sites or + services. +

Children’s Privacy

+ These Services do not address anyone under the age of 13. + We do not knowingly collect personally + identifiable information from children under 13 years of age. In the case + We discover that a child under 13 has provided + us with personal information, We immediately + delete this from our servers. If you are a parent or guardian + and you are aware that your child has provided us with + personal information, please contact us so that + We will be able to do the necessary actions. +

Changes to This Privacy Policy

+ We may update our Privacy Policy from + time to time. Thus, you are advised to review this page + periodically for any changes. We will + notify you of any changes by posting the new Privacy Policy on + this page. +

This policy is effective as of 2024-1-8

Contact Us

+ If you have any questions or suggestions about our + Privacy Policy, do not hesitate to contact us at JaysonNazaireMtfWaOIe@gmail.com. + + + +

+ + \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/App.kt b/app/src/main/java/com/colorful/keyboard/theme/App.kt new file mode 100644 index 0000000..e9db1a2 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/App.kt @@ -0,0 +1,31 @@ +package com.colorful.keyboard.theme + +import android.app.Application +import com.anythink.core.api.ATSDK +import com.colorful.keyboard.theme.firebase.RemoteConfig +import com.colorful.keyboard.theme.myutil.Utils +import com.colorful.keyboard.theme.room.DownloadManager +import java.util.concurrent.atomic.AtomicLong + +class App : Application() { + companion object { + lateinit var app: App + private set + + lateinit var downloadManager: DownloadManager + private set + } + + var lastAdDisplayTime: AtomicLong = AtomicLong(0L)//上次广告展示的时间 + + override fun onCreate() { + super.onCreate() + app = this + Utils.init(this) + downloadManager = DownloadManager.getInstance(this) + RemoteConfig.instance.init(this) + ATSDK.init(this, "h66b1cef2a9a51", "a90d2376d3e1dd2bd9bb5cb4f8296085f") +// ATSDK.integrationChecking(this) +// ATSDK.setNetworkLogDebug(true) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/ColorfulDetailsActivity.kt b/app/src/main/java/com/colorful/keyboard/theme/ColorfulDetailsActivity.kt new file mode 100644 index 0000000..859255d --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ColorfulDetailsActivity.kt @@ -0,0 +1,166 @@ +package com.colorful.keyboard.theme + +import android.content.Intent +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import com.colorful.keyboard.theme.ad.AdsInsUtil +import com.colorful.keyboard.theme.bean.DetailsBean +import com.colorful.keyboard.theme.bean.DownloadBean +import com.colorful.keyboard.theme.databinding.ColorfulDetailsActivityBinding +import com.colorful.keyboard.theme.myutil.AppSharedPreferences +import com.colorful.keyboard.theme.myutil.NetworkCallback +import com.colorful.keyboard.theme.myutil.NetworkUtil +import com.colorful.keyboard.theme.myutil.OnDownloadListener +import com.colorful.keyboard.theme.myutil.ResourceDownloadUtil +import com.colorful.keyboard.theme.myutil.fileIsDownload +import com.colorful.keyboard.theme.myutil.loadRoundedImage +import com.gyf.immersionbar.ktx.immersionBar +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch + +@OptIn(DelicateCoroutinesApi::class) +class ColorfulDetailsActivity : AppCompatActivity(), OnDownloadListener { + private var key: String? = null + private var title: String? = null + private lateinit var binding: ColorfulDetailsActivityBinding + private var detailsBean: DetailsBean? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ColorfulDetailsActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + title = intent.getStringExtra("title") + key = intent.getStringExtra("key") + if (key.isNullOrEmpty()) { + finish() + } + initBar() + initView() + initData() + AdsInsUtil.loadAllAdIsNotCached(this) + } + + private fun initBar() { + immersionBar { + statusBarDarkFont(true) + statusBarView(binding.view) + } + } + + override fun onBackPressed() { + super.onBackPressed() + AdsInsUtil.showAdRandomModeAndTiming(this) + } + + private fun initView() { + binding.titleTv.text = title + binding.backBtn.setOnClickListener { onBackPressed() } + + binding.downBtn.setOnClickListener { + detailsBean?.let { + updateDownloadBtn(it) + val resourceHandler = ResourceDownloadUtil(this) // 传入当前上下文 + resourceHandler.setOnDownloadListener(this) + val imageUrl = it.themeContent.androidRawZipUrl + val b = fileIsDownload(this, imageUrl) + if (b) { + AppSharedPreferences(this).setCurrentlyThemeUrl(imageUrl) + + val intent = Intent(this, PreviewActivity::class.java) + intent.putExtra(PreviewActivity.KEY_PREVIEW_URL, imageUrl) + startActivity(intent) + finish() + } else { + binding.loadingBar.visibility = View.VISIBLE + binding.downIcon.visibility = View.GONE + resourceHandler.downloadAndExtractResources(imageUrl)//文件不存在则下载 + } + } + } + } + + private fun initData() { + loadingPlay() + NetworkUtil().getResourceRequest(key!!, object : NetworkCallback { + override fun onSuccess(data: DetailsBean) { + detailsBean = data + updateUi(data) + } + + override fun onFailure(errorMessage: String) { + runOnUiThread { + if (!isFinishing && !isDestroyed) { + loadingClose() + } + } + } + }) + } + + private fun updateUi(data: DetailsBean) { + runOnUiThread { + if (!isFinishing && !isDestroyed) { + loadingClose() + + updateDownloadBtn(data) + + var url = data.themeContent.imgGif + if (url.isEmpty()) { + url = data.themeContent.img + } + loadRoundedImage(this, url, binding.imageView, 40) + } + } + } + + private fun loadingPlay() { + binding.loadingLayout.visibility = View.VISIBLE + } + + private fun loadingClose() { + binding.loadingLayout.visibility = View.GONE + } + + private fun updateDownloadBtn(data: DetailsBean) { + if (fileIsDownload(this, data.themeContent.androidRawZipUrl)) { + if (AppSharedPreferences(this).getCurrentlyThemeUrl() == data.themeContent.androidRawZipUrl) { + binding.downTv.text = getString(R.string.applied) + binding.downBtn.isClickable = false + binding.downBtn.isFocusable = false + binding.downIcon.visibility = View.GONE + } else { + binding.downTv.text = getString(R.string.apply_it) + binding.downBtn.isClickable = true + binding.downBtn.isFocusable = true + binding.downIcon.visibility = View.GONE + } + } else { + binding.downTv.text = getString(R.string.download) + binding.downBtn.isClickable = true + binding.downBtn.isFocusable = true + binding.downIcon.visibility = View.VISIBLE + } + } + + override fun onDownloadComplete(isDownloaded: Boolean) { + + binding.loadingBar.visibility = View.GONE + binding.downIcon.visibility = View.GONE + + updateUi(detailsBean!!) + + GlobalScope.launch(Dispatchers.IO) { + var url = detailsBean?.themeContent?.imgGif + if (url.isNullOrEmpty()) { + url = detailsBean?.themeContent?.img + } + val bean = DownloadBean( + title = detailsBean?.title ?: "", key = detailsBean?.key ?: "", imgUrl = url ?: "" + ) + App.downloadManager.insertDownloadBean(bean) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/DownloadsActivity.kt b/app/src/main/java/com/colorful/keyboard/theme/DownloadsActivity.kt new file mode 100644 index 0000000..0f67844 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/DownloadsActivity.kt @@ -0,0 +1,72 @@ +package com.colorful.keyboard.theme + +import android.content.Intent +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import androidx.recyclerview.widget.GridLayoutManager +import com.colorful.keyboard.theme.ad.AdsInsUtil +import com.colorful.keyboard.theme.config_adpter.DownloadAdapter +import com.colorful.keyboard.theme.databinding.ColorfulDownloadActivityBinding +import com.gyf.immersionbar.ktx.immersionBar +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +@OptIn(DelicateCoroutinesApi::class) +class DownloadsActivity : AppCompatActivity() { + private lateinit var binding: ColorfulDownloadActivityBinding + private var downloadAdapter = DownloadAdapter() + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ColorfulDownloadActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + AdsInsUtil.showAdRandomModeAndTiming(this) + initBar() + initView() + initData() + + AdsInsUtil.loadAllAdIsNotCached(this) + } + + private fun initBar() { + immersionBar { + statusBarDarkFont(true) + statusBarView(binding.view) + } + } + + private fun initView() { + binding.backBtn.setOnClickListener { + onBackPressed() + } + } + + private fun initData() { + binding.loadingLayout.visibility = View.VISIBLE + GlobalScope.launch(Dispatchers.IO) { + val downloads = App.downloadManager.getAllDownloadBeans() + withContext(Dispatchers.Main) { + binding.loadingLayout.visibility = View.GONE + if (downloads.isNotEmpty()) { + binding.noDataLayout.visibility = View.GONE + downloadAdapter.submitList(downloads) + binding.rvPhotoIst.layoutManager = GridLayoutManager(this@DownloadsActivity, 3) + binding.rvPhotoIst.adapter = downloadAdapter + downloadAdapter.setOnItemClickListener { baseQuickAdapter, _, i -> + startActivity( + Intent(this@DownloadsActivity, ColorfulDetailsActivity::class.java) + .putExtra("title", baseQuickAdapter.getItem(i)!!.title) + .putExtra("key", baseQuickAdapter.getItem(i)!!.key) + .putExtra("url", baseQuickAdapter.getItem(i)!!.imgUrl) + ) + } + } else { + binding.noDataLayout.visibility = View.VISIBLE + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/KeyboardService.kt b/app/src/main/java/com/colorful/keyboard/theme/KeyboardService.kt new file mode 100644 index 0000000..e0a6770 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/KeyboardService.kt @@ -0,0 +1,359 @@ +package com.colorful.keyboard.theme + +import android.graphics.BitmapFactory +import android.graphics.drawable.BitmapDrawable +import android.inputmethodservice.InputMethodService +import android.net.Uri +import android.view.View +import android.view.inputmethod.EditorInfo +import android.view.inputmethod.InputConnection +import android.widget.VideoView +import com.colorful.keyboard.theme.myutil.AppSharedPreferences +import com.colorful.keyboard.theme.myutil.colorsXmlPullParser +import com.colorful.keyboard.theme.myutil.currentlyThemeUFileString +import com.colorful.keyboard.theme.myutil.getBitmapDrawable +import com.colorful.keyboard.theme.myutil.getPath +import com.colorful.keyboard.theme.myutil.getRawVideoPath +import com.colorful.keyboard.theme.myutil.getStateDrawable +import com.colorful.keyboard.theme.view.JourneyKeyboardView +import com.colorful.keyboard.theme.view.Keyboard +import com.colorful.keyboard.theme.view.KeyboardView +import com.colorful.keyboard.theme.view.JourneyKeyboard +import java.io.File + +class KeyboardService : InputMethodService() { + + private lateinit var keyboardView: JourneyKeyboardView + private lateinit var currentKeyboard: Keyboard + private var isAllCaps = false + private var isCap = false + private lateinit var rootView: View + + override fun onCreateInputView(): View { + rootView = layoutInflater.inflate(R.layout.custom_keyboard, null) // 这里使用了一个容器布局 + keyboardView = rootView.findViewById(R.id.keyboardView) // 在容器布局中找到 KeyboardView 的引用 + currentKeyboard = Keyboard(this, R.xml.my_custom_keyboard_layout) + keyboardView.keyboard = currentKeyboard + keyboardView.setOnKeyboardActionListener(onKeyboardActionListener) + + isCap = keyboardView.isCap() + isAllCaps = keyboardView.isAllCaps() + + return rootView // 返回包含 KeyboardView 的容器布局 + } + + override fun onWindowShown() { + super.onWindowShown() + updateConfig() + } + + private fun updateConfig() { + val currentlyUrl = AppSharedPreferences(this).getCurrentlyThemeUrl() + if (currentlyUrl.isNotEmpty()) { + val currentlyThemeUFile = currentlyThemeUFileString(this, currentlyUrl) + val config = JourneyKeyboardView.Config(this) + config.keyBackground = getStateDrawable(this, + getPath(currentlyThemeUFile, "btn_keyboard_key_normal_normal.9.png"), + getPath(currentlyThemeUFile, "btn_keyboard_key_normal_pressed.9.png") + ) + config.specialKeyBackground = getStateDrawable(this, + getPath(currentlyThemeUFile, "btn_keyboard_spacekey_normal_normal.9.png"), + getPath(currentlyThemeUFile, "btn_keyboard_spacekey_normal_pressed.9.png") + ) + config.deleteDrawable = getStateDrawable(this, + getPath(currentlyThemeUFile, "sym_keyboard_delete_normal.png"), + getPath(currentlyThemeUFile, "sym_keyboard_delete_pressed.png") + ) + config.toggleKeyBackground = getStateDrawable(this, + getPath(currentlyThemeUFile, "btn_keyboard_key_toggle_normal_on.9.png"), + getPath(currentlyThemeUFile, "btn_keyboard_key_toggle_pressed_on.9.png") + ) + + val colorMap = colorsXmlPullParser(currentlyThemeUFile) + colorMap.forEach { (name, value) -> + if (name == "key_text_color_normal") { + config.keyTextColor = value + config.keySpecialTextColor = value + } + if (name == "key_text_color_functional") { + config.toggleKeyTextColor = value + } + } + config.capitalDrawable = + getBitmapDrawable(this,currentlyThemeUFile, "sym_keyboard_shift_locked.png") + config.lowerDrawable = getBitmapDrawable(this,currentlyThemeUFile, "sym_keyboard_shift.png") + config.capitalLockDrawable = + getBitmapDrawable(this,currentlyThemeUFile, "sym_keyboard_shift_locked.png") + + val videoView = rootView.findViewById(R.id.videoView) + val videoPath = getRawVideoPath(currentlyThemeUFile) + if (File(videoPath).exists()) { + // 设置视频路径并启动播放 + videoView.setVideoURI(Uri.parse(videoPath)) + videoView.setOnPreparedListener { mp -> + mp.isLooping = true // 循环播放 + videoView.start() + } + videoView.visibility = View.VISIBLE + } else { + val imagePath = + "$currentlyThemeUFile/res/drawable-xxhdpi-v4/keyboard_background.jpg" + val bitmap = BitmapFactory.decodeFile(imagePath) + val background = BitmapDrawable(resources, bitmap) + rootView.background = background + videoView.visibility = View.GONE + } + keyboardView.setConfig(config) + } + } + + private val onKeyboardActionListener = object : KeyboardView.OnKeyboardActionListener { + override fun onKey(primaryCode: Int, keyCodes: IntArray?) { + val ic = currentInputConnection + performKey(ic, primaryCode, keyCodes) + } + + override fun onPress(primaryCode: Int) {} + + override fun onRelease(primaryCode: Int) {} + + override fun onText(text: CharSequence?) {} + + override fun swipeLeft() {} + + override fun swipeRight() {} + + override fun swipeDown() {} + + override fun swipeUp() {} + } + + private var keyboardType = KeyboardType.NORMAL + + private val keyboardNormal by lazy { Keyboard(this, R.xml.my_custom_keyboard_layout) } + private val keyboardNormalModeChange by lazy { Keyboard(this, R.xml.keyboard_mode_change) } + private val keyboardNormalMore by lazy { Keyboard(this, R.xml.keyboard_more_symbol) } + + /** + * 根据 primaryCode去做相应的处理 + */ + private fun performKey(ic: InputConnection, primaryCode: Int, keyCodes: IntArray?) { + when (primaryCode) { + JourneyKeyboard.KEYCODE_SHIFT -> keyShift() + JourneyKeyboard.KEYCODE_MODE_CHANGE -> keyModeChange() + JourneyKeyboard.KEYCODE_CANCEL -> keyCancel(primaryCode) + JourneyKeyboard.KEYCODE_DONE -> keyDone(primaryCode) + JourneyKeyboard.KEYCODE_DELETE -> keyDelete(ic) + JourneyKeyboard.KEYCODE_MODE_BACK -> keyBack(false) + JourneyKeyboard.KEYCODE_BACK -> keyBack(true) + JourneyKeyboard.KEYCODE_MORE -> keyMore() + //无效的按键值,打印相关日志 + else -> commitText(ic, primaryCode) + } + } + + private fun commitText(ic: InputConnection, primaryCode: Int) { + val code = primaryCode.toChar().toString() + ic.commitText(code, 1) + + if (isCap && !isAllCaps) {//如果当前是大写键盘,并且并且没有锁定,则自动变换成小写键盘 + isCap = false + isAllCaps = false + toLowerCaseKey(currentKeyboard) + + keyboardView.run { + setCap(isCap) + setAllCaps(isAllCaps) + keyboard = currentKeyboard + } + } + } + /** + * 触发删除 + */ + private fun keyDelete(ic: InputConnection) { + ic.deleteSurroundingText(1, 0) + } + + /** + * 触发Shift,切换大小字母键盘 + */ + private fun keyShift() { + //将键盘进行大小写键盘切换 + if (isAllCaps) {//上次状态为大写锁定时,转换为小写 + toLowerCaseKey(currentKeyboard) + } else {//反之上次状态即为小写时,转换为大写 + toUpperCaseKey(currentKeyboard) + } + + when { + isAllCaps -> {//上次状态为锁定时,此次状态将改变为小写,将变量状态改变 + isAllCaps = false + isCap = false + } + + isCap -> {//上次状态为非锁定,此次状态改变为锁定 + isAllCaps = true + } + + else -> {//上次状态为小写(默认),此次状态改变为大写 + isCap = true + isAllCaps = false + } + } + + keyboardView.let { + it.setCap(isCap) + it.setAllCaps(isAllCaps) + it.keyboard = currentKeyboard + } + + + } + + /** + * 转换为大写 + */ + private fun toUpperCaseKey(keyboard: Keyboard) { + keyboard.run { + for (key in keys) { + if (key.label?.length == 1) {// 一个字符 + var c = key.label.toString()[0] + if (c.isLowerCase()) { //是小写字母 + //转换为大写 + val letter = c.toUpperCase() + key.label = letter.toString() + key.codes[0] = letter.toInt() + } + + } + } + } + + } + + /** + * 转换为小写 + */ + private fun toLowerCaseKey(keyboard: Keyboard) { + keyboard.run { + for (key in keys) { + if (key.label?.length == 1) {// 一个字符 + var c = key.label.toString()[0] + if (c.isUpperCase()) { //是大写字母 + //转换为小写 + val letter = c.toLowerCase() + key.label = letter.toString() + key.codes[0] = letter.toInt() + } + + } + } + } + + } + + /** + * 模式改变,切换键盘 + */ + private fun keyModeChange() { + when (keyboardType) { + JourneyKeyboard.KeyboardType.NORMAL -> { + keyboardType = KeyboardType.NORMAL_MODE_CHANGE + } + } + + switchKeyboard() + } + + private fun switchKeyboard() { + when (keyboardType) { + KeyboardType.NORMAL -> { + currentKeyboard = keyboardNormal + } + + KeyboardType.NORMAL_MODE_CHANGE -> { + currentKeyboard = keyboardNormalModeChange + } + + KeyboardType.NORMAL_MORE -> { + currentKeyboard = keyboardNormalMore + } + } + + keyboardView.run { + keyboard = currentKeyboard + } + + } + + /** + * 取消,关闭键盘 + */ + private fun keyCancel(primaryCode: Int) { + val ic = currentInputConnection + ic?.performEditorAction(EditorInfo.IME_ACTION_DONE) + } + + /** + * 完成 + */ + private fun keyDone(primaryCode: Int) { + val ic = currentInputConnection + ic?.performEditorAction(EditorInfo.IME_ACTION_DONE) + } + + + /** + * 返回 + */ + private fun keyBack(isBack: Boolean) { + when (keyboardType) { + KeyboardType.NORMAL_MODE_CHANGE -> { + keyboardType = KeyboardType.NORMAL + } + + KeyboardType.NORMAL_MORE -> { + keyboardType = if (isBack) KeyboardType.NORMAL else KeyboardType.NORMAL_MODE_CHANGE + } + } + + switchKeyboard() + } + + /** + * 更多 + */ + private fun keyMore() { + when (keyboardType) { + KeyboardType.NORMAL -> { + keyboardType = KeyboardType.NORMAL_MORE + } + + KeyboardType.NORMAL_MODE_CHANGE -> { + keyboardType = KeyboardType.NORMAL_MORE + } + } + + switchKeyboard() + } + + + object KeyboardType { + /** + * 默认键盘 - 字母带符号 + */ + const val NORMAL = 0x00000001 + + /** + * 默认键盘 - 切换键盘 + */ + internal const val NORMAL_MODE_CHANGE = 0x00000002 + + /** + * 默认键盘 - 更多 + */ + internal const val NORMAL_MORE = 0x00000003 + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/LaunchActivity.kt b/app/src/main/java/com/colorful/keyboard/theme/LaunchActivity.kt new file mode 100644 index 0000000..36bf130 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/LaunchActivity.kt @@ -0,0 +1,116 @@ +package com.colorful.keyboard.theme + +import android.annotation.SuppressLint +import android.content.Intent +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.os.Message +import android.util.Log +import androidx.appcompat.app.AppCompatActivity +import com.anythink.core.api.ATAdInfo +import com.anythink.core.api.ATSDK +import com.colorful.keyboard.theme.ad.AdShowFailed +import com.colorful.keyboard.theme.ad.AdsInsUtil +import com.colorful.keyboard.theme.ad.ShowListener +import com.colorful.keyboard.theme.databinding.ActivitySplashBinding +import com.gyf.immersionbar.ktx.immersionBar + +class LaunchActivity : AppCompatActivity() { + companion object { + private const val MSG_PROGRESS = 0 + private const val MSG_LOAD_AD_LOADED = 1 + private const val MSG_LOAD_AD_FAIL = 2 + } + + private lateinit var binding: ActivitySplashBinding + private val mMaxLoading = 10000L//最大超时 + private var progress = 0f + private val delayMillis = mMaxLoading / 100 + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + binding = ActivitySplashBinding.inflate(layoutInflater) + setContentView(binding.root) + loadAd() + handler.sendEmptyMessageDelayed(MSG_PROGRESS, delayMillis) + immersionBar { + fullScreen(true) + statusBarDarkFont(true) + } + } + + private val handler = object : Handler(Looper.getMainLooper()) { + override fun handleMessage(msg: Message) { + val progressBar = binding.customProgressBar + if (!isFinishing && !isDestroyed) { + when (msg.what) { + MSG_PROGRESS -> { + if (progress >= 100f) {//超时 + toMainActivity() + return + } + val cacheAd = AdsInsUtil.canShowAd(AdsInsUtil.Placement.TOP_ON_AD_ONE) + if (cacheAd) { + sendEmptyMessageDelayed(MSG_LOAD_AD_LOADED, delayMillis) + removeMessages(MSG_PROGRESS) + return + } + progress += 1 + progressBar.setProgress(progress) + sendEmptyMessageDelayed(MSG_PROGRESS, delayMillis) + } + + MSG_LOAD_AD_LOADED -> { + if (progress >= 100f) { + showAd() + removeMessages(MSG_LOAD_AD_LOADED) + return + } + progress += 1 + progressBar.setProgress(progress) + sendEmptyMessageDelayed(MSG_LOAD_AD_LOADED, delayMillis) + } + + MSG_LOAD_AD_FAIL -> { + sendEmptyMessageDelayed(MSG_LOAD_AD_LOADED, delayMillis) + removeMessages(MSG_LOAD_AD_FAIL) + removeMessages(MSG_PROGRESS) + } + } + } + } + } + + + private fun toMainActivity() { + startActivity(Intent(this, MainActivity::class.java)) + finish() + } + + private fun loadAd() { + AdsInsUtil.loadAllAdIsNotCached(this) + } + + private fun showAd() { + AdsInsUtil.showAd(this, AdsInsUtil.Placement.TOP_ON_AD_ONE, object : ShowListener { + override fun onAdClosed() { + toMainActivity() + } + + override fun onAdShowFailed(error: AdShowFailed?) { + toMainActivity() + } + + override fun onAdShown(ad: ATAdInfo?) { + AdsInsUtil.loadAllAdIsNotCached(this@LaunchActivity) + } + }) + } + + @SuppressLint("MissingSuperCall") + override fun onBackPressed() { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/LocalPrivacyAct.kt b/app/src/main/java/com/colorful/keyboard/theme/LocalPrivacyAct.kt new file mode 100644 index 0000000..b961f8e --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/LocalPrivacyAct.kt @@ -0,0 +1,121 @@ +package com.colorful.keyboard.theme + +import android.annotation.SuppressLint +import android.annotation.TargetApi +import android.graphics.Bitmap +import android.os.Build +import android.os.Bundle +import android.view.View +import android.webkit.* +import androidx.appcompat.app.AppCompatActivity +import com.colorful.keyboard.theme.databinding.ActivityWebPrivacyBinding +import com.gyf.immersionbar.ktx.immersionBar + +class LocalPrivacyAct : AppCompatActivity() { + + private lateinit var binding: ActivityWebPrivacyBinding + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityWebPrivacyBinding.inflate(layoutInflater) + setContentView(binding.root) + initBar() + initView() + } + + private fun initBar() { + immersionBar { + statusBarDarkFont(true) + statusBarView(binding.view) + } + } + + private fun initView() { + binding.backBtn.setOnClickListener { + finish() + } + initWebView() + loadUrl() + } + + private fun loadUrl() { + binding.webView.loadUrl("file:///android_asset/PrivacyPolicy.html") + } + + @SuppressLint("SetJavaScriptEnabled") + private fun initWebView() { + // 设置背景色 + binding.webView.setBackgroundColor(0); + // 设置填充透明度 + binding.webView.background.alpha = 0 + + binding.webView.settings.javaScriptEnabled = true + binding.webView.settings.domStorageEnabled = true + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + binding.webView.settings.mixedContentMode = 0 + } + + binding.webView.settings.apply { + javaScriptEnabled = true + loadWithOverviewMode = true + useWideViewPort = true + setSupportZoom(true) + loadWithOverviewMode = true + javaScriptCanOpenWindowsAutomatically = true + } + binding.webView.webChromeClient = object : WebChromeClient() { + override fun onReceivedTitle(view: WebView?, title: String?) { + } + } + binding.webView.webViewClient = object : WebViewClient() { + private var mLoadError = false + override fun shouldOverrideUrlLoading( + view: WebView, request: WebResourceRequest? + ): Boolean { + val url = request?.url?.toString() + return overrideUrlLoading(view, url) + } + + @Suppress("OverridingDeprecatedMember") + override fun shouldOverrideUrlLoading(view: WebView, url: String?): Boolean { + return overrideUrlLoading(view, url) + } + + override fun onPageFinished(view: WebView?, url: String?) { + super.onPageFinished(view, url) + binding.progressBar.visibility = View.GONE + if (mLoadError) { + } + } + + override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { + binding.progressBar.visibility = View.VISIBLE + mLoadError = false + super.onPageStarted(view, url, favicon) + } + + @TargetApi(Build.VERSION_CODES.M) + override fun onReceivedError( + view: WebView?, request: WebResourceRequest?, error: WebResourceError? + ) { + error(error?.errorCode, error?.description, request?.url?.toString()) + super.onReceivedError(view, request, error) + } + + @Suppress("OverridingDeprecatedMember", "DEPRECATION") + override fun onReceivedError( + view: WebView?, errorCode: Int, description: String?, failingUrl: String? + ) { + error(errorCode, description, failingUrl) + super.onReceivedError(view, errorCode, description, failingUrl) + } + + private fun error(code: Int?, desc: CharSequence?, url: String?) { + } + + private fun overrideUrlLoading(view: WebView, url: String?): Boolean { + return false + } + } + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/MainActivity.java b/app/src/main/java/com/colorful/keyboard/theme/MainActivity.java new file mode 100644 index 0000000..065244a --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/MainActivity.java @@ -0,0 +1,303 @@ +package com.colorful.keyboard.theme; + +import static com.colorful.keyboard.theme.myutil.AppUtilKt.isMyInputMethodDefault; +import static com.colorful.keyboard.theme.myutil.AppUtilKt.isMyInputMethodEnabled; +import static com.colorful.keyboard.theme.net.BaseInitApiRequest.getNetData; +import static com.colorful.keyboard.theme.net.BaseInitApiRequest.initHHYApiStores; + +import android.annotation.SuppressLint; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.graphics.Color; +import android.os.Bundle; +import android.provider.Settings; +import android.text.SpannableString; +import android.text.style.UnderlineSpan; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.fragment.app.Fragment; +import androidx.viewpager2.widget.ViewPager2; + + +import com.anythink.core.api.ATSDK; +import com.colorful.keyboard.theme.ad.AdsInsUtil; +import com.colorful.keyboard.theme.adapter.ViewPager2Adapter; +import com.colorful.keyboard.theme.fragment.KeyboardListFragment; +import com.colorful.keyboard.theme.model.ThemeListBean; +import com.colorful.keyboard.theme.myutil.AppUtilKt; +import com.colorful.keyboard.theme.myutil.ConfigBitmapUtils; +import com.colorful.keyboard.theme.myutil.ImmUtils; +import com.colorful.keyboard.theme.myutil.SPUtils; +import com.colorful.keyboard.theme.net.ApiCallbackCommon; +import com.colorful.keyboard.theme.net.ApiException; +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class MainActivity extends AppCompatActivity { + + private TabLayout tabLayout; + private ViewPager2 viewPager; + private List fragmentList = new ArrayList<>(); + + private LinearLayout loadingLayout; + + private DrawerLayout drawerLayout; + private LinearLayout navLayout; + private TextView tvVersion; + + private RelativeLayout keyboardSettingLayout; + private TextView keyboardNumber; + + private RelativeLayout dialog_step_layout; + private TextView step1Btn; + private TextView step2Btn; + private LinearLayout no_data_layout; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + registerReceiver(); + // AppLovinSdk.getInstance( this ).showMediationDebugger(); + ImmUtils.setStatusBar(this, false, false); + tabLayout = findViewById(R.id.tabLayout); + viewPager = findViewById(R.id.viewPager); + no_data_layout = findViewById(R.id.no_data_layout); + loadingLayout = findViewById(R.id.loadingLayout); + drawerLayout = findViewById(R.id.drawerLayout); + navLayout = findViewById(R.id.nav_view); + ImageView ivSetting = findViewById(R.id.iv_setting); + backToast = Toast.makeText(getBaseContext(), "Press again to exit", Toast.LENGTH_SHORT); + tvVersion = findViewById(R.id.tv_version); + keyboardSettingLayout = findViewById(R.id.keyboard_setting); + dialog_step_layout = findViewById(R.id.dialog_step_layout); + keyboardSettingLayout.setOnClickListener(v -> { + dialog_step_layout.setVisibility(View.VISIBLE); + }); + dialog_step_layout.setOnClickListener(v -> { + dialog_step_layout.setVisibility(View.GONE); + }); + step1Btn = findViewById(R.id.step_1_btn); + step2Btn = findViewById(R.id.step_2_btn); + keyboardNumber = findViewById(R.id.keyboardNumber); + try { + PackageManager packageManager = getPackageManager(); + String packageName = getPackageName(); + PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0); + tvVersion.setText("v" + packageInfo.versionName); + } catch (PackageManager.NameNotFoundException e) { + throw new RuntimeException(e); + } + if (SPUtils.getInstance().getString("bg").isEmpty()) { + ConfigBitmapUtils.saveConfigImgToLocal(this, "https://cdn.kikakeyboard.com/terminal/online/20200331/Us21R82MAD-1585651198.jpg.webp"); + } + + findViewById(R.id.nav_view).setOnClickListener(v -> { + }); + ivSetting.setOnClickListener(view -> { + if (!drawerLayout.isDrawerOpen(findViewById(R.id.nav_view))) { + drawerLayout.openDrawer(findViewById(R.id.nav_view)); + } + }); + LinearLayout llYinsi = findViewById(R.id.ll_yinsi); + llYinsi.setOnClickListener(view -> { + startActivity(new Intent(MainActivity.this, LocalPrivacyAct.class)); + drawerLayout.close(); + }); + LinearLayout llDownload = findViewById(R.id.ll_download); + llDownload.setOnClickListener(v -> { + drawerLayout.close(); + startActivity(new Intent(MainActivity.this, DownloadsActivity.class)); + }); + LinearLayout ll_share = findViewById(R.id.ll_share); + ll_share.setOnClickListener(v -> { + drawerLayout.close(); + AppUtilKt.shareAppInfo(this); + }); + step1Btn.setOnClickListener(v -> { + Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS); + startActivity(intent); + + }); + + step2Btn.setOnClickListener(v -> { + InputMethodManager imeManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); + imeManager.showInputMethodPicker(); + }); + + TextView textView = findViewById(R.id.try_again); // 你的TextView的ID + String text = "Load error, try again!"; + // 创建一个SpannableString并应用下划线 + SpannableString spannableString = new SpannableString(text); + spannableString.setSpan(new UnderlineSpan(), 0, text.length(), 0); + // 将带有下划线的文本设置给TextView + textView.setText(spannableString); + textView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + initData(); + } + }); + initData(); + } + + private void initData(){ + loadingLayout.setVisibility(View.VISIBLE); + no_data_layout.setVisibility(View.GONE); + HashMap hashMap = new HashMap<>(); + hashMap.put("offset", 0); + hashMap.put("fetch_size", 100); + hashMap.put("sign", "a28aadc61c76c754944f6ddb48962c9c"); + getNetData(initHHYApiStores().getCategories(hashMap), new ApiCallbackCommon(this, false) { + @Override + public void onSuccess(ThemeListBean model) { + loadingLayout.setVisibility(View.GONE); + no_data_layout.setVisibility(View.GONE); + fragmentList.clear(); + for (int i = 0; i < model.getData().getSections().size(); i++) { + tabLayout.addTab(tabLayout.newTab()); + KeyboardListFragment photoFragment = new KeyboardListFragment(); + Bundle bundle = new Bundle(); + bundle.putString("id", model.getData().getSections().get(i).getKey()); + photoFragment.setArguments(bundle); + fragmentList.add(photoFragment); + } + + ViewPager2Adapter homeTalentViewPager2Adapter = new ViewPager2Adapter(MainActivity.this, fragmentList); + viewPager.setAdapter(homeTalentViewPager2Adapter); + viewPager.setCurrentItem(0); + viewPager.setOffscreenPageLimit(2); + + TabLayoutMediator mediator = new TabLayoutMediator(tabLayout, viewPager, new TabLayoutMediator.TabConfigurationStrategy() { + @Override + public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) { + String title = model.getData().getSections().get(position).getTitle().trim().toLowerCase(); + tab.setText(title); + } + }); + + mediator.attach(); + + } + + @Override + public void onFailure(ApiException ex) { + loadingLayout.setVisibility(View.GONE); + no_data_layout.setVisibility(View.VISIBLE); + } + }); + } + + @Override + protected void onResume() { + super.onResume(); + updateKeyboardSettingLayout(); + AdsInsUtil.INSTANCE.loadAllAdIsNotCached(this); + } + + @SuppressLint("SetTextI18n") + private void updateKeyboardSettingLayout() { + boolean enabledSet = isMyInputMethodEnabled(this); + boolean defaultSet = isMyInputMethodDefault(this); + + if (enabledSet) { + step1Btn.setBackground(getDrawable(R.drawable.drw_gray_select_bg)); + step1Btn.setText("Step 1:Enabled"); + step1Btn.setTextColor(Color.parseColor("#999999")); + } else { + step1Btn.setBackground(getDrawable(R.drawable.drw_80_btn)); + step1Btn.setText("Step 1:Select"); + step1Btn.setTextColor(Color.parseColor("#000000")); + } + if (defaultSet) { + step2Btn.setBackground(getDrawable(R.drawable.drw_gray_select_bg)); + step2Btn.setText("Step 2:Enabled"); + step1Btn.setTextColor(Color.parseColor("#999999")); + } else { + step2Btn.setBackground(getDrawable(R.drawable.drw_80_btn)); + step2Btn.setText("Step 2:Select"); + step1Btn.setTextColor(Color.parseColor("#000000")); + } + + int number = 0; + if (!enabledSet) { + number += 1; + } + if (!defaultSet) { + number += 1; + } + + keyboardNumber.setText("" + number); + + if (enabledSet && defaultSet) { + keyboardSettingLayout.setVisibility(View.GONE); + } else { + keyboardSettingLayout.setVisibility(View.VISIBLE); + } + } + + private BroadcastReceiver receiver; + + private void registerReceiver() { + IntentFilter filter = new IntentFilter(Intent.ACTION_INPUT_METHOD_CHANGED); + receiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + updateKeyboardSettingLayout(); + boolean enabledSet = isMyInputMethodEnabled(MainActivity.this); + boolean defaultSet = isMyInputMethodDefault(MainActivity.this); + if (enabledSet && defaultSet) { + dialog_step_layout.setVisibility(View.GONE); + } else { + dialog_step_layout.setVisibility(View.VISIBLE); + } + } + }; + registerReceiver(receiver, filter); + } + + private void unregisterReceiver() { + if (receiver != null) { + unregisterReceiver(receiver); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unregisterReceiver(); + } + + + private long backPressedTime = 0; + private Toast backToast; + + @Override + public void onBackPressed() { + if (backPressedTime + 2000 > System.currentTimeMillis()) { + super.onBackPressed(); + backToast.cancel(); + } else { + backToast.show(); + } + backPressedTime = System.currentTimeMillis(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/PreviewActivity.kt b/app/src/main/java/com/colorful/keyboard/theme/PreviewActivity.kt new file mode 100644 index 0000000..7bb5f2a --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/PreviewActivity.kt @@ -0,0 +1,174 @@ +package com.colorful.keyboard.theme + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.graphics.BitmapFactory +import android.graphics.Color +import android.graphics.drawable.BitmapDrawable +import android.os.Bundle +import android.provider.Settings +import android.view.View +import android.view.inputmethod.InputMethodManager +import androidx.appcompat.app.AppCompatActivity +import com.colorful.keyboard.theme.ad.AdsInsUtil +import com.colorful.keyboard.theme.databinding.ColorfulPreviewActivityBinding +import com.colorful.keyboard.theme.myutil.currentlyThemeUFileString +import com.colorful.keyboard.theme.myutil.getBitmapXXDrawable +import com.colorful.keyboard.theme.myutil.isMyInputMethodDefault +import com.colorful.keyboard.theme.myutil.isMyInputMethodEnabled +import com.colorful.keyboard.theme.myutil.loadAndBlurImage +import com.gyf.immersionbar.ktx.immersionBar + +class PreviewActivity : AppCompatActivity() { + companion object { + const val KEY_PREVIEW_URL = "key_preview_url" + } + + private lateinit var binding: ColorfulPreviewActivityBinding + + private var themeUrl = "" + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ColorfulPreviewActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + AdsInsUtil.showAdRandomModeAndTiming(this) + initBar() + themeUrl = intent.getStringExtra(KEY_PREVIEW_URL).toString() + registerReceiver() + initView() + AdsInsUtil.loadAllAdIsNotCached(this) + } + + private fun initBar() { + immersionBar { + statusBarDarkFont(true) + statusBarView(binding.view) + } + } + + override fun onResume() { + super.onResume() + updateSetMyInputMethod() + } + + override fun onBackPressed() { + super.onBackPressed() + } + + private fun initView() { + val currentlyThemeUFile = currentlyThemeUFileString(this, themeUrl) + loadAndBlurImage( + this, + getBitmapXXDrawable(this, currentlyThemeUFile, "keyboard_preview_screenshot.jpg"), + binding.previewIv + ) + + val imagePath = + "$currentlyThemeUFile/res/drawable-xxhdpi-v4/keyboard_preview.jpg" + val bitmap = BitmapFactory.decodeFile(imagePath) + val background = BitmapDrawable(resources, bitmap) + binding.keyboardIv.background = background + + binding.backBtn.setOnClickListener { onBackPressed() } + + binding.activateBtn.setOnClickListener { + binding.dialogStepLayout.visibility = View.VISIBLE + } + + binding.step1Btn.setOnClickListener { + val intent = Intent(Settings.ACTION_INPUT_METHOD_SETTINGS) + startActivity(intent) + } + + binding.step2Btn.setOnClickListener { + val imeManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager + imeManager.showInputMethodPicker() + } + + binding.dialogStepLayout.setOnClickListener { + binding.dialogStepLayout.visibility = View.GONE + } + } + + private fun updateSetMyInputMethod() { + val enabled = isMyInputMethodEnabled(this) + val default = isMyInputMethodDefault(this) + if (enabled) { + binding.step1Btn.background = getDrawable(R.drawable.drw_gray_select_bg) + binding.step1Btn.text = "Step 1:Enabled" + binding.step1Btn.setTextColor(Color.parseColor("#999999")) + } else { + binding.step1Btn.background = getDrawable(R.drawable.drw_80_btn) + binding.step1Btn.text = "Step 1:Select" + binding.step1Btn.setTextColor(Color.parseColor("#000000")) + } + if (default) { + binding.step2Btn.background = getDrawable(R.drawable.drw_gray_select_bg) + binding.step2Btn.text = "Step 2:Enabled" + binding.step1Btn.setTextColor(Color.parseColor("#999999")) + } else { + binding.step2Btn.background = getDrawable(R.drawable.drw_80_btn) + binding.step2Btn.text = "Step 2:Select" + binding.step1Btn.setTextColor(Color.parseColor("#000000")) + } + + if (enabled && default) { + binding.edit.visibility = View.VISIBLE + binding.tv.visibility = View.GONE + } else { + binding.edit.visibility = View.GONE + binding.tv.visibility = View.VISIBLE + } + + if (enabled && default) { + binding.unauthorizedLayout.visibility = View.INVISIBLE + + showKeyboard(binding.edit) + } + } + + private var receiver: BroadcastReceiver? = null + private fun registerReceiver() { + val filter = IntentFilter(Intent.ACTION_INPUT_METHOD_CHANGED) + receiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + updateSetMyInputMethod() + val enabled = isMyInputMethodEnabled(this@PreviewActivity) + val default = isMyInputMethodDefault(this@PreviewActivity) + if (enabled && default) { + binding.dialogStepLayout.visibility = View.GONE + binding.edit.visibility = View.VISIBLE + binding.tv.visibility = View.GONE + showKeyboard(binding.edit) + } else { + binding.dialogStepLayout.visibility = View.VISIBLE + } + } + } + registerReceiver(receiver, filter) + } + + private fun unregisterReceiver() { + if (receiver != null) { + unregisterReceiver(receiver) + } + } + + override fun onDestroy() { + super.onDestroy() + unregisterReceiver() + } + + private fun showKeyboard(view: View) { + view.postDelayed({ + view.requestFocus() + val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT) + }, 1000) // 设置延迟时间 + + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/SettingActivity.java b/app/src/main/java/com/colorful/keyboard/theme/SettingActivity.java new file mode 100644 index 0000000..6a5eb16 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/SettingActivity.java @@ -0,0 +1,49 @@ +package com.colorful.keyboard.theme; + +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.colorful.keyboard.theme.myutil.ImmUtils; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + + +public class SettingActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_setting); + ImmUtils.setStatusBar(this, false, false); + TextView tvVersion = findViewById(R.id.tv_version); + ImageView ivBack = findViewById(R.id.iv_back_setting); + LinearLayout llyinsi = findViewById(R.id.ll_yinsi); + PackageManager packageManager = getPackageManager(); + String packageName = getPackageName(); + try { + PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0); + tvVersion.setText("v" + packageInfo.versionName); + } catch (PackageManager.NameNotFoundException e) { + throw new RuntimeException(e); + } + llyinsi.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + startActivity(new Intent(SettingActivity.this, LocalPrivacyAct.class)); + } + }); + ivBack.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + finish(); + } + }); + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/TestFragment.java b/app/src/main/java/com/colorful/keyboard/theme/TestFragment.java new file mode 100644 index 0000000..cc6951b --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/TestFragment.java @@ -0,0 +1,7 @@ +package com.colorful.keyboard.theme; + +import android.preference.PreferenceFragment; + + +public class TestFragment extends PreferenceFragment { +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/ThemeSettingsActivity.java b/app/src/main/java/com/colorful/keyboard/theme/ThemeSettingsActivity.java new file mode 100644 index 0000000..063b97f --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ThemeSettingsActivity.java @@ -0,0 +1,286 @@ +package com.colorful.keyboard.theme; + +import static com.colorful.keyboard.theme.net.BaseInitApiRequest.getNetData; +import static com.colorful.keyboard.theme.net.BaseInitApiRequest.initHHYApiStores; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.provider.Settings; +import android.util.Log; +import android.view.View; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +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.colorful.keyboard.theme.constant.ConfigConstant; +import com.colorful.keyboard.theme.latin.LatinIME; +import com.colorful.keyboard.theme.model.ThemeDetailsBean; +import com.colorful.keyboard.theme.myutil.ConfigFileUtils; +import com.colorful.keyboard.theme.myutil.ImmUtils; +import com.colorful.keyboard.theme.myutil.SPUtils; +import com.colorful.keyboard.theme.net.ApiCallbackCommon; + +import java.io.File; +import java.util.HashMap; + +public class ThemeSettingsActivity extends AppCompatActivity { + + private String key; + private String title; + private TextView tvStepOne; + private TextView tvStepTwo; + private LinearLayout ll_setting; + private LinearLayout ll_step; + private TextView tv_to_setting; + ThemeDetailsBean themeDetailsBean; + boolean isCurrentSetting = false; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_setting_theme); + ImmUtils.setStatusBar(this,false,false); + title = getIntent().getStringExtra("title"); + key = getIntent().getStringExtra("key"); + String url = getIntent().getStringExtra("url"); + + ImageView imageView = findViewById(R.id.iv_back_setting); + ll_setting = findViewById(R.id.ll_setting); + ll_step = findViewById(R.id.ll_step); + tv_to_setting = findViewById(R.id.tv_to_setting); + + + tvStepOne = findViewById(R.id.tv_step_one); + tvStepTwo = findViewById(R.id.tv_step_two); + + ImageView iv_theme = findViewById(R.id.iv_theme); + Glide.with(this).load(url).into(iv_theme); + TextView tv_setting_title = findViewById(R.id.tv_setting_title); + tv_setting_title.setText(title); + + imageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + finish(); + } + }); + + getInfo(); + + /* new MaxAdInputManager(this, Constant.adIdSee, new AdInputListener() { + @Override + public void adShow() { + } + + @Override + public void adClose() { + } + });*/ + + + } + + @Override + protected void onResume() { + super.onResume(); + if(isInputMethodOfThisImeEnabled()){ + tvStepOne.setBackground(getResources().getDrawable(R.drawable.shape_green)); + }else { + tvStepOne.setBackground(getResources().getDrawable(R.drawable.shape_grey)); + } + String string = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); + + boolean isMy = string.contains("com.colorful.keyboard.theme"); + + if(isMy){ + tvStepTwo.setBackground(getResources().getDrawable(R.drawable.shape_green)); + }else { + tvStepTwo.setBackground(getResources().getDrawable(R.drawable.shape_grey)); + } + Log.e("666",string); + + tvStepOne.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if(!isInputMethodOfThisImeEnabled()){ + Intent intent = new Intent(android.provider.Settings.ACTION_INPUT_METHOD_SETTINGS); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } + } + }); + + tvStepTwo.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if(!isMy){ + + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(INPUT_METHOD_ACTION); + registerReceiver(inputMethodChangeReceiver, intentFilter); + + try { + ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).showInputMethodPicker(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + }); + + if(isMy && isInputMethodOfThisImeEnabled()){ + ll_step.setVisibility(View.GONE); + ll_setting.setVisibility(View.VISIBLE); + }else{ + ll_step.setVisibility(View.VISIBLE); + ll_setting.setVisibility(View.GONE); + } + + tv_to_setting.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if(!isCurrentSetting){ + if (null!=themeDetailsBean){ + SPUtils.getInstance().put("id",themeDetailsBean.getData().getItem().getKey()); + /* new MaxAdInputManager(ThemeSettingsActivity.this, Constant.adIdSetting, new AdInputListener() { + @Override + public void adShow() { + } + + @Override + public void adClose() { + saveConfigImgToLocal(ThemeSettingsActivity.this,themeDetailsBean.getData().getItem().getThemeContent().getImgBanner()); + } + });*/ + } + } + } + }); + } + + public void saveConfigImgToLocal(Context context, String url) { + Glide.with(context) + .downloadOnly() + .load(url) + .listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + return false; + } + + + @Override + public boolean onResourceReady(File resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + configSaveToAlbum(context, resource.getAbsolutePath()); + return false; + } + }) + .preload(); + + } + + public void configSaveToAlbum(Context context, String srcPath) { + String imageSrc = context.getExternalFilesDir("input").getAbsolutePath() +"image/"+ System.currentTimeMillis() + ".png"; + File file = new File(imageSrc); + SPUtils.getInstance().put("bg",imageSrc); + + App.Companion.getApp().stopService(new Intent(App.Companion.getApp(), LatinIME.class)); + App.Companion.getApp().startService(new Intent(App.Companion.getApp(),LatinIME.class)); + ConfigConstant.isNeedSetting = true; + Toast.makeText(ThemeSettingsActivity.this,"Success",Toast.LENGTH_SHORT).show(); + if(SPUtils.getInstance().getString("id") .equals(themeDetailsBean.getData().getItem().getKey()) ){ + isCurrentSetting = true; + tv_to_setting.setBackground(getResources().getDrawable(R.drawable.shape_green)); + }else{ + tv_to_setting.setBackground(getResources().getDrawable(R.drawable.shape_grey)); + isCurrentSetting = false; + } + boolean isCopySuccess = false; + try { + isCopySuccess = ConfigFileUtils.configCopy(srcPath, file.getAbsolutePath(),false); + } catch (Exception e) { + e.printStackTrace(); + } + /*if (isCopySuccess) { + try { + MediaStore.Images.Media.insertImage(context.getContentResolver(), + file.getAbsolutePath(),file.getName() , null); + context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse(file.getAbsolutePath()))); + Toast.makeText(context,"successfully",Toast.LENGTH_SHORT).show(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + } else { + + }*/ + } + + + private static final String INPUT_METHOD_ACTION = "android.intent.action.INPUT_METHOD_CHANGED"; + + private BroadcastReceiver inputMethodChangeReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(INPUT_METHOD_ACTION)) { + //监听到输入法发生改变 + onResume(); + } + } + }; + + + private boolean isInputMethodOfThisImeEnabled() { + final InputMethodManager imm = + (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + final String imePackageName = getPackageName(); + for (final InputMethodInfo imi : imm.getEnabledInputMethodList()) { + if (imi.getPackageName().equals(imePackageName)) { + return true; + } + } + return false; + } + + private void getInfo(){ + HashMap hashMap = new HashMap<>(); + hashMap.put("sign","a28aadc61c76c754944f6ddb48962c9c"); + getNetData(initHHYApiStores().getDetailsTheme(key,hashMap), + new ApiCallbackCommon(this, false) { + @Override + public void onSuccess(ThemeDetailsBean model) { + themeDetailsBean = model; + Log.e("666",SPUtils.getInstance().getString("id")); + Log.e("666",model.getData().getItem().getKey()); + Log.e("666",model.getData().getItem().getKey()); + Log.e("666",(SPUtils.getInstance().getString("id") == model.getData().getItem().getKey())+""); + if(SPUtils.getInstance().getString("id") .equals(model.getData().getItem().getKey()) ){ + isCurrentSetting = true; + tv_to_setting.setBackground(getResources().getDrawable(R.drawable.shape_green)); + }else{ + tv_to_setting.setBackground(getResources().getDrawable(R.drawable.shape_grey)); + isCurrentSetting = false; + } + } + + @Override + public void onFailure(com.colorful.keyboard.theme.net.ApiException ex) { + + } + }); + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/AdInstLoad.kt b/app/src/main/java/com/colorful/keyboard/theme/ad/AdInstLoad.kt new file mode 100644 index 0000000..a03abcc --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/AdInstLoad.kt @@ -0,0 +1,74 @@ +package com.colorful.keyboard.theme.ad + +import android.app.Activity +import android.util.Log +import com.anythink.core.api.ATAdInfo +import com.anythink.core.api.AdError +import com.anythink.interstitial.api.ATInterstitial +import com.anythink.interstitial.api.ATInterstitialListener + +class AdInstLoad { + private var mPlace: String + private var adLoadListener: LoadListener? = null + private var activity: Activity? = null + + constructor(activity: Activity, place: String, listener: LoadListener?) { + this.mPlace = place + this.adLoadListener = listener + this.activity = activity + init() + } + + constructor(place: String, listener: LoadListener?) { + this.mPlace = place + this.adLoadListener = listener + init() + } + + private fun init() { + + val atInterstitial = ATInterstitial(activity, mPlace) + atInterstitial.setAdListener(object : ATInterstitialListener { + override fun onInterstitialAdLoaded() { + val info = atInterstitial.checkAdStatus().atTopAdInfo + + InstAdCacheManager.instance.setAdCache(mPlace, atInterstitial) + adLoadListener?.loaded(info) + } + + override fun onInterstitialAdLoadFail(adError: AdError?) { + adLoadListener?.loadFailed(adError) + + Log.d("ocean","onInterstitialAdLoadFail->${adError} ") + + Log.d("ocean","AdError.getFullErrorInfo()->${adError?.fullErrorInfo}") + } + + override fun onInterstitialAdClicked(p0: ATAdInfo?) { + + } + + override fun onInterstitialAdShow(p0: ATAdInfo?) { + + } + + override fun onInterstitialAdClose(p0: ATAdInfo?) { + + } + + override fun onInterstitialAdVideoStart(p0: ATAdInfo?) { + + } + + override fun onInterstitialAdVideoEnd(p0: ATAdInfo?) { + + } + + override fun onInterstitialAdVideoError(p0: AdError?) { + + } + + }) + atInterstitial.load() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/AdInstShower.kt b/app/src/main/java/com/colorful/keyboard/theme/ad/AdInstShower.kt new file mode 100644 index 0000000..1b96ccb --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/AdInstShower.kt @@ -0,0 +1,68 @@ +package com.colorful.keyboard.theme.ad + +import android.app.Activity +import com.anythink.core.api.ATAdInfo +import com.anythink.core.api.AdError +import com.anythink.interstitial.api.ATInterstitialListener +import com.colorful.keyboard.theme.App + +class AdInstShower { + private var mPlace: String + private var showListener: ShowListener? = null + private var activity: Activity? = null + + constructor(activity: Activity, place: String, showListener: ShowListener?) { + this.mPlace = place + this.showListener = showListener + this.activity = activity + init() + } + + constructor(place: String, showListener: ShowListener?) { + this.mPlace = place + this.showListener = showListener + init() + } + + private fun init() { + val atInterstitial = InstAdCacheManager.instance.getAdCache(mPlace) + atInterstitial?.setAdListener(object : ATInterstitialListener { + override fun onInterstitialAdLoaded() { + + } + + override fun onInterstitialAdLoadFail(p0: AdError?) { + + } + + override fun onInterstitialAdClicked(p0: ATAdInfo?) { + showListener?.onAdClicked() + } + + override fun onInterstitialAdShow(p0: ATAdInfo?) { + showListener?.onAdShown(p0) + App.app.lastAdDisplayTime.set(System.currentTimeMillis()) + } + + override fun onInterstitialAdClose(p0: ATAdInfo?) { + showListener?.onAdClosed() + } + + override fun onInterstitialAdVideoStart(p0: ATAdInfo?) { + + } + + override fun onInterstitialAdVideoEnd(p0: ATAdInfo?) { + + } + + override fun onInterstitialAdVideoError(adError: AdError?) { + showListener?.onAdShowFailed(AdShowFailed(adError.toString())) + } + + }) + if (atInterstitial?.isAdReady == true) { + atInterstitial.show(activity) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/AdShowFailed.kt b/app/src/main/java/com/colorful/keyboard/theme/ad/AdShowFailed.kt new file mode 100644 index 0000000..6528f84 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/AdShowFailed.kt @@ -0,0 +1,5 @@ +package com.colorful.keyboard.theme.ad + +data class AdShowFailed( + val msg: String = "", +) \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/AdsInsUtil.kt b/app/src/main/java/com/colorful/keyboard/theme/ad/AdsInsUtil.kt new file mode 100644 index 0000000..af2f88a --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/AdsInsUtil.kt @@ -0,0 +1,90 @@ +package com.colorful.keyboard.theme.ad + +import android.app.Activity +import com.colorful.keyboard.theme.App +import com.colorful.keyboard.theme.myutil.AppSharedPreferences +import com.unity3d.services.ads.api.Show +import java.util.Random + +object AdsInsUtil { + + object Placement { + const val TOP_ON_AD_ONE = "n66b1cf2f2c70c" + const val TOP_ON_AD_TOW = "n66b1cf2f04a38" + const val TOP_ON_AD_THREE = "n66b1cf2ecd817" + + val adPlaceAllList = listOf( + TOP_ON_AD_ONE, + TOP_ON_AD_TOW, + TOP_ON_AD_THREE + ) + } + + fun loadSplashAllAd(act: Activity) { + Placement.adPlaceAllList.drop(1).forEach { placement -> + loadAdIfNotCached(act, placement) + } + } + + fun loadAllAdIsNotCached(act: Activity) { + Placement.adPlaceAllList.forEach { placement -> + loadAdIfNotCached(act, placement) + } + } + + fun loadAdIfNotCached(act: Activity, placement: String, listener: LoadListener? = null) { + if (act.isFinishing || canShowAd(placement)) return + loadAd(act, placement, listener) + } + + fun showAdRandomModeAndTiming(act: Activity, listener: ShowListener? = null) { + val adPlace: MutableList = ArrayList() + Placement.adPlaceAllList.forEach { placement -> + if (canShowAd(placement)) { + adPlace.add(placement) + } + } + if (adPlace.isNotEmpty()) { + val placeId = Random().nextInt(adPlace.size) + val place = adPlace[placeId] + showAd(act, place, listener) + } + } + + fun canShowAd(adID: String): Boolean { + InstAdCacheManager.instance.getAdCache(adID)?.let { + return it.isAdReady + } ?: let { + return false + } + } + + fun loadAd( + act: Activity, + adID: String, + loadListener: LoadListener? + ): AdInstLoad { + return AdInstLoad(act, adID, loadListener) + } + + fun showAd( + act: Activity, + adID: String, + listener: ShowListener? + ): AdInstShower { + return AdInstShower(act, adID, listener) + } + + fun showAdTiming(act: Activity, placement: String, listener: ShowListener? = null) { + //当前时间减去旧时间,才展示广告(满足间隔时间才show广告) + val showAdIntervalTime = AppSharedPreferences(App.app).getShowAdIntervalTime() + if (System.currentTimeMillis() - App.app.lastAdDisplayTime.get() >= showAdIntervalTime) { + //判断当前广告位是否可以show,不能show则判断补位广告是否可以show。 + if (act.isFinishing || !canShowAd(placement)) { + showAd(act, placement, listener) + } else { + showAd(act, placement, listener) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/InstAdCacheManager.kt b/app/src/main/java/com/colorful/keyboard/theme/ad/InstAdCacheManager.kt new file mode 100644 index 0000000..0522d26 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/InstAdCacheManager.kt @@ -0,0 +1,35 @@ +package com.colorful.keyboard.theme.ad + +import com.anythink.interstitial.api.ATInterstitial + +class InstAdCacheManager { + private val mAdCacheDict: MutableMap = mutableMapOf() + + companion object { + val instance: InstAdCacheManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { + InstAdCacheManager() + } + } + + fun setAdCache(place: String, adCache: ATInterstitial) { + mAdCacheDict[place] = adCache + } + + fun getAdCache(place: String): ATInterstitial? { + return mAdCacheDict[place] + } + + fun getLoadedInstCount(): Int { + var count = 0 + try { + mAdCacheDict.forEach { (key, value) -> + if (value.isAdReady) { + count += 1 + } + } + } catch (_: Exception) { + + } + return count + } +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/LoadListener.kt b/app/src/main/java/com/colorful/keyboard/theme/ad/LoadListener.kt new file mode 100644 index 0000000..64541ee --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/LoadListener.kt @@ -0,0 +1,10 @@ +package com.colorful.keyboard.theme.ad + +import com.anythink.core.api.ATAdInfo +import com.anythink.core.api.AdError + + +interface LoadListener { + fun loadFailed(error: AdError?) {} + fun loaded(ad: ATAdInfo) {} +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/ShowListener.kt b/app/src/main/java/com/colorful/keyboard/theme/ad/ShowListener.kt new file mode 100644 index 0000000..1e4df93 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/ShowListener.kt @@ -0,0 +1,11 @@ +package com.colorful.keyboard.theme.ad + +import com.anythink.core.api.ATAdInfo +import com.colorful.keyboard.theme.ad.AdShowFailed + +interface ShowListener { + fun onAdShown(ad: ATAdInfo?) {} + fun onAdShowFailed(error: AdShowFailed?) {} + fun onAdClosed() {} + fun onAdClicked() {} +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/async/Async.java b/app/src/main/java/com/colorful/keyboard/theme/ad/async/Async.java new file mode 100644 index 0000000..ff42f55 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/async/Async.java @@ -0,0 +1,83 @@ +package com.colorful.keyboard.theme.ad.async; + +import android.os.Handler; +import android.os.Looper; + +import java.util.concurrent.Callable; +import java.util.concurrent.Future; + +public class Async { + private static ThreadPoolExecutorWrapper sThreadPoolExecutorWrapper; + + private static ThreadPoolExecutorWrapper getThreadPoolExecutorWrapper() { + if (sThreadPoolExecutorWrapper == null) { + synchronized (Async.class) { + if (sThreadPoolExecutorWrapper == null) { + sThreadPoolExecutorWrapper = new ThreadPoolExecutorWrapper(12, 12, 10); +// if (BuildConfig.DEBUG) +// LogUtil.d(LogFilterDef.APP_INIT, LogHelper.getFileLineMethod(1)); + } + } + } + + return sThreadPoolExecutorWrapper; + } + + public static void run(Runnable task) { + getThreadPoolExecutorWrapper().executeTask(task); + } + + public static Future submit(Callable task) { + return getThreadPoolExecutorWrapper().submitTask(task); + } + + public static boolean isMainThread() { + return Thread.currentThread() == Looper.getMainLooper().getThread(); + } + + public static void schedule(long delay, Runnable task) { + getThreadPoolExecutorWrapper().scheduleTask(delay, task); + } + + public static void scheduleTaskAtFixedRateIgnoringTaskRunningTime(long initialDelay, long period, Runnable task) { + getThreadPoolExecutorWrapper().scheduleTaskAtFixedRateIgnoringTaskRunningTime(initialDelay, period, task); + } + + public static void scheduleTaskAtFixedRateIncludingTaskRunningTime(long initialDelay, long period, Runnable task) { + getThreadPoolExecutorWrapper().scheduleTaskAtFixedRateIncludingTaskRunningTime(initialDelay, period, task); + } + + public static boolean removeScheduledTask(Runnable task) { + return getThreadPoolExecutorWrapper().removeScheduledTask(task); + } + + public static void scheduleTaskOnUiThread(long delay, Runnable task) { + getThreadPoolExecutorWrapper().scheduleTaskOnUiThread(delay, task); + } + + public static void removeScheduledTaskOnUiThread(Runnable task) { + getThreadPoolExecutorWrapper().removeScheduledTaskOnUiThread(task); + } + + public static void runOnUiThread(Runnable task) { + getThreadPoolExecutorWrapper().runTaskOnUiThread(task); + } + + public static Handler getMainHandler() { + return getThreadPoolExecutorWrapper().getMainHandler(); + } + + /* + single background thread to execute Job + */ + public static void scheduleInQueue(Runnable task) { + getThreadPoolExecutorWrapper().scheduleOnQueue(task); + } + + public static void shutdown() { + if (sThreadPoolExecutorWrapper != null) { + sThreadPoolExecutorWrapper.shutdown(); + sThreadPoolExecutorWrapper = null; + } + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/async/HandlerPoster.java b/app/src/main/java/com/colorful/keyboard/theme/ad/async/HandlerPoster.java new file mode 100644 index 0000000..738d356 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/async/HandlerPoster.java @@ -0,0 +1,140 @@ +package com.colorful.keyboard.theme.ad.async; + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.SystemClock; + +import java.util.LinkedList; +import java.util.Queue; + +public class HandlerPoster extends Handler { + + private final int ASYNC = 1; + + private final int SYNC = 2; + + private final Queue asyncPool; + + private final Queue syncPool; + + private final int maxMillisInsideHandleMessage; + + private boolean asyncActive;//执行状态。避免重复发送消息导致消息队列过多 + + private boolean syncActive;//执行状态。避免重复发送消息导致消息队列过多 + + HandlerPoster(Looper looper, int maxMillisInsideHandleMessage) { + super(looper); + this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage; + asyncPool = new LinkedList(); + syncPool = new LinkedList(); + } + + void dispose() { + this.removeCallbacksAndMessages(null); + this.asyncPool.clear(); + this.syncPool.clear(); + } + + void async(Runnable runnable) throws Exception { + synchronized (asyncPool) { + asyncPool.offer(runnable); + //判断当前是否有异步任务正在执行 + if (!asyncActive) { + asyncActive = true; + if (!sendMessage(obtainMessage(ASYNC))) { + throw new Exception("Could not send handler message"); + } + } + } + } + + void sync(SyncPost post) throws Exception { + synchronized (syncPool) { + syncPool.offer(post); + //判断当前是否有同步任务正在执行 + if (!syncActive) { + syncActive = true; + if (!sendMessage(obtainMessage(SYNC))) { + throw new Exception("Could not send handler message"); + } + } + } + } + + @Override + public void handleMessage(Message msg) { + if (msg.what == ASYNC) { + boolean rescheduled = false; + try { + //当执行完一个任务后就判断一次是否超过时间限制,如果超过,那么不管队列中的任务是否执行完成都退出,同时发起一个新的消息到Handler循环队列 + //在while部分,使用poll从队列取出一个任务,判断是否为空,如果为空进入队列同步块;然后再取一次,再次判断。 + //如果恰巧在进入同步队列之前有新的任务来了,那么第二次取到的当然就不是 NULL也就会继续执行下去。 + //反之,如果还是为空;那么重置当前队列的状态为false,同时跳出循环。 + long started = SystemClock.uptimeMillis(); + while (true) { + Runnable runnable = null; + synchronized (asyncPool){ + runnable = asyncPool.size()==0?null:asyncPool.poll();//2018.12.24 add by xw 如果为空就去null + } + if (runnable == null) { + synchronized (asyncPool) { + // Check again, this time in synchronized + runnable = asyncPool.poll(); + if (runnable == null) { + asyncActive = false; + return; + } + } + } + runnable.run(); + long timeInMethod = SystemClock.uptimeMillis() - started; + if (timeInMethod >= maxMillisInsideHandleMessage) { + if (!sendMessage(obtainMessage(ASYNC))) { + throw new Exception("Could not send handler message"); + } + rescheduled = true; + return; + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + asyncActive = rescheduled; + } + } else if (msg.what == SYNC) { + boolean rescheduled = false; + try { + long started = SystemClock.uptimeMillis(); + while (true) { + SyncPost post = syncPool.poll(); + if (post == null) { + synchronized (syncPool) { + // Check again, this time in synchronized + post = syncPool.poll(); + if (post == null) { + syncActive = false; + return; + } + } + } + post.run(); + long timeInMethod = SystemClock.uptimeMillis() - started; + if (timeInMethod >= maxMillisInsideHandleMessage) { + if (!sendMessage(obtainMessage(SYNC))) { + throw new Exception("Could not send handler message"); + } + rescheduled = true; + return; + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + syncActive = rescheduled; + } + } else + super.handleMessage(msg); + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/async/MainThreadSwitcher.java b/app/src/main/java/com/colorful/keyboard/theme/ad/async/MainThreadSwitcher.java new file mode 100644 index 0000000..cf9e092 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/async/MainThreadSwitcher.java @@ -0,0 +1,73 @@ +package com.colorful.keyboard.theme.ad.async; + +import android.os.Looper; + +/** + * 网上找到的关于子线程切换到主线程的代码,实现子线程任意时刻切换到主线程,并可选择地阻塞子线程。 + * 此方案避免handler满天飞的情况。 + * 参考资料:http://c.jinhusns.com/cms/c-884 + * Created by DonWZ on 2016-10-18 + */ +public class MainThreadSwitcher { + private static HandlerPoster mainPoster = null; + + private static HandlerPoster getMainPoster() { + if (mainPoster == null) { + synchronized (MainThreadSwitcher.class) { + if (mainPoster == null) { + mainPoster = new HandlerPoster(Looper.getMainLooper(), 500);//限制主线程单次运行时间 + } + } + } + return mainPoster; + } + + /** + * Asynchronously. + * The child thread asynchronous run relative to the main thread, + * not blocking the child thread + * @param runnable + * Runnable Interface + */ + public static void runOnMainThreadAsync(Runnable runnable) { + if (Looper.myLooper() == Looper.getMainLooper()) { + runnable.run(); + return; + } + try { + getMainPoster().async(runnable); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * + * Synchronously. + * The child thread relative thread synchronization operation, + * blocking the child thread, + * thread for the main thread to complete + * @param runnable + * Runnable Interface + */ + public static void runOnMainThreadSync(Runnable runnable) { + if (Looper.myLooper() == Looper.getMainLooper()) { + runnable.run(); + return; + } + SyncPost poster = new SyncPost(runnable); + try { + getMainPoster().sync(poster); + } catch (Exception e) { + e.printStackTrace(); + } + poster.waitRun(); + } + + public static void dispose() { + if (mainPoster != null) { + mainPoster.dispose(); + mainPoster = null; + } + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/async/SyncPost.java b/app/src/main/java/com/colorful/keyboard/theme/ad/async/SyncPost.java new file mode 100644 index 0000000..76342db --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/async/SyncPost.java @@ -0,0 +1,44 @@ +package com.colorful.keyboard.theme.ad.async; + +public class SyncPost { + + boolean end = false; + + Runnable runnable; + + SyncPost(Runnable runnable) { + this.runnable = runnable; + } + + public void run() { + //进入同步块,然后调用Runnable接口的run方法。同时在执行完成后将end重置为true; + //然后调用this.notifyAll();通知等待的部分可以继续了,当然有这样的情况;假如在进入该同步块的时候子线程还未执行到this.wait();部分呢? + //所以我们为此准备了end和try。 + synchronized (this) { + runnable.run(); + end = true; + try { + this.notifyAll(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public void waitRun() { + //首先判断状态,如果状态已经变了,那么证明子线程执行到此处时,主线程已经执行了void_run()。 + //所以也就不用进入同步块进行等待了。反之进入等待直到主线程调用this.notifyAll(); + if (!end) { + synchronized (this) { + if (!end) { + try { + this.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + } + +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/async/TaskQueue.java b/app/src/main/java/com/colorful/keyboard/theme/ad/async/TaskQueue.java new file mode 100644 index 0000000..063d954 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/async/TaskQueue.java @@ -0,0 +1,46 @@ +package com.colorful.keyboard.theme.ad.async; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +public class TaskQueue extends Thread{ + private BlockingQueue mQueue; + + public TaskQueue() { + mQueue = new LinkedBlockingQueue(); + } + + public TaskQueue(String name) { + this(); + setName(name); + } + + public void stopTaskQueue() { + // use 'Poison Pill Shutdown' to stop the task queue + // add a non-Runnable object, which will be recognized as the command + // by the thread to break the infinite loop + mQueue.add(new Object()); + } + + public void scheduleTask(Runnable task) { + mQueue.add(task); + } + + @Override + public void run() { + while (true) { + try { + Object obj = mQueue.take(); + + if (obj instanceof Runnable) { + ((Runnable) obj).run(); + obj = null; + } else { + break; + } + + } catch (InterruptedException e) { + } + } + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/ad/async/ThreadPoolExecutorWrapper.java b/app/src/main/java/com/colorful/keyboard/theme/ad/async/ThreadPoolExecutorWrapper.java new file mode 100644 index 0000000..7ba4c24 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/ad/async/ThreadPoolExecutorWrapper.java @@ -0,0 +1,158 @@ +package com.colorful.keyboard.theme.ad.async; + +import android.os.Handler; +import android.os.Looper; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class ThreadPoolExecutorWrapper { + private static final Long IDLE_THREAD_KEEP_ALIVE_TIME = 60L; + private ExecutorService mThreadPoolExecutor;//normal thread pool + private ScheduledThreadPoolExecutor mScheduledThreadPoolExecutor;//can schedule task thread pool + private Handler mMainHandler; + private TaskQueue mActionQueue; + private Map mScheduledJobRecord = new HashMap<>();//ScheduledThreadPoolExecutor will wrap Runnable, so we record this + private Object mScheduledJobRecordMutex = new Object(); + + /* + maxThreadCount:thread pool max thread count + activeThreadCount:thread pool min thread count even if all thread is idle + IDLE_THREAD_KEEP_ALIVE_TIME:IDLE thread will be shutdown when TIME_OUT if (maxThreadCount - activeThreadCount) > 0 + */ + public ThreadPoolExecutorWrapper(int activeThreadCount, int maxThreadCount, int maxScheTaskThread) { + mThreadPoolExecutor = new ThreadPoolExecutor(activeThreadCount, maxThreadCount, + IDLE_THREAD_KEEP_ALIVE_TIME, TimeUnit.SECONDS, + new LinkedBlockingQueue()); + + if (maxScheTaskThread > 0) { + mScheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(maxScheTaskThread); + } + + mMainHandler = new Handler(Looper.getMainLooper()); + mActionQueue = new TaskQueue(Async.class.getName()); + mActionQueue.start(); + } + + public void executeTask(Runnable task) { + if (task == null) { + return; + } + + mThreadPoolExecutor.execute(task); + } + + public Future submitTask(Callable task) { + return mThreadPoolExecutor.submit(task); + } + + public void scheduleTask(long delay, Runnable task) { + if (task == null) { + return; + } + mScheduledThreadPoolExecutor.schedule(task, delay, TimeUnit.MILLISECONDS); + } + + public void scheduleTaskAtFixedRateIgnoringTaskRunningTime(long initialDelay, long period, Runnable task) { + if (task == null) { + return; + } + + synchronized (mScheduledJobRecordMutex) { + if (mScheduledJobRecord.containsKey(task.hashCode())) { + return; + } + + mScheduledJobRecord.put(task.hashCode(), mScheduledThreadPoolExecutor.scheduleAtFixedRate(task, initialDelay, period, TimeUnit.MILLISECONDS)); + } + } + + public void scheduleTaskAtFixedRateIncludingTaskRunningTime(long initialDelay, long period, Runnable task) { + if (task == null) { + return; + } + + synchronized (mScheduledJobRecordMutex) { + if (mScheduledJobRecord.containsKey(task.hashCode())) { + return; + } + + mScheduledJobRecord.put(task.hashCode(), mScheduledThreadPoolExecutor.scheduleWithFixedDelay(task, initialDelay, period, TimeUnit.MILLISECONDS)); + } + } + + public boolean removeScheduledTask(Runnable task) { + if (task == null) { + return false; + } + + synchronized (mScheduledJobRecordMutex) { + if (!mScheduledJobRecord.containsKey(task.hashCode())) { + return false; + } + + ScheduledFuture internalJob = (ScheduledFuture) mScheduledJobRecord.get(task.hashCode()); + internalJob.cancel(true); + mScheduledJobRecord.remove(task.hashCode()); + return true; + } + } + + public void scheduleTaskOnUiThread(long delay, Runnable task) { + if (task == null) { + return; + } + mMainHandler.postDelayed(task, delay); + } + + public void removeScheduledTaskOnUiThread(Runnable task) { + if (task == null) { + return; + } + mMainHandler.removeCallbacks(task); + } + + public void runTaskOnUiThread(Runnable task) { + if (task == null) { + return; + } + + mMainHandler.post(task); + } + + public Handler getMainHandler() { + return mMainHandler; + } + + public void scheduleOnQueue(Runnable task) { + if (task == null) { + return; + } + + mActionQueue.scheduleTask(task); + } + + public void shutdown() { + if (mThreadPoolExecutor != null) { + mThreadPoolExecutor.shutdown(); + mThreadPoolExecutor = null; + } + + if (mScheduledThreadPoolExecutor != null) { + mScheduledThreadPoolExecutor.shutdown(); + mScheduledThreadPoolExecutor = null; + } + + if (mActionQueue != null) { + mActionQueue.stopTaskQueue(); + } + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/adapter/ViewPager2Adapter.java b/app/src/main/java/com/colorful/keyboard/theme/adapter/ViewPager2Adapter.java new file mode 100644 index 0000000..2ffc5e6 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/adapter/ViewPager2Adapter.java @@ -0,0 +1,27 @@ +package com.colorful.keyboard.theme.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.viewpager2.adapter.FragmentStateAdapter; + +import java.util.List; + +public class ViewPager2Adapter extends FragmentStateAdapter { + List fragmentList; + public ViewPager2Adapter(@NonNull FragmentActivity fragmentActivity, List fragmentList) { + super(fragmentActivity); + this.fragmentList = fragmentList; + } + + @NonNull + @Override + public Fragment createFragment(int position) { + return fragmentList.get(position); + } + + @Override + public int getItemCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/bean/Author.kt b/app/src/main/java/com/colorful/keyboard/theme/bean/Author.kt new file mode 100644 index 0000000..8c76aae --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/bean/Author.kt @@ -0,0 +1,10 @@ +package com.colorful.keyboard.theme.bean + +import java.io.Serializable + +data class Author( + val name: String, + val key: String, + val photoUrl: String, + val homeUrl: String +):Serializable \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/bean/CategoryDataBean.kt b/app/src/main/java/com/colorful/keyboard/theme/bean/CategoryDataBean.kt new file mode 100644 index 0000000..c0aa11c --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/bean/CategoryDataBean.kt @@ -0,0 +1,12 @@ +package com.colorful.keyboard.theme.bean + +import java.io.Serializable + +data class CategoryDataBean( + val layout: Int, + val grid: Int, + val type: Int, + val title: String, + val key: String, + var items: List +) : Serializable \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/bean/Content.kt b/app/src/main/java/com/colorful/keyboard/theme/bean/Content.kt new file mode 100644 index 0000000..91b69b9 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/bean/Content.kt @@ -0,0 +1,7 @@ +package com.colorful.keyboard.theme.bean + +import java.io.Serializable + +data class Content( + val imageUrl: String +) : Serializable \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/bean/DetailsBean.kt b/app/src/main/java/com/colorful/keyboard/theme/bean/DetailsBean.kt new file mode 100644 index 0000000..6fa4afc --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/bean/DetailsBean.kt @@ -0,0 +1,16 @@ +package com.colorful.keyboard.theme.bean + +import java.io.Serializable + +data class DetailsBean( + val key: String, + val title: String, + val type: Int, + val thumbUrl: String, + val pkgName: String, + val thumbUrlGif: String, + val content: Content, + val themeContent: ThemeDetailsContent, + val author: Author, + val lock: LockBean +) : Serializable \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/bean/DownloadBean.kt b/app/src/main/java/com/colorful/keyboard/theme/bean/DownloadBean.kt new file mode 100644 index 0000000..6bea6cc --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/bean/DownloadBean.kt @@ -0,0 +1,18 @@ +package com.colorful.keyboard.theme.bean + +import androidx.annotation.Keep +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import java.io.Serializable + +@Keep +@Entity +data class DownloadBean( + @ColumnInfo(name = "title") var title: String, + @ColumnInfo(name = "key") var key: String, + @ColumnInfo(name = "imgUrl") var imgUrl: String, +) : Serializable { + @PrimaryKey(autoGenerate = true) + var id: Long = 0 +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/bean/ItemDataBean.kt b/app/src/main/java/com/colorful/keyboard/theme/bean/ItemDataBean.kt new file mode 100644 index 0000000..97c848d --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/bean/ItemDataBean.kt @@ -0,0 +1,14 @@ +package com.colorful.keyboard.theme.bean + +import java.io.Serializable + +data class ItemDataBean( + val key: String, + val title: String, + val type: Int, + val thumbUrl: String, + val thumbUrlGif: String, + val themeContentBean: ThemeContentBean, + val lockBean: LockBean +) : Serializable + diff --git a/app/src/main/java/com/colorful/keyboard/theme/bean/LockBean.kt b/app/src/main/java/com/colorful/keyboard/theme/bean/LockBean.kt new file mode 100644 index 0000000..1412436 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/bean/LockBean.kt @@ -0,0 +1,7 @@ +package com.colorful.keyboard.theme.bean + +import java.io.Serializable + +data class LockBean( + val type: Int +) : Serializable \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/bean/MainDataBean.kt b/app/src/main/java/com/colorful/keyboard/theme/bean/MainDataBean.kt new file mode 100644 index 0000000..6f2e749 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/bean/MainDataBean.kt @@ -0,0 +1,13 @@ +package com.colorful.keyboard.theme.bean + +import java.io.Serializable + +data class MainDataBean( + val layout: Int, + val grid: Int, + val type: Int, + var title: String, + val key: String, + val mainItemDataBean: MainItemDataBean, + var items: List? = null, +) : Serializable \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/bean/MainItemDataBean.kt b/app/src/main/java/com/colorful/keyboard/theme/bean/MainItemDataBean.kt new file mode 100644 index 0000000..675aab6 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/bean/MainItemDataBean.kt @@ -0,0 +1,11 @@ +package com.colorful.keyboard.theme.bean + +import java.io.Serializable + +data class MainItemDataBean( + val key: String, + val title: String, + val type: Int, + val thumbUrl: String +) : Serializable + diff --git a/app/src/main/java/com/colorful/keyboard/theme/bean/ThemeContentBean.kt b/app/src/main/java/com/colorful/keyboard/theme/bean/ThemeContentBean.kt new file mode 100644 index 0000000..2509927 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/bean/ThemeContentBean.kt @@ -0,0 +1,7 @@ +package com.colorful.keyboard.theme.bean + +import java.io.Serializable + +data class ThemeContentBean( + val pushIcon: String +) : Serializable \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/bean/ThemeDetailsContent.kt b/app/src/main/java/com/colorful/keyboard/theme/bean/ThemeDetailsContent.kt new file mode 100644 index 0000000..2297b72 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/bean/ThemeDetailsContent.kt @@ -0,0 +1,13 @@ +package com.colorful.keyboard.theme.bean + +import java.io.Serializable + +data class ThemeDetailsContent( + val img: String, + val imgBanner: String, + val imgPreviewGif: String, + val pushIcon: String, + val pushBanner: String, + val androidRawZipUrl: String, + val imgGif: String +) : Serializable \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/compat/EditorInfoCompatUtils.java b/app/src/main/java/com/colorful/keyboard/theme/compat/EditorInfoCompatUtils.java new file mode 100644 index 0000000..f37a8a3 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/compat/EditorInfoCompatUtils.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.compat; + +import android.os.Build; +import android.os.LocaleList; +import android.view.inputmethod.EditorInfo; + +import java.util.Locale; + +public final class EditorInfoCompatUtils { + private EditorInfoCompatUtils() { + // This utility class is not publicly instantiable. + } + + public static String imeActionName(final int imeOptions) { + final int actionId = imeOptions & EditorInfo.IME_MASK_ACTION; + switch (actionId) { + case EditorInfo.IME_ACTION_UNSPECIFIED: + return "actionUnspecified"; + case EditorInfo.IME_ACTION_NONE: + return "actionNone"; + case EditorInfo.IME_ACTION_GO: + return "actionGo"; + case EditorInfo.IME_ACTION_SEARCH: + return "actionSearch"; + case EditorInfo.IME_ACTION_SEND: + return "actionSend"; + case EditorInfo.IME_ACTION_NEXT: + return "actionNext"; + case EditorInfo.IME_ACTION_DONE: + return "actionDone"; + case EditorInfo.IME_ACTION_PREVIOUS: + return "actionPrevious"; + default: + return "actionUnknown(" + actionId + ")"; + } + } + + public static Locale getPrimaryHintLocale(final EditorInfo editorInfo) { + if (editorInfo == null) { + return null; + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + LocaleList localeList = editorInfo.hintLocales; + if (localeList != null && !localeList.isEmpty()) + return localeList.get(0); + } + return null; + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/compat/MenuItemIconColorCompat.java b/app/src/main/java/com/colorful/keyboard/theme/compat/MenuItemIconColorCompat.java new file mode 100644 index 0000000..41d5653 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/compat/MenuItemIconColorCompat.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 Raimondas Rimkus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.compat; + +import android.app.ActionBar; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.view.MenuItem; +import android.view.View; +import android.widget.TextView; + +import java.util.ArrayList; + +public class MenuItemIconColorCompat { + /** + * Set a menu item's icon to matching text color. + * @param menuItem the menu item that should change colors. + * @param actionBar target ActionBar. + */ + public static void matchMenuIconColor(final View view, final MenuItem menuItem, final ActionBar actionBar) { + ArrayList views = new ArrayList<>(); + + view.getRootView().findViewsWithText(views, actionBar.getTitle(), View.FIND_VIEWS_WITH_TEXT); + if (views.size() == 1 && views.get(0) instanceof TextView) { + int color = ((TextView) views.get(0)).getCurrentTextColor(); + setIconColor(menuItem, color); + } + } + + /** + * Set a menu item's icon to specific color. + * @param menuItem the menu item that should change colors. + * @param color the color that the icon should be changed to. + */ + private static void setIconColor(final MenuItem menuItem, final int color) { + if (menuItem != null) { + Drawable drawable = menuItem.getIcon(); + if (drawable != null) { + drawable.mutate(); + drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + } + } + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/compat/PreferenceManagerCompat.java b/app/src/main/java/com/colorful/keyboard/theme/compat/PreferenceManagerCompat.java new file mode 100644 index 0000000..c51daf7 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/compat/PreferenceManagerCompat.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 Raimondas Rimkus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.compat; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Build; +import android.preference.PreferenceManager; + +public class PreferenceManagerCompat { + public static Context getDeviceContext(Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + return context.createDeviceProtectedStorageContext(); + } + + return context; + } + + public static SharedPreferences getDeviceSharedPreferences(Context context) { + return PreferenceManager.getDefaultSharedPreferences(getDeviceContext(context)); + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/compat/ViewOutlineProviderCompatUtils.java b/app/src/main/java/com/colorful/keyboard/theme/compat/ViewOutlineProviderCompatUtils.java new file mode 100644 index 0000000..781e897 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/compat/ViewOutlineProviderCompatUtils.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.compat; + +import android.inputmethodservice.InputMethodService; +import android.os.Build; +import android.view.View; + +public class ViewOutlineProviderCompatUtils { + private ViewOutlineProviderCompatUtils() { + // This utility class is not publicly instantiable. + } + + public interface InsetsUpdater { + void setInsets(final InputMethodService.Insets insets); + } + + private static final InsetsUpdater EMPTY_INSETS_UPDATER = new InsetsUpdater() { + @Override + public void setInsets(final InputMethodService.Insets insets) {} + }; + + public static InsetsUpdater setInsetsOutlineProvider(final View view) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + return EMPTY_INSETS_UPDATER; + } + return ViewOutlineProviderCompatUtilsLXX.setInsetsOutlineProvider(view); + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/compat/ViewOutlineProviderCompatUtilsLXX.java b/app/src/main/java/com/colorful/keyboard/theme/compat/ViewOutlineProviderCompatUtilsLXX.java new file mode 100644 index 0000000..a4eb20a --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/compat/ViewOutlineProviderCompatUtilsLXX.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.compat; + +import android.annotation.TargetApi; +import android.graphics.Outline; +import android.inputmethodservice.InputMethodService; +import android.os.Build; +import android.view.View; +import android.view.ViewOutlineProvider; + + +@TargetApi(Build.VERSION_CODES.LOLLIPOP) +class ViewOutlineProviderCompatUtilsLXX { + private ViewOutlineProviderCompatUtilsLXX() { + // This utility class is not publicly instantiable. + } + + static ViewOutlineProviderCompatUtils.InsetsUpdater setInsetsOutlineProvider(final View view) { + final InsetsOutlineProvider provider = new InsetsOutlineProvider(view); + view.setOutlineProvider(provider); + return provider; + } + + private static class InsetsOutlineProvider extends ViewOutlineProvider + implements ViewOutlineProviderCompatUtils.InsetsUpdater { + private final View mView; + private static final int NO_DATA = -1; + private int mLastVisibleTopInsets = NO_DATA; + + public InsetsOutlineProvider(final View view) { + mView = view; + view.setOutlineProvider(this); + } + + @Override + public void setInsets(final InputMethodService.Insets insets) { + final int visibleTopInsets = insets.visibleTopInsets; + if (mLastVisibleTopInsets != visibleTopInsets) { + mLastVisibleTopInsets = visibleTopInsets; + mView.invalidateOutline(); + } + } + + @Override + public void getOutline(final View view, final Outline outline) { + if (mLastVisibleTopInsets == NO_DATA) { + // Call default implementation. + ViewOutlineProvider.BACKGROUND.getOutline(view, outline); + return; + } + // TODO: Revisit this when floating/resize keyboard is supported. + outline.setRect( + view.getLeft(), mLastVisibleTopInsets, view.getRight(), view.getBottom()); + } + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/config_adpter/DownloadAdapter.java b/app/src/main/java/com/colorful/keyboard/theme/config_adpter/DownloadAdapter.java new file mode 100644 index 0000000..c815bd0 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/config_adpter/DownloadAdapter.java @@ -0,0 +1,36 @@ +package com.colorful.keyboard.theme.config_adpter; + +import android.content.Context; +import android.view.ViewGroup; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.chad.library.adapter4.BaseQuickAdapter; +import com.chad.library.adapter4.viewholder.QuickViewHolder; +import com.colorful.keyboard.theme.App; +import com.colorful.keyboard.theme.R; +import com.colorful.keyboard.theme.bean.DownloadBean; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +public class DownloadAdapter extends BaseQuickAdapter { + + @Override + protected void onBindViewHolder(@NonNull QuickViewHolder quickViewHolder, int i, @Nullable DownloadBean itemsBean) { + ImageView imageView = quickViewHolder.getView(R.id.iv_photo); + + String url = itemsBean.getImgUrl(); + + Glide.with(App.Companion.getApp()) + .load(url) + .placeholder(R.drawable.placeholder) + .into(imageView); + } + + @NonNull + @Override + protected QuickViewHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup viewGroup, int i) { + return new QuickViewHolder(R.layout.item_info, viewGroup); + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/config_adpter/PhotoListAdapter.java b/app/src/main/java/com/colorful/keyboard/theme/config_adpter/PhotoListAdapter.java new file mode 100644 index 0000000..afc8a57 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/config_adpter/PhotoListAdapter.java @@ -0,0 +1,39 @@ +package com.colorful.keyboard.theme.config_adpter; + +import android.content.Context; +import android.view.ViewGroup; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bumptech.glide.Glide; +import com.chad.library.adapter4.BaseQuickAdapter; +import com.chad.library.adapter4.viewholder.QuickViewHolder; +import com.colorful.keyboard.theme.App; +import com.colorful.keyboard.theme.R; +import com.colorful.keyboard.theme.model.ThemePhotoListBean; + +public class PhotoListAdapter extends BaseQuickAdapter { + + @Override + protected void onBindViewHolder(@NonNull QuickViewHolder quickViewHolder, int i, @Nullable ThemePhotoListBean.DataBean.SectionsBean.ItemsBean itemsBean) { + ImageView imageView = quickViewHolder.getView(R.id.iv_photo); + + String url = itemsBean.getThumbUrlGif(); + if(url.isEmpty()){ + url = itemsBean.getThumbUrl(); + } + + Glide.with(App.Companion.getApp()) + .load(url) + .placeholder(R.drawable.placeholder) + .into(imageView); + } + + @NonNull + @Override + protected QuickViewHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup viewGroup, int i) { + return new QuickViewHolder(R.layout.item_info, viewGroup); + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/config_adpter/TestAdapter.java b/app/src/main/java/com/colorful/keyboard/theme/config_adpter/TestAdapter.java new file mode 100644 index 0000000..85c5a7b --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/config_adpter/TestAdapter.java @@ -0,0 +1,30 @@ +package com.colorful.keyboard.theme.config_adpter; + + +import android.content.Context; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.chad.library.adapter4.BaseQuickAdapter; +import com.chad.library.adapter4.viewholder.QuickViewHolder; +import com.colorful.keyboard.theme.R; +import com.colorful.keyboard.theme.model.ThemeListModel; + +public class TestAdapter extends BaseQuickAdapter { + + @Override + protected void onBindViewHolder(@NonNull QuickViewHolder quickViewHolder, int i, @Nullable ThemeListModel s) { + TextView textView = quickViewHolder.getView(R.id.tv_theme); + textView.setText(s.getName()); + } + + @NonNull + @Override + protected QuickViewHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup viewGroup, int i) { + return new QuickViewHolder(R.layout.item_photo_info,viewGroup); + } + +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/constant/ConfigConstant.java b/app/src/main/java/com/colorful/keyboard/theme/constant/ConfigConstant.java new file mode 100644 index 0000000..2227c8d --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/constant/ConfigConstant.java @@ -0,0 +1,5 @@ +package com.colorful.keyboard.theme.constant; + +public class ConfigConstant { + public static boolean isNeedSetting = false; +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/event/Event.java b/app/src/main/java/com/colorful/keyboard/theme/event/Event.java new file mode 100644 index 0000000..3edd28f --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/event/Event.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.event; + +import com.colorful.keyboard.theme.latin.common.Constants; +import com.colorful.keyboard.theme.latin.common.StringUtils; + +/** + * Class representing a generic input event as handled by Latin IME. + * + * This contains information about the origin of the event, but it is generalized and should + * represent a software keypress, hardware keypress, or d-pad move alike. + * Very importantly, this does not necessarily result in inputting one character, or even anything + * at all - it may be a dead key, it may be a partial input, it may be a special key on the + * keyboard, it may be a cancellation of a keypress (e.g. in a soft keyboard the finger of the + * user has slid out of the key), etc. It may also be a batch input from a gesture or handwriting + * for example. + * The combiner should figure out what to do with this. + */ +public class Event { + // Should the types below be represented by separate classes instead? It would be cleaner + // but probably a bit too much + // An event we don't handle in Latin IME, for example pressing Ctrl on a hardware keyboard. + final public static int EVENT_TYPE_NOT_HANDLED = 0; + // A key press that is part of input, for example pressing an alphabetic character on a + // hardware qwerty keyboard. It may be part of a sequence that will be re-interpreted later + // through combination. + final public static int EVENT_TYPE_INPUT_KEYPRESS = 1; + // A toggle event is triggered by a key that affects the previous character. An example would + // be a numeric key on a 10-key keyboard, which would toggle between 1 - a - b - c with + // repeated presses. + final public static int EVENT_TYPE_TOGGLE = 2; + // A mode event instructs the combiner to change modes. The canonical example would be the + // hankaku/zenkaku key on a Japanese keyboard, or even the caps lock key on a qwerty keyboard + // if handled at the combiner level. + final public static int EVENT_TYPE_MODE_KEY = 3; + // An event corresponding to a string generated by some software process. + final public static int EVENT_TYPE_SOFTWARE_GENERATED_STRING = 6; + // An event corresponding to a cursor move + final public static int EVENT_TYPE_CURSOR_MOVE = 7; + + // 0 is a valid code point, so we use -1 here. + final public static int NOT_A_CODE_POINT = -1; + // -1 is a valid key code, so we use 0 here. + final public static int NOT_A_KEY_CODE = 0; + + final private static int FLAG_NONE = 0; + // This event is coming from a key repeat, software or hardware. + final private static int FLAG_REPEAT = 0x2; + // This event has already been consumed. + final private static int FLAG_CONSUMED = 0x4; + + final private int mEventType; // The type of event - one of the constants above + // The code point associated with the event, if relevant. This is a unicode code point, and + // has nothing to do with other representations of the key. It is only relevant if this event + // is of KEYPRESS type, but for a mode key like hankaku/zenkaku or ctrl, there is no code point + // associated so this should be NOT_A_CODE_POINT to avoid unintentional use of its value when + // it's not relevant. + final public int mCodePoint; + + final public CharSequence mText; + + // The key code associated with the event, if relevant. This is relevant whenever this event + // has been triggered by a key press, but not for a gesture for example. This has conceptually + // no link to the code point, although keys that enter a straight code point may often set + // this to be equal to mCodePoint for convenience. If this is not a key, this must contain + // NOT_A_KEY_CODE. + final public int mKeyCode; + + // Coordinates of the touch event, if relevant. If useful, we may want to replace this with + // a MotionEvent or something in the future. This is only relevant when the keypress is from + // a software keyboard obviously, unless there are touch-sensitive hardware keyboards in the + // future or some other awesome sauce. + final public int mX; + final public int mY; + + // Some flags that can't go into the key code. It's a bit field of FLAG_* + final private int mFlags; + + // The next event, if any. Null if there is no next event yet. + final public Event mNextEvent; + + // This method is private - to create a new event, use one of the create* utility methods. + private Event(final int type, final CharSequence text, final int codePoint, final int keyCode, + final int x, final int y, final int flags, + final Event next) { + mEventType = type; + mText = text; + mCodePoint = codePoint; + mKeyCode = keyCode; + mX = x; + mY = y; + mFlags = flags; + mNextEvent = next; + } + + public static Event createSoftwareKeypressEvent(final int codePoint, final int keyCode, + final int x, final int y, final boolean isKeyRepeat) { + return new Event(EVENT_TYPE_INPUT_KEYPRESS, null, codePoint, keyCode, x, y, + isKeyRepeat ? FLAG_REPEAT : FLAG_NONE, null); + } + + /** + * Creates an input event with a CharSequence. This is used by some software processes whose + * output is a string, possibly with styling. Examples include press on a multi-character key, + * or combination that outputs a string. + * @param text the CharSequence associated with this event. + * @param keyCode the key code, or NOT_A_KEYCODE if not applicable. + * @return an event for this text. + */ + public static Event createSoftwareTextEvent(final CharSequence text, final int keyCode) { + return new Event(EVENT_TYPE_SOFTWARE_GENERATED_STRING, text, NOT_A_CODE_POINT, keyCode, + Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, + FLAG_NONE, null /* next */); + } + + // Returns whether this is a function key like backspace, ctrl, settings... as opposed to keys + // that result in input like letters or space. + public boolean isFunctionalKeyEvent() { + // This logic may need to be refined in the future + return NOT_A_CODE_POINT == mCodePoint; + } + + public boolean isKeyRepeat() { + return 0 != (FLAG_REPEAT & mFlags); + } + + public boolean isConsumed() { return 0 != (FLAG_CONSUMED & mFlags); } + + public CharSequence getTextToCommit() { + if (isConsumed()) { + return ""; // A consumed event should input no text. + } + switch (mEventType) { + case EVENT_TYPE_MODE_KEY: + case EVENT_TYPE_NOT_HANDLED: + case EVENT_TYPE_TOGGLE: + case EVENT_TYPE_CURSOR_MOVE: + return ""; + case EVENT_TYPE_INPUT_KEYPRESS: + return StringUtils.newSingleCodePointString(mCodePoint); + case EVENT_TYPE_SOFTWARE_GENERATED_STRING: + return mText; + } + throw new RuntimeException("Unknown event type: " + mEventType); + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/event/InputTransaction.java b/app/src/main/java/com/colorful/keyboard/theme/event/InputTransaction.java new file mode 100644 index 0000000..c225e11 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/event/InputTransaction.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.event; + + +import com.colorful.keyboard.theme.latin.settings.SettingsValues; + +/** + * An object encapsulating a single transaction for input. + */ +public class InputTransaction { + // UPDATE_LATER is stronger than UPDATE_NOW. The reason for this is, if we have to update later, + // it's because something will change that we can't evaluate now, which means that even if we + // re-evaluate now we'll have to do it again later. The only case where that wouldn't apply + // would be if we needed to update now to find out the new state right away, but then we + // can't do it with this deferred mechanism anyway. + public static final int SHIFT_NO_UPDATE = 0; + public static final int SHIFT_UPDATE_NOW = 1; + public static final int SHIFT_UPDATE_LATER = 2; + + // Initial conditions + public final SettingsValues mSettingsValues; + + // Outputs + private int mRequiredShiftUpdate = SHIFT_NO_UPDATE; + + public InputTransaction(final SettingsValues settingsValues) { + mSettingsValues = settingsValues; + } + + /** + * Indicate that this transaction requires some type of shift update. + * @param updateType What type of shift update this requires. + */ + public void requireShiftUpdate(final int updateType) { + mRequiredShiftUpdate = Math.max(mRequiredShiftUpdate, updateType); + } + + /** + * Gets what type of shift update this transaction requires. + * @return The shift update type. + */ + public int getRequiredShiftUpdate() { + return mRequiredShiftUpdate; + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/firebase/Constants.kt b/app/src/main/java/com/colorful/keyboard/theme/firebase/Constants.kt new file mode 100644 index 0000000..78c507e --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/firebase/Constants.kt @@ -0,0 +1,8 @@ +package com.colorful.keyboard.theme.firebase + +object Constants { + const val KEY_SHOW_AD_INTERVAL_TIME = "key_ad_show_interval" + const val DEFAULT_SHOW_AD_INTERVAL_TIME = 1000 * 30L + +} + diff --git a/app/src/main/java/com/colorful/keyboard/theme/firebase/RemoteConfig.kt b/app/src/main/java/com/colorful/keyboard/theme/firebase/RemoteConfig.kt new file mode 100644 index 0000000..c90cde5 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/firebase/RemoteConfig.kt @@ -0,0 +1,134 @@ +package com.colorful.keyboard.theme.firebase + +import android.annotation.SuppressLint +import android.app.Application +import android.content.Context +import android.os.Handler +import android.os.Message +import android.text.TextUtils +import android.util.Log +import com.colorful.keyboard.theme.App +import com.colorful.keyboard.theme.BuildConfig +import com.colorful.keyboard.theme.myutil.AppSharedPreferences +import com.google.firebase.remoteconfig.ConfigUpdate +import com.google.firebase.remoteconfig.ConfigUpdateListener +import com.google.firebase.remoteconfig.FirebaseRemoteConfig +import com.google.firebase.remoteconfig.FirebaseRemoteConfigException +import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings +import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue +import java.lang.ref.WeakReference + +class RemoteConfig { + + private var ctx: Context? = null + private var mFirebaseRemoteConfig: FirebaseRemoteConfig? = null + + //配置是否初始化成功 + private var isInit = false + + //上次获取数据的时间 + private var lastFetchTime: Long = 0 + private val handler = MHandler(this) + + companion object { + const val MSG_REFRESH_CONFIG = 1 + val instance: RemoteConfig by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { + RemoteConfig() + } + } + + fun init(ctx: Application) { + this.ctx = ctx + initConfig() + fetchConfig() + onConfigUpdate() + } + + private fun initConfig() { + var intervalTime = (60 * 10).toLong() + //如果是开发状态,则将提取时间缩短 + if (BuildConfig.DEBUG) { + intervalTime = (60 * 5).toLong() + } + mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance() + val configSettings = + FirebaseRemoteConfigSettings.Builder() //默认值12小时的最短提取间隔,如果在间隔内取值,则优先取上次的结果 + .setMinimumFetchIntervalInSeconds(intervalTime).build() + mFirebaseRemoteConfig!!.setConfigSettingsAsync(configSettings) + } + + private fun onConfigUpdate() { + mFirebaseRemoteConfig!!.addOnConfigUpdateListener(object : ConfigUpdateListener { + override fun onUpdate(configUpdate: ConfigUpdate) { + try { +// if (configUpdate.updatedKeys.contains(Constants.KEY_SHOULD_ENTER_MUSIC_JSON)) { +// +// } + mFirebaseRemoteConfig!!.activate().addOnCompleteListener { task -> + if (task.isSuccessful) { + updateData("onConfigUpdate", mFirebaseRemoteConfig!!.all) + } + } + } catch (ignore: Exception) { + } + } + + override fun onError(error: FirebaseRemoteConfigException) { + } + }) + } + + @SuppressLint("LongLogTag") + private fun fetchConfig() { + //这里可能会抛出异常 FirebaseRemoteConfigFetchThrottledException + try { + mFirebaseRemoteConfig!!.fetchAndActivate().addOnCompleteListener { task -> + if (task.isSuccessful) { + isInit = true + lastFetchTime = System.currentTimeMillis() + updateData("fetchAndActivate", mFirebaseRemoteConfig!!.all) + //24小时后,重新再去获取 + handler.removeMessages(MSG_REFRESH_CONFIG) + handler.sendEmptyMessageDelayed( + MSG_REFRESH_CONFIG, (1000 * 60 * 60 * 24).toLong() + ) + } else { + //这里需要重新再去获取 + handler.removeMessages(MSG_REFRESH_CONFIG) + handler.sendEmptyMessageDelayed(MSG_REFRESH_CONFIG, (1000 * 60 * 15).toLong()) + } + } + } catch (ignore: Exception) { + } + } + + private fun updateData(from: String, all: Map) { + val appSharedPreferences = AppSharedPreferences(App.app) + for ((key, value) in all) { + try { + Log.d("colorful-config","from->$from key->$key value->${value.asString()}") + if (TextUtils.equals(Constants.KEY_SHOW_AD_INTERVAL_TIME, key)) { + val t = value.asString() + appSharedPreferences.setShowAdIntervalTime(t.toLong()) + } + } catch (ignore: Exception) { + + } + } + } + + private class MHandler(remoteConfig: RemoteConfig) : Handler() { + private val weakReference: WeakReference = WeakReference(remoteConfig) + + override fun handleMessage(msg: Message) { + super.handleMessage(msg) + val remoteConfig = weakReference.get() + if (remoteConfig?.ctx != null) { + if (msg.what == MSG_REFRESH_CONFIG) { + remoteConfig.fetchConfig() + } + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/fragment/KeyboardListFragment.kt b/app/src/main/java/com/colorful/keyboard/theme/fragment/KeyboardListFragment.kt new file mode 100644 index 0000000..210a0b1 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/fragment/KeyboardListFragment.kt @@ -0,0 +1,91 @@ +package com.colorful.keyboard.theme.fragment + +import android.content.Intent +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.LinearLayout +import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import com.colorful.keyboard.theme.ColorfulDetailsActivity +import com.colorful.keyboard.theme.R +import com.colorful.keyboard.theme.config_adpter.PhotoListAdapter +import com.colorful.keyboard.theme.model.ThemePhotoListBean +import com.colorful.keyboard.theme.net.ApiCallbackCommon +import com.colorful.keyboard.theme.net.ApiException +import com.colorful.keyboard.theme.net.BaseInitApiRequest + +class KeyboardListFragment : Fragment() { + private var swipeRefreshLayout: SwipeRefreshLayout? = null + private var recyclerView: RecyclerView? = null + private var catid: String? = "" + private var photoListAdapter: PhotoListAdapter? = null + private var loadingLayout: LinearLayout? = null + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + if (arguments != null) { + val arguments = arguments + catid = arguments!!.getString("id") + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + val inflate = inflater.inflate(R.layout.fragment_photo_list, container, false) + swipeRefreshLayout = inflate.findViewById(R.id.swiper) + recyclerView = inflate.findViewById(R.id.rv_photo_ist) + loadingLayout = inflate.findViewById(R.id.loadingLayout) + return inflate + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + loadingLayout?.visibility = View.VISIBLE + //recyclerView.setAdapter(new PhotoListAdapter()); + swipeRefreshLayout!!.isEnabled = false + photoListAdapter = PhotoListAdapter() + recyclerView!!.layoutManager = GridLayoutManager(activity, 3) + recyclerView!!.adapter = photoListAdapter + photoListAdapter!!.setOnItemClickListener { baseQuickAdapter, view, i -> + startActivity( + Intent(activity, ColorfulDetailsActivity::class.java) + .putExtra("title", baseQuickAdapter.getItem(i)!!.title) + .putExtra("key", baseQuickAdapter.getItem(i)!!.key).putExtra( + "url", baseQuickAdapter.getItem(i)!! + .thumbUrl + ) + .putExtra("",baseQuickAdapter.getItem(i)?.thumbUrlGif) + ) + } + info + } + + private val info: Unit + private get() { + val hashMap = HashMap() + hashMap["offset"] = "0" + hashMap["fetch_size"] = "100" + hashMap["sign"] = "a28aadc61c76c754944f6ddb48962c9c" + BaseInitApiRequest.getNetData(BaseInitApiRequest.initHHYApiStores() + .getThemeList(catid, hashMap), + object : ApiCallbackCommon(activity, false) { + + + override fun onSuccess(model: ThemePhotoListBean?) { + photoListAdapter!!.submitList(model?.data?.sections!![0]?.items) + + loadingLayout?.visibility = View.GONE + } + + override fun onFailure(ex: ApiException) { + loadingLayout?.visibility = View.GONE + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/colorful/keyboard/theme/keyboard/Key.java b/app/src/main/java/com/colorful/keyboard/theme/keyboard/Key.java new file mode 100644 index 0000000..15f34c7 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/keyboard/Key.java @@ -0,0 +1,909 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.colorful.keyboard.theme.keyboard; +import static com.colorful.keyboard.theme.latin.common.Constants.CODE_OUTPUT_TEXT; +import static com.colorful.keyboard.theme.latin.common.Constants.CODE_SHIFT; +import static com.colorful.keyboard.theme.latin.common.Constants.CODE_SWITCH_ALPHA_SYMBOL; +import static com.colorful.keyboard.theme.latin.common.Constants.CODE_UNSPECIFIED; + +import android.content.res.TypedArray; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.graphics.drawable.Drawable; +import android.text.TextUtils; + +import com.colorful.keyboard.theme.R; +import com.colorful.keyboard.theme.keyboard.internal.KeyDrawParams; +import com.colorful.keyboard.theme.keyboard.internal.KeySpecParser; +import com.colorful.keyboard.theme.keyboard.internal.KeyStyle; +import com.colorful.keyboard.theme.keyboard.internal.KeyVisualAttributes; +import com.colorful.keyboard.theme.keyboard.internal.KeyboardIconsSet; +import com.colorful.keyboard.theme.keyboard.internal.KeyboardParams; +import com.colorful.keyboard.theme.keyboard.internal.KeyboardRow; +import com.colorful.keyboard.theme.keyboard.internal.MoreKeySpec; +import com.colorful.keyboard.theme.latin.common.Constants; +import com.colorful.keyboard.theme.latin.common.StringUtils; + +import java.util.Arrays; +import java.util.Locale; + + +/** + * Class for describing the position and characteristics of a single key in the keyboard. + */ +public class Key implements Comparable { + /** + * The key code (unicode or custom code) that this key generates. + */ + private final int mCode; + + /** Label to display */ + private final String mLabel; + /** Hint label to display on the key in conjunction with the label */ + private final String mHintLabel; + /** Flags of the label */ + private final int mLabelFlags; + private static final int LABEL_FLAGS_ALIGN_HINT_LABEL_TO_BOTTOM = 0x02; + private static final int LABEL_FLAGS_ALIGN_ICON_TO_BOTTOM = 0x04; + private static final int LABEL_FLAGS_ALIGN_LABEL_OFF_CENTER = 0x08; + // Font typeface specification. + private static final int LABEL_FLAGS_FONT_MASK = 0x30; + private static final int LABEL_FLAGS_FONT_NORMAL = 0x10; + private static final int LABEL_FLAGS_FONT_MONO_SPACE = 0x20; + private static final int LABEL_FLAGS_FONT_DEFAULT = 0x30; + // Start of key text ratio enum values + private static final int LABEL_FLAGS_FOLLOW_KEY_TEXT_RATIO_MASK = 0x1C0; + private static final int LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO = 0x40; + private static final int LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO = 0x80; + private static final int LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO = 0xC0; + private static final int LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO = 0x140; + // End of key text ratio mask enum values + private static final int LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT = 0x400; + private static final int LABEL_FLAGS_HAS_HINT_LABEL = 0x800; + // The bit to calculate the ratio of key label width against key width. If autoXScale bit is on + // and autoYScale bit is off, the key label may be shrunk only for X-direction. + // If both autoXScale and autoYScale bits are on, the key label text size may be auto scaled. + private static final int LABEL_FLAGS_AUTO_X_SCALE = 0x4000; + private static final int LABEL_FLAGS_AUTO_Y_SCALE = 0x8000; + private static final int LABEL_FLAGS_AUTO_SCALE = LABEL_FLAGS_AUTO_X_SCALE + | LABEL_FLAGS_AUTO_Y_SCALE; + private static final int LABEL_FLAGS_PRESERVE_CASE = 0x10000; + private static final int LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED = 0x20000; + private static final int LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL = 0x40000; + private static final int LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR = 0x80000; + private static final int LABEL_FLAGS_DISABLE_HINT_LABEL = 0x40000000; + private static final int LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS = 0x80000000; + + /** Icon to display instead of a label. Icon takes precedence over a label */ + private final int mIconId; + + /** Width of the key, excluding the padding */ + private final int mWidth; + /** Height of the key, excluding the padding */ + private final int mHeight; + /** Exact theoretical width of the key, excluding the padding */ + private final float mDefinedWidth; + /** Exact theoretical height of the key, excluding the padding */ + private final float mDefinedHeight; + /** X coordinate of the top-left corner of the key in the keyboard layout, excluding the + * padding. */ + private final int mX; + /** Y coordinate of the top-left corner of the key in the keyboard layout, excluding the + * padding. */ + private final int mY; + /** Hit bounding box of the key */ + private final Rect mHitbox = new Rect(); + + /** More keys. It is guaranteed that this is null or an array of one or more elements */ + private final MoreKeySpec[] mMoreKeys; + /** More keys column number and flags */ + private final int mMoreKeysColumnAndFlags; + private static final int MORE_KEYS_COLUMN_NUMBER_MASK = 0x000000ff; + // If this flag is specified, more keys keyboard should have the specified number of columns. + // Otherwise more keys keyboard should have less than or equal to the specified maximum number + // of columns. + private static final int MORE_KEYS_FLAGS_FIXED_COLUMN = 0x00000100; + // If this flag is specified, the order of more keys is determined by the order in the more + // keys' specification. Otherwise the order of more keys is automatically determined. + private static final int MORE_KEYS_FLAGS_FIXED_ORDER = 0x00000200; + private static final int MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER = 0; + private static final int MORE_KEYS_MODE_FIXED_COLUMN_WITH_AUTO_ORDER = + MORE_KEYS_FLAGS_FIXED_COLUMN; + private static final int MORE_KEYS_MODE_FIXED_COLUMN_WITH_FIXED_ORDER = + (MORE_KEYS_FLAGS_FIXED_COLUMN | MORE_KEYS_FLAGS_FIXED_ORDER); + private static final int MORE_KEYS_FLAGS_HAS_LABELS = 0x40000000; + private static final int MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY = 0x10000000; + // TODO: Rename these specifiers to !autoOrder! and !fixedOrder! respectively. + private static final String MORE_KEYS_AUTO_COLUMN_ORDER = "!autoColumnOrder!"; + private static final String MORE_KEYS_FIXED_COLUMN_ORDER = "!fixedColumnOrder!"; + private static final String MORE_KEYS_HAS_LABELS = "!hasLabels!"; + private static final String MORE_KEYS_NO_PANEL_AUTO_MORE_KEY = "!noPanelAutoMoreKey!"; + + /** Background type that represents different key background visual than normal one. */ + private final int mBackgroundType; + public static final int BACKGROUND_TYPE_EMPTY = 0; + public static final int BACKGROUND_TYPE_NORMAL = 1; + public static final int BACKGROUND_TYPE_FUNCTIONAL = 2; + public static final int BACKGROUND_TYPE_ACTION = 5; + public static final int BACKGROUND_TYPE_SPACEBAR = 6; + + private final int mActionFlags; + private static final int ACTION_FLAGS_IS_REPEATABLE = 0x01; + private static final int ACTION_FLAGS_NO_KEY_PREVIEW = 0x02; + private static final int ACTION_FLAGS_ALT_CODE_WHILE_TYPING = 0x04; + private static final int ACTION_FLAGS_ENABLE_LONG_PRESS = 0x08; + + private final KeyVisualAttributes mKeyVisualAttributes; + private final OptionalAttributes mOptionalAttributes; + + private static final class OptionalAttributes { + /** Text to output when pressed. This can be multiple characters, like ".com" */ + public final String mOutputText; + public final int mAltCode; + + private OptionalAttributes(final String outputText, final int altCode) { + mOutputText = outputText; + mAltCode = altCode; + } + + public static OptionalAttributes newInstance(final String outputText, final int altCode) { + if (outputText == null && altCode == CODE_UNSPECIFIED) { + return null; + } + return new OptionalAttributes(outputText, altCode); + } + } + + private final int mHashCode; + + /** The current pressed state of this key */ + private boolean mPressed; + + /** + * Constructor for a key on MoreKeyKeyboard. + */ + public Key(final String label, final int iconId, final int code, final String outputText, + final String hintLabel, final int labelFlags, final int backgroundType, + final float x, final float y, final float width, final float height, + final float leftPadding, final float rightPadding, final float topPadding, + final float bottomPadding) { + mHitbox.set(Math.round(x - leftPadding), Math.round(y - topPadding), + Math.round(x + width + rightPadding), Math.round(y + height + bottomPadding)); + mX = Math.round(x); + mY = Math.round(y); + mWidth = Math.round(x + width) - mX; + mHeight = Math.round(y + height) - mY; + mDefinedWidth = width; + mDefinedHeight = height; + mHintLabel = hintLabel; + mLabelFlags = labelFlags; + mBackgroundType = backgroundType; + // TODO: Pass keyActionFlags as an argument. + mActionFlags = ACTION_FLAGS_NO_KEY_PREVIEW; + mMoreKeys = null; + mMoreKeysColumnAndFlags = 0; + mLabel = label; + mOptionalAttributes = OptionalAttributes.newInstance(outputText, CODE_UNSPECIFIED); + mCode = code; + mIconId = iconId; + mKeyVisualAttributes = null; + + mHashCode = computeHashCode(this); + } + + /** + * Create a key with the given top-left coordinate and extract its attributes from a key + * specification string, Key attribute array, key style, and etc. + * + * @param keySpec the key specification. + * @param keyAttr the Key XML attributes array. + * @param style the {@link KeyStyle} of this key. + * @param params the keyboard building parameters. + * @param row the row that this key belongs to. row's x-coordinate will be the right edge of + * this key. + */ + public Key(final String keySpec, final TypedArray keyAttr, + final KeyStyle style, final KeyboardParams params, + final KeyboardRow row) { + // Update the row to work with the new key + row.setCurrentKey(keyAttr, isSpacer()); + + mDefinedWidth = row.getKeyWidth(); + mDefinedHeight = row.getKeyHeight(); + + final float keyLeft = row.getKeyX(); + final float keyTop = row.getKeyY(); + final float keyRight = keyLeft + mDefinedWidth; + final float keyBottom = keyTop + mDefinedHeight; + + final float leftPadding = row.getKeyLeftPadding(); + final float topPadding = row.getKeyTopPadding(); + final float rightPadding = row.getKeyRightPadding(); + final float bottomPadding = row.getKeyBottomPadding(); + + mHitbox.set(Math.round(keyLeft - leftPadding), Math.round(keyTop - topPadding), + Math.round(keyRight + rightPadding), Math.round(keyBottom + bottomPadding)); + mX = Math.round(keyLeft); + mY = Math.round(keyTop); + mWidth = Math.round(keyRight) - mX; + mHeight = Math.round(keyBottom) - mY; + + mBackgroundType = style.getInt(keyAttr, + R.styleable.Keyboard_Key_backgroundType, row.getDefaultBackgroundType()); + + mLabelFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags) + | row.getDefaultKeyLabelFlags(); + final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId); + final Locale localeForUpcasing = params.mId.getLocale(); + int actionFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags); + String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys); + + // Get maximum column order number and set a relevant mode value. + int moreKeysColumnAndFlags = MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER + | style.getInt(keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn, + params.mMaxMoreKeysKeyboardColumn); + int value; + if ((value = MoreKeySpec.getIntValue(moreKeys, MORE_KEYS_AUTO_COLUMN_ORDER, -1)) > 0) { + // Override with fixed column order number and set a relevant mode value. + moreKeysColumnAndFlags = MORE_KEYS_MODE_FIXED_COLUMN_WITH_AUTO_ORDER + | (value & MORE_KEYS_COLUMN_NUMBER_MASK); + } + if ((value = MoreKeySpec.getIntValue(moreKeys, MORE_KEYS_FIXED_COLUMN_ORDER, -1)) > 0) { + // Override with fixed column order number and set a relevant mode value. + moreKeysColumnAndFlags = MORE_KEYS_MODE_FIXED_COLUMN_WITH_FIXED_ORDER + | (value & MORE_KEYS_COLUMN_NUMBER_MASK); + } + if (MoreKeySpec.getBooleanValue(moreKeys, MORE_KEYS_HAS_LABELS)) { + moreKeysColumnAndFlags |= MORE_KEYS_FLAGS_HAS_LABELS; + } + if (MoreKeySpec.getBooleanValue(moreKeys, MORE_KEYS_NO_PANEL_AUTO_MORE_KEY)) { + moreKeysColumnAndFlags |= MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY; + } + mMoreKeysColumnAndFlags = moreKeysColumnAndFlags; + + final String[] additionalMoreKeys; + if ((mLabelFlags & LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS) != 0) { + additionalMoreKeys = null; + } else { + additionalMoreKeys = style.getStringArray(keyAttr, + R.styleable.Keyboard_Key_additionalMoreKeys); + } + moreKeys = MoreKeySpec.insertAdditionalMoreKeys(moreKeys, additionalMoreKeys); + if (moreKeys != null) { + actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS; + mMoreKeys = new MoreKeySpec[moreKeys.length]; + for (int i = 0; i < moreKeys.length; i++) { + mMoreKeys[i] = new MoreKeySpec(moreKeys[i], needsToUpcase, localeForUpcasing); + } + } else { + mMoreKeys = null; + } + mActionFlags = actionFlags; + + mIconId = KeySpecParser.getIconId(keySpec); + + final int code = KeySpecParser.getCode(keySpec); + if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) { + mLabel = params.mId.mCustomActionLabel; + } else if (code >= Character.MIN_SUPPLEMENTARY_CODE_POINT) { + // This is a workaround to have a key that has a supplementary code point in its label. + // Because we can put a string in resource neither as a XML entity of a supplementary + // code point nor as a surrogate pair. + mLabel = new StringBuilder().appendCodePoint(code).toString(); + } else { + final String label = KeySpecParser.getLabel(keySpec); + mLabel = needsToUpcase + ? StringUtils.toTitleCaseOfKeyLabel(label, localeForUpcasing) + : label; + } + if ((mLabelFlags & LABEL_FLAGS_DISABLE_HINT_LABEL) != 0) { + mHintLabel = null; + } else { + final String hintLabel = style.getString( + keyAttr, R.styleable.Keyboard_Key_keyHintLabel); + mHintLabel = needsToUpcase + ? StringUtils.toTitleCaseOfKeyLabel(hintLabel, localeForUpcasing) + : hintLabel; + } + String outputText = KeySpecParser.getOutputText(keySpec); + if (needsToUpcase) { + outputText = StringUtils.toTitleCaseOfKeyLabel(outputText, localeForUpcasing); + } + // Choose the first letter of the label as primary code if not specified. + if (code == CODE_UNSPECIFIED && TextUtils.isEmpty(outputText) + && !TextUtils.isEmpty(mLabel)) { + if (StringUtils.codePointCount(mLabel) == 1) { + // Use the first letter of the hint label if shiftedLetterActivated flag is + // specified. + if (hasShiftedLetterHint() && isShiftedLetterActivated()) { + mCode = mHintLabel.codePointAt(0); + } else { + mCode = mLabel.codePointAt(0); + } + } else { + // In some locale and case, the character might be represented by multiple code + // points, such as upper case Eszett of German alphabet. + outputText = mLabel; + mCode = CODE_OUTPUT_TEXT; + } + } else if (code == CODE_UNSPECIFIED && outputText != null) { + if (StringUtils.codePointCount(outputText) == 1) { + mCode = outputText.codePointAt(0); + outputText = null; + } else { + mCode = CODE_OUTPUT_TEXT; + } + } else { + mCode = needsToUpcase ? StringUtils.toTitleCaseOfKeyCode(code, localeForUpcasing) + : code; + } + final int altCodeInAttr = KeySpecParser.parseCode( + style.getString(keyAttr, R.styleable.Keyboard_Key_altCode), CODE_UNSPECIFIED); + final int altCode = needsToUpcase + ? StringUtils.toTitleCaseOfKeyCode(altCodeInAttr, localeForUpcasing) + : altCodeInAttr; + mOptionalAttributes = OptionalAttributes.newInstance(outputText, altCode); + mKeyVisualAttributes = KeyVisualAttributes.newInstance(keyAttr); + mHashCode = computeHashCode(this); + } + + /** + * Copy constructor for DynamicGridKeyboard.GridKey. + * + * @param key the original key. + */ + protected Key(final Key key) { + this(key, key.mMoreKeys); + } + + private Key(final Key key,final MoreKeySpec[] moreKeys) { + // Final attributes. + mCode = key.mCode; + mLabel = key.mLabel; + mHintLabel = key.mHintLabel; + mLabelFlags = key.mLabelFlags; + mIconId = key.mIconId; + mWidth = key.mWidth; + mHeight = key.mHeight; + mDefinedWidth = key.mDefinedWidth; + mDefinedHeight = key.mDefinedHeight; + mX = key.mX; + mY = key.mY; + mHitbox.set(key.mHitbox); + mMoreKeys = moreKeys; + mMoreKeysColumnAndFlags = key.mMoreKeysColumnAndFlags; + mBackgroundType = key.mBackgroundType; + mActionFlags = key.mActionFlags; + mKeyVisualAttributes = key.mKeyVisualAttributes; + mOptionalAttributes = key.mOptionalAttributes; + mHashCode = key.mHashCode; + // Key state. + mPressed = key.mPressed; + } + + public static Key removeRedundantMoreKeys(final Key key, + final MoreKeySpec.LettersOnBaseLayout lettersOnBaseLayout) { + final MoreKeySpec[] moreKeys = key.getMoreKeys(); + final MoreKeySpec[] filteredMoreKeys = MoreKeySpec.removeRedundantMoreKeys( + moreKeys, lettersOnBaseLayout); + return (filteredMoreKeys == moreKeys) ? key : new Key(key, filteredMoreKeys); + } + + private static boolean needsToUpcase(final int labelFlags, final int keyboardElementId) { + if ((labelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0) return false; + switch (keyboardElementId) { + case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED: + case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED: + case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED: + return true; + default: + return false; + } + } + + private static int computeHashCode(final Key key) { + return Arrays.hashCode(new Object[] { + key.mX, + key.mY, + key.mWidth, + key.mHeight, + key.mCode, + key.mLabel, + key.mHintLabel, + key.mIconId, + key.mBackgroundType, + Arrays.hashCode(key.mMoreKeys), + key.getOutputText(), + key.mActionFlags, + key.mLabelFlags, + // Key can be distinguishable without the following members. + // key.mOptionalAttributes.mAltCode, + // key.mOptionalAttributes.mDisabledIconId, + // key.mOptionalAttributes.mPreviewIconId, + // key.mMaxMoreKeysColumn, + // key.mDefinedHeight, + // key.mDefinedWidth, + }); + } + + private boolean equalsInternal(final Key o) { + if (this == o) return true; + return o.mX == mX + && o.mY == mY + && o.mWidth == mWidth + && o.mHeight == mHeight + && o.mCode == mCode + && TextUtils.equals(o.mLabel, mLabel) + && TextUtils.equals(o.mHintLabel, mHintLabel) + && o.mIconId == mIconId + && o.mBackgroundType == mBackgroundType + && Arrays.equals(o.mMoreKeys, mMoreKeys) + && TextUtils.equals(o.getOutputText(), getOutputText()) + && o.mActionFlags == mActionFlags + && o.mLabelFlags == mLabelFlags; + } + + @Override + public int compareTo(Key o) { + if (equalsInternal(o)) return 0; + if (mHashCode > o.mHashCode) return 1; + return -1; + } + + @Override + public int hashCode() { + return mHashCode; + } + + @Override + public boolean equals(final Object o) { + return o instanceof Key && equalsInternal((Key)o); + } + + @Override + public String toString() { + return toShortString() + " " + getX() + "," + getY() + " " + getWidth() + "x" + getHeight(); + } + + public String toShortString() { + final int code = getCode(); + if (code == CODE_OUTPUT_TEXT) { + return getOutputText(); + } + return Constants.printableCode(code); + } + + public int getCode() { + return mCode; + } + + public String getLabel() { + return mLabel; + } + + public String getHintLabel() { + return mHintLabel; + } + + public MoreKeySpec[] getMoreKeys() { + return mMoreKeys; + } + + public void setHitboxRightEdge(final int right) { + mHitbox.right = right; + } + + public final boolean isSpacer() { + return this instanceof Spacer; + } + + public final boolean isActionKey() { + return mBackgroundType == BACKGROUND_TYPE_ACTION; + } + + public final boolean isShift() { + return mCode == CODE_SHIFT; + } + + public final boolean isModifier() { + return mCode == CODE_SHIFT || mCode == CODE_SWITCH_ALPHA_SYMBOL; + } + + public final boolean isRepeatable() { + return (mActionFlags & ACTION_FLAGS_IS_REPEATABLE) != 0; + } + + public final boolean noKeyPreview() { + return (mActionFlags & ACTION_FLAGS_NO_KEY_PREVIEW) != 0; + } + + public final boolean altCodeWhileTyping() { + return (mActionFlags & ACTION_FLAGS_ALT_CODE_WHILE_TYPING) != 0; + } + + public final boolean isLongPressEnabled() { + // We need not start long press timer on the key which has activated shifted letter. + return (mActionFlags & ACTION_FLAGS_ENABLE_LONG_PRESS) != 0 + && (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) == 0; + } + + public KeyVisualAttributes getVisualAttributes() { + return mKeyVisualAttributes; + } + + public final Typeface selectTypeface(final KeyDrawParams params) { + switch (mLabelFlags & LABEL_FLAGS_FONT_MASK) { + case LABEL_FLAGS_FONT_NORMAL: + return Typeface.DEFAULT; + case LABEL_FLAGS_FONT_MONO_SPACE: + return Typeface.MONOSPACE; + case LABEL_FLAGS_FONT_DEFAULT: + default: + // The type-face is specified by keyTypeface attribute. + return params.mTypeface; + } + } + + public final int selectTextSize(final KeyDrawParams params) { + switch (mLabelFlags & LABEL_FLAGS_FOLLOW_KEY_TEXT_RATIO_MASK) { + case LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO: + return params.mLetterSize; + case LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO: + return params.mLargeLetterSize; + case LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO: + return params.mLabelSize; + case LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO: + return params.mHintLabelSize; + default: // No follow key ratio flag specified. + return StringUtils.codePointCount(mLabel) == 1 ? params.mLetterSize : params.mLabelSize; + } + } + + public final int selectTextColor(final KeyDrawParams params) { + if ((mLabelFlags & LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR) != 0) { + return params.mFunctionalTextColor; + } + return isShiftedLetterActivated() ? params.mTextInactivatedColor : params.mTextColor; + } + + public final int selectHintTextSize(final KeyDrawParams params) { + if (hasHintLabel()) { + return params.mHintLabelSize; + } + if (hasShiftedLetterHint()) { + return params.mShiftedLetterHintSize; + } + return params.mHintLetterSize; + } + + public final int selectHintTextColor(final KeyDrawParams params) { + if (hasHintLabel()) { + return params.mHintLabelColor; + } + if (hasShiftedLetterHint()) { + return isShiftedLetterActivated() ? params.mShiftedLetterHintActivatedColor + : params.mShiftedLetterHintInactivatedColor; + } + return params.mHintLetterColor; + } + + public final String getPreviewLabel() { + return isShiftedLetterActivated() ? mHintLabel : mLabel; + } + + private boolean previewHasLetterSize() { + return (mLabelFlags & LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO) != 0 + || StringUtils.codePointCount(getPreviewLabel()) == 1; + } + + public final int selectPreviewTextSize(final KeyDrawParams params) { + if (previewHasLetterSize()) { + return params.mPreviewTextSize; + } + return params.mLetterSize; + } + + public Typeface selectPreviewTypeface(final KeyDrawParams params) { + if (previewHasLetterSize()) { + return selectTypeface(params); + } + return Typeface.DEFAULT_BOLD; + } + + public final boolean isAlignHintLabelToBottom(final int defaultFlags) { + return ((mLabelFlags | defaultFlags) & LABEL_FLAGS_ALIGN_HINT_LABEL_TO_BOTTOM) != 0; + } + + public final boolean isAlignIconToBottom() { + return (mLabelFlags & LABEL_FLAGS_ALIGN_ICON_TO_BOTTOM) != 0; + } + + public final boolean isAlignLabelOffCenter() { + return (mLabelFlags & LABEL_FLAGS_ALIGN_LABEL_OFF_CENTER) != 0; + } + + public final boolean hasShiftedLetterHint() { + return (mLabelFlags & LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT) != 0 + && !TextUtils.isEmpty(mHintLabel); + } + + public final boolean hasHintLabel() { + return (mLabelFlags & LABEL_FLAGS_HAS_HINT_LABEL) != 0; + } + + public final boolean needsAutoXScale() { + return (mLabelFlags & LABEL_FLAGS_AUTO_X_SCALE) != 0; + } + + public final boolean needsAutoScale() { + return (mLabelFlags & LABEL_FLAGS_AUTO_SCALE) == LABEL_FLAGS_AUTO_SCALE; + } + + private final boolean isShiftedLetterActivated() { + return (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) != 0 + && !TextUtils.isEmpty(mHintLabel); + } + + public final int getMoreKeysColumnNumber() { + return mMoreKeysColumnAndFlags & MORE_KEYS_COLUMN_NUMBER_MASK; + } + + public final boolean isMoreKeysFixedColumn() { + return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_FIXED_COLUMN) != 0; + } + + public final boolean isMoreKeysFixedOrder() { + return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_FIXED_ORDER) != 0; + } + + public final boolean hasLabelsInMoreKeys() { + return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_HAS_LABELS) != 0; + } + + public final int getMoreKeyLabelFlags() { + final int labelSizeFlag = hasLabelsInMoreKeys() + ? LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO + : LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO; + return labelSizeFlag | LABEL_FLAGS_AUTO_X_SCALE; + } + + public final boolean hasNoPanelAutoMoreKey() { + return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY) != 0; + } + + public final String getOutputText() { + final OptionalAttributes attrs = mOptionalAttributes; + return (attrs != null) ? attrs.mOutputText : null; + } + + public final int getAltCode() { + final OptionalAttributes attrs = mOptionalAttributes; + return (attrs != null) ? attrs.mAltCode : CODE_UNSPECIFIED; + } + + public int getIconId() { + return mIconId; + } + + public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) { + final Drawable icon = iconSet.getIconDrawable(getIconId()); + if (icon != null) { + icon.setAlpha(alpha); + } + return icon; + } + + public Drawable getPreviewIcon(final KeyboardIconsSet iconSet) { + return iconSet.getIconDrawable(getIconId()); + } + + /** + * Gets the width of the key in pixels, excluding the padding. + * @return The width of the key in pixels, excluding the padding. + */ + public int getWidth() { + return mWidth; + } + + /** + * Gets the height of the key in pixels, excluding the padding. + * @return The height of the key in pixels, excluding the padding. + */ + public int getHeight() { + return mHeight; + } + + /** + * Gets the theoretical width of the key in pixels, excluding the padding. This is the exact + * width that the key was defined to be, but this will likely differ from the actual drawn width + * because the normal (drawn/functional) width was determined by rounding the left and right + * edge to fit evenly in a pixel. + * @return The defined width of the key in pixels, excluding the padding. + */ + public float getDefinedWidth() { + return mDefinedWidth; + } + + /** + * Gets the theoretical height of the key in pixels, excluding the padding. This is the exact + * height that the key was defined to be, but this will likely differ from the actual drawn + * height because the normal (drawn/functional) width was determined by rounding the top and + * bottom edge to fit evenly in a pixel. + * @return The defined width of the key in pixels, excluding the padding. + */ + public float getDefinedHeight() { + return mDefinedHeight; + } + + /** + * Gets the x-coordinate of the top-left corner of the key in pixels, excluding the padding. + * @return The x-coordinate of the top-left corner of the key in pixels, excluding the padding. + */ + public int getX() { + return mX; + } + + /** + * Gets the y-coordinate of the top-left corner of the key in pixels, excluding the padding. + * @return The y-coordinate of the top-left corner of the key in pixels, excluding the padding. + */ + public int getY() { + return mY; + } + + /** + * Gets the amount of padding for the hitbox above the key's visible position. + * @return The hitbox padding above the key. + */ + public int getTopPadding() { + return mY - mHitbox.top; + } + + /** + * Gets the amount of padding for the hitbox below the key's visible position. + * @return The hitbox padding below the key. + */ + public int getBottomPadding() { + return mHitbox.bottom - mY - mHeight; + } + + /** + * Gets the amount of padding for the hitbox to the left of the key's visible position. + * @return The hitbox padding to the left of the key. + */ + public int getLeftPadding() { + return mX - mHitbox.left; + } + + /** + * Gets the amount of padding for the hitbox to the right of the key's visible position. + * @return The hitbox padding to the right of the key. + */ + public int getRightPadding() { + return mHitbox.right - mX - mWidth; + } + + /** + * Informs the key that it has been pressed, in case it needs to change its appearance or + * state. + * @see #onReleased() + */ + public void onPressed() { + mPressed = true; + } + + /** + * Informs the key that it has been released, in case it needs to change its appearance or + * state. + * @see #onPressed() + */ + public void onReleased() { + mPressed = false; + } + + /** + * Detects if a point falls on this key. + * @param x the x-coordinate of the point + * @param y the y-coordinate of the point + * @return whether or not the point falls on the key. This generally includes all points + * between the key and the keyboard edge for keys attached to an edge and all points between + * the key and halfway to adjacent keys. + */ + public boolean isOnKey(final int x, final int y) { + return mHitbox.contains(x, y); + } + + /** + * Returns the square of the distance to the nearest clickable edge of the key and the given + * point. + * @param x the x-coordinate of the point + * @param y the y-coordinate of the point + * @return the square of the distance of the point from the nearest edge of the key + */ + public int squaredDistanceToHitboxEdge(final int x, final int y) { + final int left = mHitbox.left; + // The hit box right is exclusive + final int right = mHitbox.right - 1; + final int top = mHitbox.top; + // The hit box bottom is exclusive + final int bottom = mHitbox.bottom - 1; + final int edgeX = x < left ? left : Math.min(x, right); + final int edgeY = y < top ? top : Math.min(y, bottom); + final int dx = x - edgeX; + final int dy = y - edgeY; + return dx * dx + dy * dy; + } + + static class KeyBackgroundState { + private final int[] mReleasedState; + private final int[] mPressedState; + + private KeyBackgroundState(final int ... attrs) { + mReleasedState = attrs; + mPressedState = Arrays.copyOf(attrs, attrs.length + 1); + mPressedState[attrs.length] = android.R.attr.state_pressed; + } + + public int[] getState(final boolean pressed) { + return pressed ? mPressedState : mReleasedState; + } + + public static final KeyBackgroundState[] STATES = { + // 0: BACKGROUND_TYPE_EMPTY + new KeyBackgroundState(android.R.attr.state_empty), + // 1: BACKGROUND_TYPE_NORMAL + new KeyBackgroundState(), + // 2: BACKGROUND_TYPE_FUNCTIONAL + new KeyBackgroundState(), + // 3: BACKGROUND_TYPE_STICKY_OFF + new KeyBackgroundState(android.R.attr.state_checkable), + // 4: BACKGROUND_TYPE_STICKY_ON + new KeyBackgroundState(android.R.attr.state_checkable, android.R.attr.state_checked), + // 5: BACKGROUND_TYPE_ACTION + new KeyBackgroundState(android.R.attr.state_active), + // 6: BACKGROUND_TYPE_SPACEBAR + new KeyBackgroundState(), + }; + } + + /** + * Returns the background drawable for the key, based on the current state and type of the key. + * @return the background drawable of the key. + * @see android.graphics.drawable.StateListDrawable#setState(int[]) + */ + public final Drawable selectBackgroundDrawable(final Drawable keyBackground, + final Drawable functionalKeyBackground, + final Drawable spacebarBackground) { + final Drawable background; + if (mBackgroundType == BACKGROUND_TYPE_FUNCTIONAL) { + background = functionalKeyBackground; + } else if (mBackgroundType == BACKGROUND_TYPE_SPACEBAR) { + background = spacebarBackground; + } else { + background = keyBackground; + } + final int[] state = KeyBackgroundState.STATES[mBackgroundType].getState(mPressed); + background.setState(state); + return background; + } + + public static class Spacer extends Key { + public Spacer(final TypedArray keyAttr, final KeyStyle keyStyle, + final KeyboardParams params, final KeyboardRow row) { + super(null /* keySpec */, keyAttr, keyStyle, params, row); + } + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyDetector.java b/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyDetector.java new file mode 100644 index 0000000..76f2176 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyDetector.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.keyboard; + +/** + * This class handles key detection. + */ +public class KeyDetector { + private final int mKeyHysteresisDistanceSquared; + private final int mKeyHysteresisDistanceForSlidingModifierSquared; + + private Keyboard mKeyboard; + private int mCorrectionX; + private int mCorrectionY; + + public KeyDetector() { + this(0.0f /* keyHysteresisDistance */, 0.0f /* keyHysteresisDistanceForSlidingModifier */); + } + + /** + * Key detection object constructor with key hysteresis distances. + * + * @param keyHysteresisDistance if the pointer movement distance is smaller than this, the + * movement will not be handled as meaningful movement. The unit is pixel. + * @param keyHysteresisDistanceForSlidingModifier the same parameter for sliding input that + * starts from a modifier key such as shift and symbols key. + */ + public KeyDetector(final float keyHysteresisDistance, + final float keyHysteresisDistanceForSlidingModifier) { + mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance); + mKeyHysteresisDistanceForSlidingModifierSquared = (int)( + keyHysteresisDistanceForSlidingModifier * keyHysteresisDistanceForSlidingModifier); + } + + public void setKeyboard(final Keyboard keyboard, final float correctionX, + final float correctionY) { + if (keyboard == null) { + throw new NullPointerException(); + } + mCorrectionX = (int)correctionX; + mCorrectionY = (int)correctionY; + mKeyboard = keyboard; + } + + public int getKeyHysteresisDistanceSquared(final boolean isSlidingFromModifier) { + return isSlidingFromModifier + ? mKeyHysteresisDistanceForSlidingModifierSquared : mKeyHysteresisDistanceSquared; + } + + public int getTouchX(final int x) { + return x + mCorrectionX; + } + + // TODO: Remove vertical correction. + public int getTouchY(final int y) { + return y + mCorrectionY; + } + + public Keyboard getKeyboard() { + return mKeyboard; + } + + public boolean alwaysAllowsKeySelectionByDraggingFinger() { + return false; + } + + /** + * Detect the key whose hitbox the touch point is in. + * + * @param x The x-coordinate of a touch point + * @param y The y-coordinate of a touch point + * @return the key that the touch point hits. + */ + public Key detectHitKey(final int x, final int y) { + if (mKeyboard == null) { + return null; + } + final int touchX = getTouchX(x); + final int touchY = getTouchY(y); + + for (final Key key: mKeyboard.getNearestKeys(touchX, touchY)) { + if (key.isOnKey(touchX, touchY)) { + return key; + } + } + return null; + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/keyboard/Keyboard.java b/app/src/main/java/com/colorful/keyboard/theme/keyboard/Keyboard.java new file mode 100644 index 0000000..798416b --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/keyboard/Keyboard.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.keyboard; + +import android.util.SparseArray; + +import com.colorful.keyboard.theme.keyboard.internal.KeyVisualAttributes; +import com.colorful.keyboard.theme.keyboard.internal.KeyboardIconsSet; +import com.colorful.keyboard.theme.keyboard.internal.KeyboardParams; +import com.colorful.keyboard.theme.latin.common.Constants; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard + * consists of rows of keys. + *

The layout file for a keyboard contains XML that looks like the following snippet:

+ *
+ * <Keyboard
+ *         latin:keyWidth="10%p"
+ *         latin:rowHeight="50px"
+ *         latin:horizontalGap="2%p"
+ *         latin:verticalGap="2%p" >
+ *     <Row latin:keyWidth="10%p" >
+ *         <Key latin:keyLabel="A" />
+ *         ...
+ *     </Row>
+ *     ...
+ * </Keyboard>
+ * 
+ */ +public class Keyboard { + public final KeyboardId mId; + + /** Total height of the keyboard, including the padding and keys */ + public final int mOccupiedHeight; + /** Total width of the keyboard, including the padding and keys */ + public final int mOccupiedWidth; + + /** The padding below the keyboard */ + public final float mBottomPadding; + /** Default gap between rows */ + public final float mVerticalGap; + /** Default gap between columns */ + public final float mHorizontalGap; + + /** Per keyboard key visual parameters */ + public final KeyVisualAttributes mKeyVisualAttributes; + + public final int mMostCommonKeyHeight; + public final int mMostCommonKeyWidth; + + /** More keys keyboard template */ + public final int mMoreKeysTemplate; + + /** List of keys in this keyboard */ + private final List mSortedKeys; + public final List mShiftKeys; + public final List mAltCodeKeysWhileTyping; + public final KeyboardIconsSet mIconsSet; + + private final SparseArray mKeyCache = new SparseArray<>(); + + private final ProximityInfo mProximityInfo; + + public Keyboard(final KeyboardParams params) { + mId = params.mId; + mOccupiedHeight = params.mOccupiedHeight; + mOccupiedWidth = params.mOccupiedWidth; + mMostCommonKeyHeight = params.mMostCommonKeyHeight; + mMostCommonKeyWidth = params.mMostCommonKeyWidth; + mMoreKeysTemplate = params.mMoreKeysTemplate; + mKeyVisualAttributes = params.mKeyVisualAttributes; + mBottomPadding = params.mBottomPadding; + mVerticalGap = params.mVerticalGap; + mHorizontalGap = params.mHorizontalGap; + + mSortedKeys = Collections.unmodifiableList(new ArrayList<>(params.mSortedKeys)); + mShiftKeys = Collections.unmodifiableList(params.mShiftKeys); + mAltCodeKeysWhileTyping = Collections.unmodifiableList(params.mAltCodeKeysWhileTyping); + mIconsSet = params.mIconsSet; + + mProximityInfo = new ProximityInfo(params.mGridWidth, params.mGridHeight, + mOccupiedWidth, mOccupiedHeight, mSortedKeys); + } + + /** + * Return the sorted list of keys of this keyboard. + * The keys are sorted from top-left to bottom-right order. + * The list may contain {@link Key.Spacer} object as well. + * @return the sorted unmodifiable list of {@link Key}s of this keyboard. + */ + public List getSortedKeys() { + return mSortedKeys; + } + + public Key getKey(final int code) { + if (code == Constants.CODE_UNSPECIFIED) { + return null; + } + synchronized (mKeyCache) { + final int index = mKeyCache.indexOfKey(code); + if (index >= 0) { + return mKeyCache.valueAt(index); + } + + for (final Key key : getSortedKeys()) { + if (key.getCode() == code) { + mKeyCache.put(code, key); + return key; + } + } + mKeyCache.put(code, null); + return null; + } + } + + public boolean hasKey(final Key aKey) { + if (mKeyCache.indexOfValue(aKey) >= 0) { + return true; + } + + for (final Key key : getSortedKeys()) { + if (key == aKey) { + mKeyCache.put(key.getCode(), key); + return true; + } + } + return false; + } + + @Override + public String toString() { + return mId.toString(); + } + + /** + * Returns the array of the keys that are closest to the given point. + * @param x the x-coordinate of the point + * @param y the y-coordinate of the point + * @return the list of the nearest keys to the given point. If the given + * point is out of range, then an array of size zero is returned. + */ + public List getNearestKeys(final int x, final int y) { + // Avoid dead pixels at edges of the keyboard + final int adjustedX = Math.max(0, Math.min(x, mOccupiedWidth - 1)); + final int adjustedY = Math.max(0, Math.min(y, mOccupiedHeight - 1)); + return mProximityInfo.getNearestKeys(adjustedX, adjustedY); + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardActionListener.java b/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardActionListener.java new file mode 100644 index 0000000..30d2f39 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardActionListener.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.keyboard; + +public interface KeyboardActionListener { + /** + * Called when the user presses a key. This is sent before the {@link #onCodeInput} is called. + * For keys that repeat, this is only called once. + * + * @param primaryCode the unicode of the key being pressed. If the touch is not on a valid key, + * the value will be zero. + * @param repeatCount how many times the key was repeated. Zero if it is the first press. + * @param isSinglePointer true if pressing has occurred while no other key is being pressed. + */ + void onPressKey(int primaryCode, int repeatCount, boolean isSinglePointer); + + /** + * Called when the user releases a key. This is sent after the {@link #onCodeInput} is called. + * For keys that repeat, this is only called once. + * + * @param primaryCode the code of the key that was released + * @param withSliding true if releasing has occurred because the user slid finger from the key + * to other key without releasing the finger. + */ + void onReleaseKey(int primaryCode, boolean withSliding); + + /** + * Send a key code to the listener. + * + * @param primaryCode this is the code of the key that was pressed + * @param x x-coordinate pixel of touched event. If {@link #onCodeInput} is not called by + * {@link PointerTracker} or so, the value should be + * {@link Constants#NOT_A_COORDINATE}. If it's called on insertion from the + * suggestion strip, it should be {@link Constants#SUGGESTION_STRIP_COORDINATE}. + * @param y y-coordinate pixel of touched event. If {@link #onCodeInput} is not called by + * {@link PointerTracker} or so, the value should be + * {@link Constants#NOT_A_COORDINATE}.If it's called on insertion from the + * suggestion strip, it should be {@link Constants#SUGGESTION_STRIP_COORDINATE}. + * @param isKeyRepeat true if this is a key repeat, false otherwise + */ + // TODO: change this to send an Event object instead + void onCodeInput(int primaryCode, int x, int y, boolean isKeyRepeat); + + /** + * Sends a string of characters to the listener. + * + * @param text the string of characters to be registered. + */ + void onTextInput(final String rawText); + + /** + * Called when user finished sliding key input. + */ + void onFinishSlidingInput(); + + /** + * Send a non-"code input" custom request to the listener. + * @return true if the request has been consumed, false otherwise. + */ + boolean onCustomRequest(int requestCode); + void onMovePointer(int steps); + void onMoveDeletePointer(int steps); + void onUpWithDeletePointerActive(); + + KeyboardActionListener EMPTY_LISTENER = new Adapter(); + + class Adapter implements KeyboardActionListener { + @Override + public void onPressKey(int primaryCode, int repeatCount, boolean isSinglePointer) {} + @Override + public void onReleaseKey(int primaryCode, boolean withSliding) {} + @Override + public void onCodeInput(int primaryCode, int x, int y, boolean isKeyRepeat) {} + @Override + public void onTextInput(String text) {} + @Override + public void onFinishSlidingInput() {} + @Override + public boolean onCustomRequest(int requestCode) { + return false; + } + @Override + public void onMovePointer(int steps) {} + @Override + public void onMoveDeletePointer(int steps) {} + @Override + public void onUpWithDeletePointerActive() {} + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardId.java b/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardId.java new file mode 100644 index 0000000..93e4a79 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardId.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.keyboard; + +import android.text.InputType; +import android.text.TextUtils; +import android.view.inputmethod.EditorInfo; + +import com.colorful.keyboard.theme.compat.EditorInfoCompatUtils; +import com.colorful.keyboard.theme.latin.Subtype; +import com.colorful.keyboard.theme.latin.utils.InputTypeUtils; + +import java.util.Arrays; +import java.util.Locale; + + +/** + * Unique identifier for each keyboard type. + */ +public final class KeyboardId { + public static final int MODE_TEXT = 0; + public static final int MODE_URL = 1; + public static final int MODE_EMAIL = 2; + public static final int MODE_IM = 3; + public static final int MODE_PHONE = 4; + public static final int MODE_NUMBER = 5; + public static final int MODE_DATE = 6; + public static final int MODE_TIME = 7; + public static final int MODE_DATETIME = 8; + + public static final int ELEMENT_ALPHABET = 0; + public static final int ELEMENT_ALPHABET_MANUAL_SHIFTED = 1; + public static final int ELEMENT_ALPHABET_AUTOMATIC_SHIFTED = 2; + public static final int ELEMENT_ALPHABET_SHIFT_LOCKED = 3; + public static final int ELEMENT_SYMBOLS = 5; + public static final int ELEMENT_SYMBOLS_SHIFTED = 6; + public static final int ELEMENT_PHONE = 7; + public static final int ELEMENT_PHONE_SYMBOLS = 8; + public static final int ELEMENT_NUMBER = 9; + + public final Subtype mSubtype; + public final int mThemeId; + public final int mWidth; + public final int mHeight; + public final int mMode; + public final int mElementId; + public final EditorInfo mEditorInfo; + public final boolean mLanguageSwitchKeyEnabled; + public final String mCustomActionLabel; + public final boolean mShowMoreKeys; + public final boolean mShowNumberRow; + + private final int mHashCode; + + public KeyboardId(final int elementId, final KeyboardLayoutSet.Params params) { + mSubtype = params.mSubtype; + mThemeId = params.mKeyboardThemeId; + mWidth = params.mKeyboardWidth; + mHeight = params.mKeyboardHeight; + mMode = params.mMode; + mElementId = elementId; + mEditorInfo = params.mEditorInfo; + mLanguageSwitchKeyEnabled = params.mLanguageSwitchKeyEnabled; + mCustomActionLabel = (mEditorInfo.actionLabel != null) + ? mEditorInfo.actionLabel.toString() : null; + mShowMoreKeys = params.mShowMoreKeys; + mShowNumberRow = params.mShowNumberRow; + + mHashCode = computeHashCode(this); + } + + private static int computeHashCode(final KeyboardId id) { + return Arrays.hashCode(new Object[] { + id.mElementId, + id.mMode, + id.mWidth, + id.mHeight, + id.passwordInput(), + id.mLanguageSwitchKeyEnabled, + id.isMultiLine(), + id.imeAction(), + id.mCustomActionLabel, + id.navigateNext(), + id.navigatePrevious(), + id.mSubtype, + id.mThemeId + }); + } + + private boolean equals(final KeyboardId other) { + if (other == this) + return true; + return other.mElementId == mElementId + && other.mMode == mMode + && other.mWidth == mWidth + && other.mHeight == mHeight + && other.passwordInput() == passwordInput() + && other.mLanguageSwitchKeyEnabled == mLanguageSwitchKeyEnabled + && other.isMultiLine() == isMultiLine() + && other.imeAction() == imeAction() + && TextUtils.equals(other.mCustomActionLabel, mCustomActionLabel) + && other.navigateNext() == navigateNext() + && other.navigatePrevious() == navigatePrevious() + && other.mSubtype.equals(mSubtype) + && other.mThemeId == mThemeId; + } + + private static boolean isAlphabetKeyboard(final int elementId) { + return elementId < ELEMENT_SYMBOLS; + } + + public boolean isAlphabetKeyboard() { + return isAlphabetKeyboard(mElementId); + } + + public boolean navigateNext() { + return (mEditorInfo.imeOptions & EditorInfo.IME_FLAG_NAVIGATE_NEXT) != 0 + || imeAction() == EditorInfo.IME_ACTION_NEXT; + } + + public boolean navigatePrevious() { + return (mEditorInfo.imeOptions & EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS) != 0 + || imeAction() == EditorInfo.IME_ACTION_PREVIOUS; + } + + public boolean passwordInput() { + final int inputType = mEditorInfo.inputType; + return InputTypeUtils.isPasswordInputType(inputType) + || InputTypeUtils.isVisiblePasswordInputType(inputType); + } + + public boolean isMultiLine() { + return (mEditorInfo.inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) != 0; + } + + public int imeAction() { + return InputTypeUtils.getImeOptionsActionIdFromEditorInfo(mEditorInfo); + } + + public Locale getLocale() { + return mSubtype.getLocaleObject(); + } + + @Override + public boolean equals(final Object other) { + return other instanceof KeyboardId && equals((KeyboardId) other); + } + + @Override + public int hashCode() { + return mHashCode; + } + + @Override + public String toString() { + return String.format(Locale.ROOT, "[%s %s:%s %dx%d %s %s%s%s%s%s%s %s]", + elementIdToName(mElementId), + mSubtype.getLocale(), + mSubtype.getKeyboardLayoutSet(), + mWidth, mHeight, + modeName(mMode), + actionName(imeAction()), + (navigateNext() ? " navigateNext" : ""), + (navigatePrevious() ? " navigatePrevious" : ""), + (passwordInput() ? " passwordInput" : ""), + (mLanguageSwitchKeyEnabled ? " languageSwitchKeyEnabled" : ""), + (isMultiLine() ? " isMultiLine" : ""), + KeyboardTheme.getKeyboardThemeName(mThemeId) + ); + } + + public static boolean equivalentEditorInfoForKeyboard(final EditorInfo a, final EditorInfo b) { + if (a == null && b == null) return true; + if (a == null || b == null) return false; + return a.inputType == b.inputType + && a.imeOptions == b.imeOptions + && TextUtils.equals(a.privateImeOptions, b.privateImeOptions); + } + + public static String elementIdToName(final int elementId) { + switch (elementId) { + case ELEMENT_ALPHABET: return "alphabet"; + case ELEMENT_ALPHABET_MANUAL_SHIFTED: return "alphabetManualShifted"; + case ELEMENT_ALPHABET_AUTOMATIC_SHIFTED: return "alphabetAutomaticShifted"; + case ELEMENT_ALPHABET_SHIFT_LOCKED: return "alphabetShiftLocked"; + case ELEMENT_SYMBOLS: return "symbols"; + case ELEMENT_SYMBOLS_SHIFTED: return "symbolsShifted"; + case ELEMENT_PHONE: return "phone"; + case ELEMENT_PHONE_SYMBOLS: return "phoneSymbols"; + case ELEMENT_NUMBER: return "number"; + default: return null; + } + } + + public static String modeName(final int mode) { + switch (mode) { + case MODE_TEXT: return "text"; + case MODE_URL: return "url"; + case MODE_EMAIL: return "email"; + case MODE_IM: return "im"; + case MODE_PHONE: return "phone"; + case MODE_NUMBER: return "number"; + case MODE_DATE: return "date"; + case MODE_TIME: return "time"; + case MODE_DATETIME: return "datetime"; + default: return null; + } + } + + public static String actionName(final int actionId) { + return (actionId == InputTypeUtils.IME_ACTION_CUSTOM_LABEL) ? "actionCustomLabel" + : EditorInfoCompatUtils.imeActionName(actionId); + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardLayoutSet.java b/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardLayoutSet.java new file mode 100644 index 0000000..4654381 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardLayoutSet.java @@ -0,0 +1,372 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.keyboard; + +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.text.InputType; +import android.util.Log; +import android.util.SparseArray; +import android.util.Xml; +import android.view.inputmethod.EditorInfo; + +import com.colorful.keyboard.theme.R; +import com.colorful.keyboard.theme.keyboard.internal.KeyboardBuilder; +import com.colorful.keyboard.theme.keyboard.internal.KeyboardParams; +import com.colorful.keyboard.theme.keyboard.internal.UniqueKeysCache; +import com.colorful.keyboard.theme.latin.Subtype; +import com.colorful.keyboard.theme.latin.utils.InputTypeUtils; +import com.colorful.keyboard.theme.latin.utils.XmlParseUtils; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.lang.ref.SoftReference; +import java.util.HashMap; + +/** + * This class represents a set of keyboard layouts. Each of them represents a different keyboard + * specific to a keyboard state, such as alphabet, symbols, and so on. Layouts in the same + * {@link KeyboardLayoutSet} are related to each other. + * A {@link KeyboardLayoutSet} needs to be created for each + * {@link EditorInfo}. + */ +public final class KeyboardLayoutSet { + private static final String TAG = KeyboardLayoutSet.class.getSimpleName(); + private static final boolean DEBUG_CACHE = false; + + private static final String TAG_KEYBOARD_SET = "KeyboardLayoutSet"; + private static final String TAG_ELEMENT = "Element"; + + private static final String KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX = "keyboard_layout_set_"; + + private final Context mContext; + private final Params mParams; + + // How many layouts we forcibly keep in cache. This only includes ALPHABET (default) and + // ALPHABET_AUTOMATIC_SHIFTED layouts - other layouts may stay in memory in the map of + // soft-references, but we forcibly cache this many alphabetic/auto-shifted layouts. + private static final int FORCIBLE_CACHE_SIZE = 4; + // By construction of soft references, anything that is also referenced somewhere else + // will stay in the cache. So we forcibly keep some references in an array to prevent + // them from disappearing from sKeyboardCache. + private static final Keyboard[] sForcibleKeyboardCache = new Keyboard[FORCIBLE_CACHE_SIZE]; + private static final HashMap> sKeyboardCache = + new HashMap<>(); + private static final UniqueKeysCache sUniqueKeysCache = UniqueKeysCache.newInstance(); + + @SuppressWarnings("serial") + public static final class KeyboardLayoutSetException extends RuntimeException { + public final KeyboardId mKeyboardId; + + public KeyboardLayoutSetException(final Throwable cause, final KeyboardId keyboardId) { + super(cause); + mKeyboardId = keyboardId; + } + } + + private static final class ElementParams { + int mKeyboardXmlId; + boolean mAllowRedundantMoreKeys; + public ElementParams() {} + } + + public static final class Params { + String mKeyboardLayoutSetName; + int mMode; + // TODO: Use {@link InputAttributes} instead of these variables. + EditorInfo mEditorInfo; + boolean mLanguageSwitchKeyEnabled; + Subtype mSubtype; + int mKeyboardThemeId; + int mKeyboardWidth; + int mKeyboardHeight; + boolean mShowMoreKeys; + boolean mShowNumberRow; + // Sparse array of KeyboardLayoutSet element parameters indexed by element's id. + final SparseArray mKeyboardLayoutSetElementIdToParamsMap = + new SparseArray<>(); + } + + public static void onSystemLocaleChanged() { + clearKeyboardCache(); + } + + public static void onKeyboardThemeChanged() { + clearKeyboardCache(); + } + + private static void clearKeyboardCache() { + sKeyboardCache.clear(); + sUniqueKeysCache.clear(); + } + + KeyboardLayoutSet(final Context context, final Params params) { + mContext = context; + mParams = params; + } + + public Keyboard getKeyboard(final int baseKeyboardLayoutSetElementId) { + final int keyboardLayoutSetElementId; + switch (mParams.mMode) { + case KeyboardId.MODE_PHONE: + if (baseKeyboardLayoutSetElementId == KeyboardId.ELEMENT_SYMBOLS) { + keyboardLayoutSetElementId = KeyboardId.ELEMENT_PHONE_SYMBOLS; + } else { + keyboardLayoutSetElementId = KeyboardId.ELEMENT_PHONE; + } + break; + case KeyboardId.MODE_NUMBER: + case KeyboardId.MODE_DATE: + case KeyboardId.MODE_TIME: + case KeyboardId.MODE_DATETIME: + keyboardLayoutSetElementId = KeyboardId.ELEMENT_NUMBER; + break; + default: + keyboardLayoutSetElementId = baseKeyboardLayoutSetElementId; + break; + } + + ElementParams elementParams = mParams.mKeyboardLayoutSetElementIdToParamsMap.get( + keyboardLayoutSetElementId); + if (elementParams == null) { + elementParams = mParams.mKeyboardLayoutSetElementIdToParamsMap.get( + KeyboardId.ELEMENT_ALPHABET); + } + // Note: The keyboard for each shift state, and mode are represented as an elementName + // attribute in a keyboard_layout_set XML file. Also each keyboard layout XML resource is + // specified as an elementKeyboard attribute in the file. + // The KeyboardId is an internal key for a Keyboard object. + + final KeyboardId id = new KeyboardId(keyboardLayoutSetElementId, mParams); + return getKeyboard(elementParams, id); + } + + private Keyboard getKeyboard(final ElementParams elementParams, final KeyboardId id) { + final SoftReference ref = sKeyboardCache.get(id); + final Keyboard cachedKeyboard = (ref == null) ? null : ref.get(); + if (cachedKeyboard != null) { + if (DEBUG_CACHE) { + Log.d(TAG, "keyboard cache size=" + sKeyboardCache.size() + ": HIT id=" + id); + } + return cachedKeyboard; + } + + final KeyboardBuilder builder = + new KeyboardBuilder<>(mContext, new KeyboardParams(sUniqueKeysCache)); + sUniqueKeysCache.setEnabled(id.isAlphabetKeyboard()); + builder.setAllowRedundantMoreKes(elementParams.mAllowRedundantMoreKeys); + final int keyboardXmlId = elementParams.mKeyboardXmlId; + builder.load(keyboardXmlId, id); + final Keyboard keyboard = builder.build(); + sKeyboardCache.put(id, new SoftReference<>(keyboard)); + if ((id.mElementId == KeyboardId.ELEMENT_ALPHABET + || id.mElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED)) { + // We only forcibly cache the primary, "ALPHABET", layouts. + for (int i = sForcibleKeyboardCache.length - 1; i >= 1; --i) { + sForcibleKeyboardCache[i] = sForcibleKeyboardCache[i - 1]; + } + sForcibleKeyboardCache[0] = keyboard; + if (DEBUG_CACHE) { + Log.d(TAG, "forcing caching of keyboard with id=" + id); + } + } + if (DEBUG_CACHE) { + Log.d(TAG, "keyboard cache size=" + sKeyboardCache.size() + ": " + + ((ref == null) ? "LOAD" : "GCed") + " id=" + id); + } + return keyboard; + } + + public static final class Builder { + private final Context mContext; + private final Resources mResources; + + private final Params mParams = new Params(); + + private static final EditorInfo EMPTY_EDITOR_INFO = new EditorInfo(); + + public Builder(final Context context, final EditorInfo ei) { + mContext = context; + mResources = context.getResources(); + final Params params = mParams; + + final EditorInfo editorInfo = (ei != null) ? ei : EMPTY_EDITOR_INFO; + params.mMode = getKeyboardMode(editorInfo); + // TODO: Consolidate those with {@link InputAttributes}. + params.mEditorInfo = editorInfo; + } + + public Builder setKeyboardTheme(final int themeId) { + mParams.mKeyboardThemeId = themeId; + return this; + } + + public Builder setKeyboardGeometry(final int keyboardWidth, final int keyboardHeight) { + mParams.mKeyboardWidth = keyboardWidth; + mParams.mKeyboardHeight = keyboardHeight; + return this; + } + + public Builder setSubtype(final Subtype subtype) { + // TODO: Consolidate with {@link InputAttributes}. + mParams.mSubtype = subtype; + mParams.mKeyboardLayoutSetName = KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX + + subtype.getKeyboardLayoutSet(); + return this; + } + + public Builder setLanguageSwitchKeyEnabled(final boolean enabled) { + mParams.mLanguageSwitchKeyEnabled = enabled; + return this; + } + + public Builder setShowSpecialChars(final boolean enabled) { + mParams.mShowMoreKeys = enabled; + return this; + } + + public Builder setShowNumberRow(final boolean enabled) { + mParams.mShowNumberRow = enabled; + return this; + } + + public KeyboardLayoutSet build() { + if (mParams.mSubtype == null) + throw new RuntimeException("KeyboardLayoutSet subtype is not specified"); + final int xmlId = getXmlId(mResources, mParams.mKeyboardLayoutSetName); + try { + parseKeyboardLayoutSet(mResources, xmlId); + } catch (final IOException | XmlPullParserException e) { + throw new RuntimeException(e.getMessage() + " in " + mParams.mKeyboardLayoutSetName, + e); + } + return new KeyboardLayoutSet(mContext, mParams); + } + + private static int getXmlId(final Resources resources, final String keyboardLayoutSetName) { + final String packageName = resources.getResourcePackageName( + R.xml.keyboard_layout_set_qwerty); + return resources.getIdentifier(keyboardLayoutSetName, "xml", packageName); + } + + private void parseKeyboardLayoutSet(final Resources res, final int resId) + throws XmlPullParserException, IOException { + final XmlResourceParser parser = res.getXml(resId); + try { + while (parser.getEventType() != XmlPullParser.END_DOCUMENT) { + final int event = parser.next(); + if (event == XmlPullParser.START_TAG) { + final String tag = parser.getName(); + if (TAG_KEYBOARD_SET.equals(tag)) { + parseKeyboardLayoutSetContent(parser); + } else { + throw new XmlParseUtils.IllegalStartTag(parser, tag, TAG_KEYBOARD_SET); + } + } + } + } finally { + parser.close(); + } + } + + private void parseKeyboardLayoutSetContent(final XmlPullParser parser) + throws XmlPullParserException, IOException { + while (parser.getEventType() != XmlPullParser.END_DOCUMENT) { + final int event = parser.next(); + if (event == XmlPullParser.START_TAG) { + final String tag = parser.getName(); + if (TAG_ELEMENT.equals(tag)) { + parseKeyboardLayoutSetElement(parser); + } else { + throw new XmlParseUtils.IllegalStartTag(parser, tag, TAG_KEYBOARD_SET); + } + } else if (event == XmlPullParser.END_TAG) { + final String tag = parser.getName(); + if (TAG_KEYBOARD_SET.equals(tag)) { + break; + } + throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_KEYBOARD_SET); + } + } + } + + private void parseKeyboardLayoutSetElement(final XmlPullParser parser) + throws XmlPullParserException, IOException { + final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), + R.styleable.KeyboardLayoutSet_Element); + try { + XmlParseUtils.checkAttributeExists(a, + R.styleable.KeyboardLayoutSet_Element_elementName, "elementName", + TAG_ELEMENT, parser); + XmlParseUtils.checkAttributeExists(a, + R.styleable.KeyboardLayoutSet_Element_elementKeyboard, "elementKeyboard", + TAG_ELEMENT, parser); + XmlParseUtils.checkEndTag(TAG_ELEMENT, parser); + + final ElementParams elementParams = new ElementParams(); + final int elementName = a.getInt( + R.styleable.KeyboardLayoutSet_Element_elementName, 0); + elementParams.mKeyboardXmlId = a.getResourceId( + R.styleable.KeyboardLayoutSet_Element_elementKeyboard, 0); + elementParams.mAllowRedundantMoreKeys = a.getBoolean( + R.styleable.KeyboardLayoutSet_Element_allowRedundantMoreKeys, true); + mParams.mKeyboardLayoutSetElementIdToParamsMap.put(elementName, elementParams); + } finally { + a.recycle(); + } + } + + private static int getKeyboardMode(final EditorInfo editorInfo) { + final int inputType = editorInfo.inputType; + final int variation = inputType & InputType.TYPE_MASK_VARIATION; + + switch (inputType & InputType.TYPE_MASK_CLASS) { + case InputType.TYPE_CLASS_NUMBER: + return KeyboardId.MODE_NUMBER; + case InputType.TYPE_CLASS_DATETIME: + switch (variation) { + case InputType.TYPE_DATETIME_VARIATION_DATE: + return KeyboardId.MODE_DATE; + case InputType.TYPE_DATETIME_VARIATION_TIME: + return KeyboardId.MODE_TIME; + default: // InputType.TYPE_DATETIME_VARIATION_NORMAL + return KeyboardId.MODE_DATETIME; + } + case InputType.TYPE_CLASS_PHONE: + return KeyboardId.MODE_PHONE; + case InputType.TYPE_CLASS_TEXT: + if (InputTypeUtils.isEmailVariation(variation)) { + return KeyboardId.MODE_EMAIL; + } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) { + return KeyboardId.MODE_URL; + } else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { + return KeyboardId.MODE_IM; + } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) { + return KeyboardId.MODE_TEXT; + } else { + return KeyboardId.MODE_TEXT; + } + default: + return KeyboardId.MODE_TEXT; + } + } + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardSwitcher.java b/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardSwitcher.java new file mode 100644 index 0000000..8e674d4 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardSwitcher.java @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.keyboard; + +import android.content.Context; +import android.content.res.Resources; +import android.os.Build; +import android.util.Log; +import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.colorful.keyboard.theme.App; +import com.colorful.keyboard.theme.R; +import com.colorful.keyboard.theme.event.Event; +import com.colorful.keyboard.theme.keyboard.internal.KeyboardState; +import com.colorful.keyboard.theme.keyboard.internal.KeyboardTextsSet; +import com.colorful.keyboard.theme.latin.InputView; +import com.colorful.keyboard.theme.latin.LatinIME; +import com.colorful.keyboard.theme.latin.RichInputMethodManager; +import com.colorful.keyboard.theme.latin.settings.Settings; +import com.colorful.keyboard.theme.latin.settings.SettingsValues; +import com.colorful.keyboard.theme.latin.utils.CapsModeUtils; +import com.colorful.keyboard.theme.latin.utils.LanguageOnSpacebarUtils; +import com.colorful.keyboard.theme.latin.utils.RecapitalizeStatus; +import com.colorful.keyboard.theme.latin.utils.ResourceUtils; +import com.colorful.keyboard.theme.myutil.SPUtils; + +import java.io.File; + +public final class KeyboardSwitcher implements KeyboardState.SwitchActions { + private static final String TAG = KeyboardSwitcher.class.getSimpleName(); + + private InputView mCurrentInputView; + private int mCurrentUiMode; + private int mCurrentTextColor = 0x0; + private View mMainKeyboardFrame; + private MainKeyboardView mKeyboardView; + private LatinIME mLatinIME; + private RichInputMethodManager mRichImm; + + private KeyboardState mState; + + private KeyboardLayoutSet mKeyboardLayoutSet; + // TODO: The following {@link KeyboardTextsSet} should be in {@link KeyboardLayoutSet}. + private final KeyboardTextsSet mKeyboardTextsSet = new KeyboardTextsSet(); + + private KeyboardTheme mKeyboardTheme; + private Context mThemeContext; + + private static KeyboardSwitcher sInstance = new KeyboardSwitcher(); + + public static KeyboardSwitcher getInstance() { + return sInstance; + } + + private KeyboardSwitcher() { + // Intentional empty constructor for singleton. + } + + public static void init(final LatinIME latinIme) { + sInstance.initInternal(latinIme); + } + + private void initInternal(final LatinIME latinIme) { + mLatinIME = latinIme; + mRichImm = RichInputMethodManager.getInstance(); + mState = new KeyboardState(this); + } + + public void updateKeyboardTheme(final int uiMode) { + final boolean themeUpdated = updateKeyboardThemeAndContextThemeWrapper( + mLatinIME, KeyboardTheme.getKeyboardTheme(mLatinIME), uiMode); + if (themeUpdated && mKeyboardView != null) { + mLatinIME.setInputView(onCreateInputView(uiMode)); + } + } + + private boolean updateKeyboardThemeAndContextThemeWrapper(final Context context, + final KeyboardTheme keyboardTheme, final int uiMode) { + int newTextColor = 0x0; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + newTextColor = context.getResources().getColor(R.color.key_text_color_lxx_system); + } + + if (mThemeContext == null + || !keyboardTheme.equals(mKeyboardTheme) + || mCurrentUiMode != uiMode + || newTextColor != mCurrentTextColor) { + mKeyboardTheme = keyboardTheme; + mCurrentUiMode = uiMode; + mCurrentTextColor = newTextColor; + mThemeContext = new ContextThemeWrapper(context, keyboardTheme.mStyleId); + KeyboardLayoutSet.onKeyboardThemeChanged(); + return true; + } + return false; + } + + public void loadKeyboard(final EditorInfo editorInfo, final SettingsValues settingsValues, + final int currentAutoCapsState, final int currentRecapitalizeState) { + final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder( + mThemeContext, editorInfo); + final Resources res = mThemeContext.getResources(); + final int keyboardWidth = mLatinIME.getMaxWidth(); + final int keyboardHeight = ResourceUtils.getKeyboardHeight(res, settingsValues); + builder.setKeyboardTheme(mKeyboardTheme.mThemeId); + builder.setKeyboardGeometry(keyboardWidth, keyboardHeight); + builder.setSubtype(mRichImm.getCurrentSubtype()); + builder.setLanguageSwitchKeyEnabled(mLatinIME.shouldShowLanguageSwitchKey()); + builder.setShowSpecialChars(!settingsValues.mHideSpecialChars); + builder.setShowNumberRow(settingsValues.mShowNumberRow); + mKeyboardLayoutSet = builder.build(); + try { + mState.onLoadKeyboard(currentAutoCapsState, currentRecapitalizeState); + mKeyboardTextsSet.setLocale(mRichImm.getCurrentSubtype().getLocaleObject(), + mThemeContext); + } catch (KeyboardLayoutSet.KeyboardLayoutSetException e) { + Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause()); + } + } + + public void saveKeyboardState() { + if (getKeyboard() != null) { + mState.onSaveKeyboardState(); + } + } + + public void onHideWindow() { + if (mKeyboardView != null) { + mKeyboardView.onHideWindow(); + } + } + + private void setKeyboard( + final int keyboardId, + final KeyboardSwitchState toggleState) { + final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent(); + setMainKeyboardFrame(currentSettingsValues, toggleState); + // TODO: pass this object to setKeyboard instead of getting the current values. + final MainKeyboardView keyboardView = mKeyboardView; + final Keyboard oldKeyboard = keyboardView.getKeyboard(); + final Keyboard newKeyboard = mKeyboardLayoutSet.getKeyboard(keyboardId); + keyboardView.setKeyboard(newKeyboard); + keyboardView.setKeyPreviewPopupEnabled( + currentSettingsValues.mKeyPreviewPopupOn, + currentSettingsValues.mKeyPreviewPopupDismissDelay); + final boolean subtypeChanged = (oldKeyboard == null) + || !newKeyboard.mId.mSubtype.equals(oldKeyboard.mId.mSubtype); + final int languageOnSpacebarFormatType = LanguageOnSpacebarUtils + .getLanguageOnSpacebarFormatType(newKeyboard.mId.mSubtype); + keyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, languageOnSpacebarFormatType); + } + + public Keyboard getKeyboard() { + if (mKeyboardView != null) { + return mKeyboardView.getKeyboard(); + } + return null; + } + + // TODO: Remove this method. Come up with a more comprehensive way to reset the keyboard layout + // when a keyboard layout set doesn't get reloaded in LatinIME.onStartInputViewInternal(). + public void resetKeyboardStateToAlphabet(final int currentAutoCapsState, + final int currentRecapitalizeState) { + mState.onResetKeyboardStateToAlphabet(currentAutoCapsState, currentRecapitalizeState); + } + + public void onPressKey(final int code, final boolean isSinglePointer, + final int currentAutoCapsState, final int currentRecapitalizeState) { + mState.onPressKey(code, isSinglePointer, currentAutoCapsState, currentRecapitalizeState); + } + + public void onReleaseKey(final int code, final boolean withSliding, + final int currentAutoCapsState, final int currentRecapitalizeState) { + mState.onReleaseKey(code, withSliding, currentAutoCapsState, currentRecapitalizeState); + } + + public void onFinishSlidingInput(final int currentAutoCapsState, + final int currentRecapitalizeState) { + mState.onFinishSlidingInput(currentAutoCapsState, currentRecapitalizeState); + } + + // Implements {@link KeyboardState.SwitchActions}. + @Override + public void setAlphabetKeyboard() { + if (DEBUG_ACTION) { + Log.d(TAG, "setAlphabetKeyboard"); + } + setKeyboard(KeyboardId.ELEMENT_ALPHABET, KeyboardSwitchState.OTHER); + } + + // Implements {@link KeyboardState.SwitchActions}. + @Override + public void setAlphabetManualShiftedKeyboard() { + if (DEBUG_ACTION) { + Log.d(TAG, "setAlphabetManualShiftedKeyboard"); + } + setKeyboard(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED, KeyboardSwitchState.OTHER); + } + + // Implements {@link KeyboardState.SwitchActions}. + @Override + public void setAlphabetAutomaticShiftedKeyboard() { + if (DEBUG_ACTION) { + Log.d(TAG, "setAlphabetAutomaticShiftedKeyboard"); + } + setKeyboard(KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardSwitchState.OTHER); + } + + // Implements {@link KeyboardState.SwitchActions}. + @Override + public void setAlphabetShiftLockedKeyboard() { + if (DEBUG_ACTION) { + Log.d(TAG, "setAlphabetShiftLockedKeyboard"); + } + setKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED, KeyboardSwitchState.OTHER); + } + + // Implements {@link KeyboardState.SwitchActions}. + @Override + public void setSymbolsKeyboard() { + if (DEBUG_ACTION) { + Log.d(TAG, "setSymbolsKeyboard"); + } + setKeyboard(KeyboardId.ELEMENT_SYMBOLS, KeyboardSwitchState.OTHER); + } + + // Implements {@link KeyboardState.SwitchActions}. + @Override + public void setSymbolsShiftedKeyboard() { + if (DEBUG_ACTION) { + Log.d(TAG, "setSymbolsShiftedKeyboard"); + } + setKeyboard(KeyboardId.ELEMENT_SYMBOLS_SHIFTED, KeyboardSwitchState.SYMBOLS_SHIFTED); + } + + public boolean isImeSuppressedByHardwareKeyboard( + final SettingsValues settingsValues, + final KeyboardSwitchState toggleState) { + return settingsValues.mHasHardwareKeyboard && toggleState == KeyboardSwitchState.HIDDEN; + } + + private void setMainKeyboardFrame( + final SettingsValues settingsValues, + final KeyboardSwitchState toggleState) { + final int visibility = isImeSuppressedByHardwareKeyboard(settingsValues, toggleState) + ? View.GONE : View.VISIBLE; + mKeyboardView.setVisibility(visibility); + // The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}. + // @see #getVisibleKeyboardView() and + // @see LatinIME#onComputeInset(android.inputmethodservice.InputMethodService.Insets) + mMainKeyboardFrame.setVisibility(visibility); + } + + public enum KeyboardSwitchState { + HIDDEN(-1), + SYMBOLS_SHIFTED(KeyboardId.ELEMENT_SYMBOLS_SHIFTED), + OTHER(-1); + + final int mKeyboardId; + + KeyboardSwitchState(int keyboardId) { + mKeyboardId = keyboardId; + } + } + + public KeyboardSwitchState getKeyboardSwitchState() { + boolean hidden = mKeyboardLayoutSet == null + || mKeyboardView == null + || !mKeyboardView.isShown(); + if (hidden) { + return KeyboardSwitchState.HIDDEN; + } else if (isShowingKeyboardId(KeyboardId.ELEMENT_SYMBOLS_SHIFTED)) { + return KeyboardSwitchState.SYMBOLS_SHIFTED; + } + return KeyboardSwitchState.OTHER; + } + + // Future method for requesting an updating to the shift state. + @Override + public void requestUpdatingShiftState(final int autoCapsFlags, final int recapitalizeMode) { + if (DEBUG_ACTION) { + Log.d(TAG, "requestUpdatingShiftState: " + + " autoCapsFlags=" + CapsModeUtils.flagsToString(autoCapsFlags) + + " recapitalizeMode=" + RecapitalizeStatus.modeToString(recapitalizeMode)); + } + mState.onUpdateShiftState(autoCapsFlags, recapitalizeMode); + } + + // Implements {@link KeyboardState.SwitchActions}. + @Override + public void startDoubleTapShiftKeyTimer() { + if (DEBUG_TIMER_ACTION) { + Log.d(TAG, "startDoubleTapShiftKeyTimer"); + } + final MainKeyboardView keyboardView = getMainKeyboardView(); + if (keyboardView != null) { + keyboardView.startDoubleTapShiftKeyTimer(); + } + } + + // Implements {@link KeyboardState.SwitchActions}. + @Override + public void cancelDoubleTapShiftKeyTimer() { + if (DEBUG_TIMER_ACTION) { + Log.d(TAG, "setAlphabetKeyboard"); + } + final MainKeyboardView keyboardView = getMainKeyboardView(); + if (keyboardView != null) { + keyboardView.cancelDoubleTapShiftKeyTimer(); + } + } + + // Implements {@link KeyboardState.SwitchActions}. + @Override + public boolean isInDoubleTapShiftKeyTimeout() { + if (DEBUG_TIMER_ACTION) { + Log.d(TAG, "isInDoubleTapShiftKeyTimeout"); + } + final MainKeyboardView keyboardView = getMainKeyboardView(); + return keyboardView != null && keyboardView.isInDoubleTapShiftKeyTimeout(); + } + + /** + * Updates state machine to figure out when to automatically switch back to the previous mode. + */ + public void onEvent(final Event event, final int currentAutoCapsState, + final int currentRecapitalizeState) { + mState.onEvent(event, currentAutoCapsState, currentRecapitalizeState); + } + + public boolean isShowingKeyboardId(int... keyboardIds) { + if (mKeyboardView == null || !mKeyboardView.isShown()) { + return false; + } + int activeKeyboardId = mKeyboardView.getKeyboard().mId.mElementId; + for (int keyboardId : keyboardIds) { + if (activeKeyboardId == keyboardId) { + return true; + } + } + return false; + } + + public boolean isShowingMoreKeysPanel() { + return mKeyboardView.isShowingMoreKeysPanel(); + } + + public View getVisibleKeyboardView() { + return mKeyboardView; + } + + public MainKeyboardView getMainKeyboardView() { + return mKeyboardView; + } + + public void deallocateMemory() { + if (mKeyboardView != null) { + mKeyboardView.cancelAllOngoingEvents(); + mKeyboardView.deallocateMemory(); + } + } + + public View onCreateInputView(final int uiMode) { + if (mKeyboardView != null) { + mKeyboardView.closing(); + } + + updateKeyboardThemeAndContextThemeWrapper( + mLatinIME, KeyboardTheme.getKeyboardTheme(mLatinIME /* context */), uiMode); + mCurrentInputView = (InputView) LayoutInflater.from(mThemeContext).inflate( + R.layout.input_view, null); + mMainKeyboardFrame = mCurrentInputView.findViewById(R.id.main_keyboard_frame); + ImageView imageView = mCurrentInputView.findViewById(R.id.iv_keyboard_bg); + ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams(); + + mMainKeyboardFrame.post(new Runnable() { + @Override + public void run() { + layoutParams.height = mMainKeyboardFrame.getHeight(); + layoutParams.width = mMainKeyboardFrame.getWidth(); + /* if (layoutParams.height > layoutParams.width){ + return; + }*/ + File file = new File(SPUtils.getInstance().getString("bg")); + Glide.with(App.Companion.getApp()).load(file).into(imageView); + } + }); + + + mKeyboardView = (MainKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view); + mKeyboardView.setKeyboardActionListener(mLatinIME); + return mCurrentInputView; + } +} diff --git a/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardTheme.java b/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardTheme.java new file mode 100644 index 0000000..8682d86 --- /dev/null +++ b/app/src/main/java/com/colorful/keyboard/theme/keyboard/KeyboardTheme.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.colorful.keyboard.theme.keyboard; + +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +import com.colorful.keyboard.theme.R; +import com.colorful.keyboard.theme.compat.PreferenceManagerCompat; +import com.colorful.keyboard.theme.latin.settings.Settings; + +public final class KeyboardTheme { + private static final String TAG = KeyboardTheme.class.getSimpleName(); + + static final String KEYBOARD_THEME_KEY = "pref_keyboard_theme_20140509"; + + // These should be aligned with Keyboard.themeId and Keyboard.Case.keyboardTheme + // attributes' values in attrs.xml. + public static final int THEME_ID_LIGHT_BORDER = 1; + public static final int THEME_ID_DARK_BORDER = 2; + public static final int THEME_ID_LIGHT = 3; + public static final int THEME_ID_DARK = 4; + public static final int THEME_ID_SYSTEM = 5; + public static final int THEME_ID_SYSTEM_BORDER = 6; + public static final int DEFAULT_THEME_ID = THEME_ID_LIGHT; + + /* package private for testing */ + static final KeyboardTheme[] KEYBOARD_THEMES = { + new KeyboardTheme(THEME_ID_LIGHT, "LXXLight", R.style.KeyboardTheme_LXX_Light), + new KeyboardTheme(THEME_ID_DARK, "LXXDark", R.style.KeyboardTheme_LXX_Dark), + new KeyboardTheme(THEME_ID_LIGHT_BORDER, "LXXLightBorder", R.style.KeyboardTheme_LXX_Light_Border), + new KeyboardTheme(THEME_ID_DARK_BORDER, "LXXDarkBorder", R.style.KeyboardTheme_LXX_Dark_Border), + new KeyboardTheme(THEME_ID_SYSTEM, "LXXSystem", R.style.KeyboardTheme_LXX_System), + new KeyboardTheme(THEME_ID_SYSTEM_BORDER, "LXXSystemBorder", R.style.KeyboardTheme_LXX_System_Border), + }; + + public final int mThemeId; + public final int mStyleId; + public final String mThemeName; + + // Note: The themeId should be aligned with "themeId" attribute of Keyboard style + // in values/themes- + \ No newline at end of file diff --git a/app/src/main/res/values-sw430dp/config-per-form-factor.xml b/app/src/main/res/values-sw430dp/config-per-form-factor.xml new file mode 100644 index 0000000..b5fd7b7 --- /dev/null +++ b/app/src/main/res/values-sw430dp/config-per-form-factor.xml @@ -0,0 +1,31 @@ + + + + + + + true + false + true + + false + false + diff --git a/app/src/main/res/values-sw430dp/config-screen-metrics.xml b/app/src/main/res/values-sw430dp/config-screen-metrics.xml new file mode 100644 index 0000000..bc1c964 --- /dev/null +++ b/app/src/main/res/values-sw430dp/config-screen-metrics.xml @@ -0,0 +1,24 @@ + + + + + + 1 + diff --git a/app/src/main/res/values-sw600dp-land/config.xml b/app/src/main/res/values-sw600dp-land/config.xml new file mode 100644 index 0000000..c036932 --- /dev/null +++ b/app/src/main/res/values-sw600dp-land/config.xml @@ -0,0 +1,54 @@ + + + + + + + + 283.5dp + 40%p + + 81.9dp + + 2.727%p + 0.0%p + 0.450%p + 0.450%p + 4.5%p + 0.9%p + + 50% + 90dp + 60% + 32% + 23% + 20% + 29% + 30.0% + 4dp + + + + 4.5%p + + 15%p + diff --git a/app/src/main/res/values-sw600dp/config-per-form-factor.xml b/app/src/main/res/values-sw600dp/config-per-form-factor.xml new file mode 100644 index 0000000..e922aac --- /dev/null +++ b/app/src/main/res/values-sw600dp/config-per-form-factor.xml @@ -0,0 +1,31 @@ + + + + + + + false + true + false + + false + false + diff --git a/app/src/main/res/values-sw600dp/config-screen-metrics.xml b/app/src/main/res/values-sw600dp/config-screen-metrics.xml new file mode 100644 index 0000000..d16c925 --- /dev/null +++ b/app/src/main/res/values-sw600dp/config-screen-metrics.xml @@ -0,0 +1,24 @@ + + + + + + 3 + diff --git a/app/src/main/res/values-sw600dp/config.xml b/app/src/main/res/values-sw600dp/config.xml new file mode 100644 index 0000000..c1e05f6 --- /dev/null +++ b/app/src/main/res/values-sw600dp/config.xml @@ -0,0 +1,62 @@ + + + + + + 35.0dp + + + + 302.4dp + 46%p + -35.0%p + + 63.0dp + 6dp + + + 98.3dp + + 2.335%p + 4.0%p + 0.783%p + 0.783%p + 4.5%p + 1.565%p + + 50% + 65dp + 50% + 60% + 32% + 23% + 20% + 22% + 28.0% + 3dp + 3dp + + + + 4.5%p + + 25.096%p + diff --git a/app/src/main/res/values-sw768dp-land/config.xml b/app/src/main/res/values-sw768dp-land/config.xml new file mode 100644 index 0000000..304a4c6 --- /dev/null +++ b/app/src/main/res/values-sw768dp-land/config.xml @@ -0,0 +1,54 @@ + + + + + + + + 365.4dp + 35%p + + 1.896%p + 0.0%p + 0.515%p + 0.515%p + 3.690%p + 1.030%p + + 81.9dp + + 50% + 75dp + 112dp + 60% + 32% + 23% + 20% + 24% + 24.00% + + + + 3.690%p + + 15%p + diff --git a/app/src/main/res/values-sw768dp/config-per-form-factor.xml b/app/src/main/res/values-sw768dp/config-per-form-factor.xml new file mode 100644 index 0000000..5ed1e81 --- /dev/null +++ b/app/src/main/res/values-sw768dp/config-per-form-factor.xml @@ -0,0 +1,31 @@ + + + + + + + false + true + false + + true + false + diff --git a/app/src/main/res/values-sw768dp/config-screen-metrics.xml b/app/src/main/res/values-sw768dp/config-screen-metrics.xml new file mode 100644 index 0000000..7769ad8 --- /dev/null +++ b/app/src/main/res/values-sw768dp/config-screen-metrics.xml @@ -0,0 +1,24 @@ + + + + + + 2 + diff --git a/app/src/main/res/values-sw768dp/config.xml b/app/src/main/res/values-sw768dp/config.xml new file mode 100644 index 0000000..c642def --- /dev/null +++ b/app/src/main/res/values-sw768dp/config.xml @@ -0,0 +1,61 @@ + + + + + + + + 302.4dp + 46%p + -35.0%p + + 2.335%p + 0.0%p + 0.533%p + 0.533%p + 3.312%p + 1.066%p + + 63.0dp + 12dp + + + 98.3dp + + 50% + 68dp + 70dp + 50% + 60% + 32% + 23% + 20% + 26% + 29.03% + 3dp + 3dp + + + + 3.312%p + + 24.466%p + diff --git a/app/src/main/res/values-v21/platform-theme.xml b/app/src/main/res/values-v21/platform-theme.xml new file mode 100644 index 0000000..4fe8a94 --- /dev/null +++ b/app/src/main/res/values-v21/platform-theme.xml @@ -0,0 +1,24 @@ + + + + + + diff --git a/app/src/main/res/values-v24/keyboard-themes.xml b/app/src/main/res/values-v24/keyboard-themes.xml new file mode 100644 index 0000000..b8d9117 --- /dev/null +++ b/app/src/main/res/values-v24/keyboard-themes.xml @@ -0,0 +1,40 @@ + + + + + + 3 + 4 + 1 + 2 + 5 + 6 + + + + @color/background_lxx_light + @color/background_lxx_dark + @color/background_lxx_light + @color/background_lxx_dark + @color/background_lxx_system + @color/background_lxx_system + + diff --git a/app/src/main/res/values-v24/themes-lxx-system-border.xml b/app/src/main/res/values-v24/themes-lxx-system-border.xml new file mode 100644 index 0000000..eaad88d --- /dev/null +++ b/app/src/main/res/values-v24/themes-lxx-system-border.xml @@ -0,0 +1,64 @@ + + + + + + + + + diff --git a/app/src/main/res/values-v24/themes-lxx-system.xml b/app/src/main/res/values-v24/themes-lxx-system.xml new file mode 100644 index 0000000..50a6c04 --- /dev/null +++ b/app/src/main/res/values-v24/themes-lxx-system.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + diff --git a/app/src/main/res/values-v31/colors.xml b/app/src/main/res/values-v31/colors.xml new file mode 100644 index 0000000..9b9c2bb --- /dev/null +++ b/app/src/main/res/values-v31/colors.xml @@ -0,0 +1,34 @@ + + + + + + @android:color/system_neutral1_100 + @android:color/system_neutral1_200 + @android:color/system_accent1_800 + @android:color/system_accent1_800 + @android:color/system_accent1_800 + @android:color/system_accent2_600 + @android:color/system_accent1_800 + @android:color/system_accent1_800 + @android:color/system_neutral1_50 + @android:color/system_neutral1_300 + 4dp + diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml new file mode 100644 index 0000000..9fba712 --- /dev/null +++ b/app/src/main/res/values/attrs.xml @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..afaa39e --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,54 @@ + + + + + #ECEFF1 + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + + #00ffffff + #ffffff + #ffffff + #ffffff + #ffffff + #ffffff + #B34DB6AC + #22222222 + #2637474F + + #263238 + #CCFFFFFF + #CCFFFFFF + #80FFFFFF + #80FFFFFF + #B380CBC4 + #66222222 + #19FFFFFF + + 4dp + #80ffffff + #ffffff + #00ffffff + #000000 + #80000000 + diff --git a/app/src/main/res/values/config-common.xml b/app/src/main/res/values/config-common.xml new file mode 100644 index 0000000..33f34f8 --- /dev/null +++ b/app/src/main/res/values/config-common.xml @@ -0,0 +1,68 @@ + + + + + 100 + + 400 + 50 + + 350 + + + 53 + + true + 100 + + 300 + 700 + 100 + 10 + 5 + + + 1200 + + + 8.0dp + + + 100 + -1 + 8.0dp + + 128 + 1dp + + 32 + 16 + 12.6dp + 40 + + + 0.0dp + + + 150 + 50 + 5 + diff --git a/app/src/main/res/values/config-per-form-factor.xml b/app/src/main/res/values/config-per-form-factor.xml new file mode 100644 index 0000000..2ffee67 --- /dev/null +++ b/app/src/main/res/values/config-per-form-factor.xml @@ -0,0 +1,30 @@ + + + + + + + true + false + true + + false + diff --git a/app/src/main/res/values/config-screen-metrics.xml b/app/src/main/res/values/config-screen-metrics.xml new file mode 100644 index 0000000..9962994 --- /dev/null +++ b/app/src/main/res/values/config-screen-metrics.xml @@ -0,0 +1,24 @@ + + + + + + 0 + diff --git a/app/src/main/res/values/config.xml b/app/src/main/res/values/config.xml new file mode 100644 index 0000000..b557aac --- /dev/null +++ b/app/src/main/res/values/config.xml @@ -0,0 +1,77 @@ + + + + + + false + + 5.0dp + + + + 205.6dp + 46%p + -61.8%p + + 52.8dp + + + 63.36dp + 8dp + + 2.335%p + 2.335%p + 0.870%p + 0.870%p + 6.905%p + 1.739%p + + -26.4dp + 50dp + 122dp + 0dp + 82% + 55% + 90% + 34% + 25% + 30% + 35% + 33.735% + 1dp + 2dp + + 0dp + 0dp + 0dp + 0dp + + + + 2.814%p + + 9.194%p + 55% + 41% + diff --git a/app/src/main/res/values/donottranslate-config-spacing-and-punctuations.xml b/app/src/main/res/values/donottranslate-config-spacing-and-punctuations.xml new file mode 100644 index 0000000..7f43807 --- /dev/null +++ b/app/src/main/res/values/donottranslate-config-spacing-and-punctuations.xml @@ -0,0 +1,32 @@ + + + + + + "  "()[]{}*&<>+=|.,;:!?/_\" + + + 46 + + + 46 + + .?! + diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml new file mode 100644 index 0000000..3e3d252 --- /dev/null +++ b/app/src/main/res/values/donottranslate.xml @@ -0,0 +1,64 @@ + + + + + + en_US + en_GB + es_US + hi_ZZ + sr_ZZ + + + + + hi_ZZ + sr_ZZ + + + Hinglish + Srpski + + + + qwerty + qwertz + azerty + dvorak + colemak + workman + pcqwerty + abc + + + + QWERTY + QWERTZ + AZERTY + Dvorak + Colemak + Workman + PC + ABC + + diff --git a/app/src/main/res/values/keyboard-icons-lxx-dark.xml b/app/src/main/res/values/keyboard-icons-lxx-dark.xml new file mode 100644 index 0000000..46be25f --- /dev/null +++ b/app/src/main/res/values/keyboard-icons-lxx-dark.xml @@ -0,0 +1,42 @@ + + + + + + diff --git a/app/src/main/res/values/keyboard-icons-lxx-light.xml b/app/src/main/res/values/keyboard-icons-lxx-light.xml new file mode 100644 index 0000000..5d30b51 --- /dev/null +++ b/app/src/main/res/values/keyboard-icons-lxx-light.xml @@ -0,0 +1,42 @@ + + + + + + diff --git a/app/src/main/res/values/keyboard-themes.xml b/app/src/main/res/values/keyboard-themes.xml new file mode 100644 index 0000000..8a4723f --- /dev/null +++ b/app/src/main/res/values/keyboard-themes.xml @@ -0,0 +1,45 @@ + + + + + + @string/keyboard_theme_light + @string/keyboard_theme_dark + @string/keyboard_theme_light_border + @string/keyboard_theme_dark_border + @string/keyboard_theme_system + @string/keyboard_theme_system_border + + + + 3 + 4 + 1 + 2 + + + + @color/background_lxx_light + @color/background_lxx_dark + @color/background_lxx_light + @color/background_lxx_dark + + diff --git a/app/src/main/res/values/keypress-vibration-durations.xml b/app/src/main/res/values/keypress-vibration-durations.xml new file mode 100644 index 0000000..032b5fd --- /dev/null +++ b/app/src/main/res/values/keypress-vibration-durations.xml @@ -0,0 +1,63 @@ + + + + + + + MODEL=Nexus S:BRAND=google,5 + + MODEL=Galaxy Nexus:BRAND=google,5 + + MODEL=Nexus 4:BRAND=google,8 + + MODEL=Nexus 10:BRAND=google,16 + + MODEL=GT-I(9100[GMPT]?|9108|9210T?):MANUFACTURER=samsung,8 + MODEL=SGH-(I9[27]7R?|I927|T989D?):MANUFACTURER=samsung,8 + MODEL=SHW-M250[KLS]?|SPH-D710|SCH-R760:MANUFACTURER=samsung,8 + MODEL=ISW11SC|SC-02C:MANUFACTURER=samsung,8 + + MODEL=(SAMSUNG-)?GT-I(930[05][NT]?|9308):MANUFACTURER=samsung,8 + MODEL=(SAMSUNG-)?SGH-(T999[V]?|I747[M]?|N064|N035):MANUFACTURER=samsung,8 + MODEL=(SAMSUNG-)?SCH-(J021|R530|I535|I939):MANUFACTURER=samsung,8 + MODEL=(SAMSUNG-)?(SCL21|SC-06D|SC-03E):MANUFACTURER=samsung,8 + MODEL=(SAMSUNG-)?(SHV-210[KLS]?|SPH-L710):MANUFACTURER=samsung,8 + + MODEL=(SAMSUNG-)?GT-I(950[0258][G]?):MANUFACTURER=samsung,7 + MODEL=(SAMSUNG-)?SGH-(I337|M919|N045):MANUFACTURER=samsung,7 + MODEL=(SAMSUNG-)?SCH-(I545|I959|R970):MANUFACTURER=samsung,7 + MODEL=(SAMSUNG-)?SPH-(L720):MANUFACTURER=samsung,7 + MODEL=(SAMSUNG-)?(SC-04E):MANUFACTURER=samsung,7 + MODEL=(SAMSUNG-)?(SHV-E300[KLS]?):MANUFACTURER=samsung,7 + + MODEL=LG-E97[013]|LS970|L-01E:MANUFACTURER=LGE,15 + + MODEL=HTC One X:MANUFACTURER=HTC,20 + + MODEL=HTC One:MANUFACTURER=HTC,15 + MODEL=HTL22:MANUFACTURER=HTC,15 + + MODEL=XT907:MANUFACTURER=motorola,30 + + MODEL=XT1035:MANUFACTURER=motorola,18 + + MODEL=C6603|C6806:MANUFACTURER=Sony,35 + + diff --git a/app/src/main/res/values/keypress-volumes.xml b/app/src/main/res/values/keypress-volumes.xml new file mode 100644 index 0000000..074581d --- /dev/null +++ b/app/src/main/res/values/keypress-volumes.xml @@ -0,0 +1,30 @@ + + + + + + HARDWARE=herring,0.5f + HARDWARE=tuna,0.5f + HARDWARE=stingray,0.4f + HARDWARE=grouper,0.3f + HARDWARE=mako,0.3f + HARDWARE=manta,0.2f + + diff --git a/app/src/main/res/values/platform-theme.xml b/app/src/main/res/values/platform-theme.xml new file mode 100644 index 0000000..07d2925 --- /dev/null +++ b/app/src/main/res/values/platform-theme.xml @@ -0,0 +1,43 @@ + + + + + + + + + diff --git a/app/src/main/res/values/strings-action-keys.xml b/app/src/main/res/values/strings-action-keys.xml new file mode 100644 index 0000000..bae8ac9 --- /dev/null +++ b/app/src/main/res/values/strings-action-keys.xml @@ -0,0 +1,24 @@ + + + + + Pause + Wait + diff --git a/app/src/main/res/values/strings-appname.xml b/app/src/main/res/values/strings-appname.xml new file mode 100644 index 0000000..9ea5ec5 --- /dev/null +++ b/app/src/main/res/values/strings-appname.xml @@ -0,0 +1,7 @@ + + + + Colorful keyboard + Colorful keyboard Settings + Your privacy comes first + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..6cbf6e4 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,134 @@ + + + + Recommend + Cool + Go + Downloading +  %s %% + Preview + Apply it + Applied + Download + Resource Loading… + + Vibrate on keypress + Test + + + Sound on keypress + + + Popup on keypress + + + Preferences + + Key press + + Appearance + + Theme + + + %sms + + System default + + + Auto-capitalization + + Capitalize the first word of each sentence + + + Languages + + + English (UK) + + English (US) + + Spanish (US) + + Hinglish + + Serbian (Latin) + + %s (%s) + + Traditional + + Compact + + BDS + + Q + + F + + Akkhor + + Material Dark Border + Material Light Border + Material Dark + Material Light + System Default + System Default Border + + + Add + + Remove + + + Keypress vibration duration + + Keypress sound volume + + Key long press delay + + + Default + + %s%% + + Keyboard height + Set custom keyboard color + Hide special characters + Hide language switch key + Switch to other keyboards + Show separate number row + Space swipe cursor move + Delete swipe + Use matching navigation bar color + Simple Keyboard is not enabled. Click OK to open Languages & Input settings. You will need to select Simple Keyboard in your current keyboard to use it. + Enabled keyboard languages + Add language + Remove language + %s keyboard layouts + Change keyboard + Privacy Policy + License + Accept and Continue + diff --git a/app/src/main/res/values/themes-common.xml b/app/src/main/res/values/themes-common.xml new file mode 100644 index 0000000..43ebd56 --- /dev/null +++ b/app/src/main/res/values/themes-common.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + diff --git a/app/src/main/res/values/themes-lxx-dark.xml b/app/src/main/res/values/themes-lxx-dark.xml new file mode 100644 index 0000000..972161e --- /dev/null +++ b/app/src/main/res/values/themes-lxx-dark.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + diff --git a/app/src/main/res/values/themes-lxx-light-border.xml b/app/src/main/res/values/themes-lxx-light-border.xml new file mode 100644 index 0000000..5d37bbc --- /dev/null +++ b/app/src/main/res/values/themes-lxx-light-border.xml @@ -0,0 +1,64 @@ + + + + + + + + + diff --git a/app/src/main/res/values/themes-lxx-light.xml b/app/src/main/res/values/themes-lxx-light.xml new file mode 100644 index 0000000..ebb8f3b --- /dev/null +++ b/app/src/main/res/values/themes-lxx-light.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..d5b12f7 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/values.xml b/app/src/main/res/values/values.xml new file mode 100644 index 0000000..bf64cc3 --- /dev/null +++ b/app/src/main/res/values/values.xml @@ -0,0 +1,123 @@ + + + #ff0477ff + #ff0467ef + #ffffffff + #ffbbbbbb + #ffeeeeee + #ff333333 + #7f999999 + #ff333333 + #ff333333 + #ffefefef + #ffefefef + #ffa8afbf + #ff989faf + 20sp + 10dp + 48dp + 101dp + 154dp + 16sp + 56dp + 20sp + 5dp + 6dp + 6dp + Back + Done + More + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml new file mode 100644 index 0000000..fa0f996 --- /dev/null +++ b/app/src/main/res/xml/backup_rules.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 0000000..9ee9997 --- /dev/null +++ b/app/src/main/res/xml/data_extraction_rules.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/empty_settings.xml b/app/src/main/res/xml/empty_settings.xml new file mode 100644 index 0000000..7964c75 --- /dev/null +++ b/app/src/main/res/xml/empty_settings.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/app/src/main/res/xml/file_path.xml b/app/src/main/res/xml/file_path.xml new file mode 100644 index 0000000..bf62f64 --- /dev/null +++ b/app/src/main/res/xml/file_path.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/kbd_abc.xml b/app/src/main/res/xml/kbd_abc.xml new file mode 100644 index 0000000..b50ef08 --- /dev/null +++ b/app/src/main/res/xml/kbd_abc.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_arabic.xml b/app/src/main/res/xml/kbd_arabic.xml new file mode 100644 index 0000000..074d497 --- /dev/null +++ b/app/src/main/res/xml/kbd_arabic.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_armenian_phonetic.xml b/app/src/main/res/xml/kbd_armenian_phonetic.xml new file mode 100644 index 0000000..6d48760 --- /dev/null +++ b/app/src/main/res/xml/kbd_armenian_phonetic.xml @@ -0,0 +1,31 @@ + + + + + + diff --git a/app/src/main/res/xml/kbd_azerty.xml b/app/src/main/res/xml/kbd_azerty.xml new file mode 100644 index 0000000..a3a98c1 --- /dev/null +++ b/app/src/main/res/xml/kbd_azerty.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_bengali.xml b/app/src/main/res/xml/kbd_bengali.xml new file mode 100644 index 0000000..b865664 --- /dev/null +++ b/app/src/main/res/xml/kbd_bengali.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_bengali_akkhor.xml b/app/src/main/res/xml/kbd_bengali_akkhor.xml new file mode 100644 index 0000000..ca93410 --- /dev/null +++ b/app/src/main/res/xml/kbd_bengali_akkhor.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_bengali_unijoy.xml b/app/src/main/res/xml/kbd_bengali_unijoy.xml new file mode 100644 index 0000000..8b345dc --- /dev/null +++ b/app/src/main/res/xml/kbd_bengali_unijoy.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_bulgarian.xml b/app/src/main/res/xml/kbd_bulgarian.xml new file mode 100644 index 0000000..93c0e5e --- /dev/null +++ b/app/src/main/res/xml/kbd_bulgarian.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_bulgarian_bds.xml b/app/src/main/res/xml/kbd_bulgarian_bds.xml new file mode 100644 index 0000000..68592b3 --- /dev/null +++ b/app/src/main/res/xml/kbd_bulgarian_bds.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_colemak.xml b/app/src/main/res/xml/kbd_colemak.xml new file mode 100644 index 0000000..e557358 --- /dev/null +++ b/app/src/main/res/xml/kbd_colemak.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_dvorak.xml b/app/src/main/res/xml/kbd_dvorak.xml new file mode 100644 index 0000000..eef574d --- /dev/null +++ b/app/src/main/res/xml/kbd_dvorak.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_east_slavic.xml b/app/src/main/res/xml/kbd_east_slavic.xml new file mode 100644 index 0000000..cc6f3c8 --- /dev/null +++ b/app/src/main/res/xml/kbd_east_slavic.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_farsi.xml b/app/src/main/res/xml/kbd_farsi.xml new file mode 100644 index 0000000..f36e04b --- /dev/null +++ b/app/src/main/res/xml/kbd_farsi.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/app/src/main/res/xml/kbd_georgian.xml b/app/src/main/res/xml/kbd_georgian.xml new file mode 100644 index 0000000..8ba1551 --- /dev/null +++ b/app/src/main/res/xml/kbd_georgian.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_greek.xml b/app/src/main/res/xml/kbd_greek.xml new file mode 100644 index 0000000..5864f54 --- /dev/null +++ b/app/src/main/res/xml/kbd_greek.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_hebrew.xml b/app/src/main/res/xml/kbd_hebrew.xml new file mode 100644 index 0000000..074d58f --- /dev/null +++ b/app/src/main/res/xml/kbd_hebrew.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_hindi.xml b/app/src/main/res/xml/kbd_hindi.xml new file mode 100644 index 0000000..61de1d0 --- /dev/null +++ b/app/src/main/res/xml/kbd_hindi.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_hindi_compact.xml b/app/src/main/res/xml/kbd_hindi_compact.xml new file mode 100644 index 0000000..3ddfc2d --- /dev/null +++ b/app/src/main/res/xml/kbd_hindi_compact.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_kannada.xml b/app/src/main/res/xml/kbd_kannada.xml new file mode 100644 index 0000000..bca6d31 --- /dev/null +++ b/app/src/main/res/xml/kbd_kannada.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_khmer.xml b/app/src/main/res/xml/kbd_khmer.xml new file mode 100644 index 0000000..8bc4ed7 --- /dev/null +++ b/app/src/main/res/xml/kbd_khmer.xml @@ -0,0 +1,31 @@ + + + + + + diff --git a/app/src/main/res/xml/kbd_lao.xml b/app/src/main/res/xml/kbd_lao.xml new file mode 100644 index 0000000..963be29 --- /dev/null +++ b/app/src/main/res/xml/kbd_lao.xml @@ -0,0 +1,31 @@ + + + + + + diff --git a/app/src/main/res/xml/kbd_macedonian.xml b/app/src/main/res/xml/kbd_macedonian.xml new file mode 100644 index 0000000..d487b89 --- /dev/null +++ b/app/src/main/res/xml/kbd_macedonian.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_malayalam.xml b/app/src/main/res/xml/kbd_malayalam.xml new file mode 100644 index 0000000..b73f15c --- /dev/null +++ b/app/src/main/res/xml/kbd_malayalam.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_marathi.xml b/app/src/main/res/xml/kbd_marathi.xml new file mode 100644 index 0000000..78398a7 --- /dev/null +++ b/app/src/main/res/xml/kbd_marathi.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_mongolian.xml b/app/src/main/res/xml/kbd_mongolian.xml new file mode 100644 index 0000000..b63bdab --- /dev/null +++ b/app/src/main/res/xml/kbd_mongolian.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_more_keys_keyboard_template.xml b/app/src/main/res/xml/kbd_more_keys_keyboard_template.xml new file mode 100644 index 0000000..4d12779 --- /dev/null +++ b/app/src/main/res/xml/kbd_more_keys_keyboard_template.xml @@ -0,0 +1,30 @@ + + + + + diff --git a/app/src/main/res/xml/kbd_nepali_romanized.xml b/app/src/main/res/xml/kbd_nepali_romanized.xml new file mode 100644 index 0000000..1f0711e --- /dev/null +++ b/app/src/main/res/xml/kbd_nepali_romanized.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_nepali_traditional.xml b/app/src/main/res/xml/kbd_nepali_traditional.xml new file mode 100644 index 0000000..01aacef --- /dev/null +++ b/app/src/main/res/xml/kbd_nepali_traditional.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_nordic.xml b/app/src/main/res/xml/kbd_nordic.xml new file mode 100644 index 0000000..95075ae --- /dev/null +++ b/app/src/main/res/xml/kbd_nordic.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_number.xml b/app/src/main/res/xml/kbd_number.xml new file mode 100644 index 0000000..c42c0ff --- /dev/null +++ b/app/src/main/res/xml/kbd_number.xml @@ -0,0 +1,27 @@ + + + + + + diff --git a/app/src/main/res/xml/kbd_pcqwerty.xml b/app/src/main/res/xml/kbd_pcqwerty.xml new file mode 100644 index 0000000..7cde1f6 --- /dev/null +++ b/app/src/main/res/xml/kbd_pcqwerty.xml @@ -0,0 +1,31 @@ + + + + + + diff --git a/app/src/main/res/xml/kbd_phone.xml b/app/src/main/res/xml/kbd_phone.xml new file mode 100644 index 0000000..560b49c --- /dev/null +++ b/app/src/main/res/xml/kbd_phone.xml @@ -0,0 +1,27 @@ + + + + + + diff --git a/app/src/main/res/xml/kbd_phone_symbols.xml b/app/src/main/res/xml/kbd_phone_symbols.xml new file mode 100644 index 0000000..d7aa04d --- /dev/null +++ b/app/src/main/res/xml/kbd_phone_symbols.xml @@ -0,0 +1,27 @@ + + + + + + diff --git a/app/src/main/res/xml/kbd_qwerty.xml b/app/src/main/res/xml/kbd_qwerty.xml new file mode 100644 index 0000000..14ebf56 --- /dev/null +++ b/app/src/main/res/xml/kbd_qwerty.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_qwertz.xml b/app/src/main/res/xml/kbd_qwertz.xml new file mode 100644 index 0000000..674c619 --- /dev/null +++ b/app/src/main/res/xml/kbd_qwertz.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_serbian.xml b/app/src/main/res/xml/kbd_serbian.xml new file mode 100644 index 0000000..dcaa57c --- /dev/null +++ b/app/src/main/res/xml/kbd_serbian.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_serbian_qwertz.xml b/app/src/main/res/xml/kbd_serbian_qwertz.xml new file mode 100644 index 0000000..b7348ca --- /dev/null +++ b/app/src/main/res/xml/kbd_serbian_qwertz.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_spanish.xml b/app/src/main/res/xml/kbd_spanish.xml new file mode 100644 index 0000000..5b5c532 --- /dev/null +++ b/app/src/main/res/xml/kbd_spanish.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_swiss.xml b/app/src/main/res/xml/kbd_swiss.xml new file mode 100644 index 0000000..77b3f4e --- /dev/null +++ b/app/src/main/res/xml/kbd_swiss.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_symbols.xml b/app/src/main/res/xml/kbd_symbols.xml new file mode 100644 index 0000000..f644c60 --- /dev/null +++ b/app/src/main/res/xml/kbd_symbols.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_symbols_shift.xml b/app/src/main/res/xml/kbd_symbols_shift.xml new file mode 100644 index 0000000..1e68d4f --- /dev/null +++ b/app/src/main/res/xml/kbd_symbols_shift.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_tamil.xml b/app/src/main/res/xml/kbd_tamil.xml new file mode 100644 index 0000000..4d5a3e5 --- /dev/null +++ b/app/src/main/res/xml/kbd_tamil.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_telugu.xml b/app/src/main/res/xml/kbd_telugu.xml new file mode 100644 index 0000000..e97c496 --- /dev/null +++ b/app/src/main/res/xml/kbd_telugu.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_thai.xml b/app/src/main/res/xml/kbd_thai.xml new file mode 100644 index 0000000..4d9eaca --- /dev/null +++ b/app/src/main/res/xml/kbd_thai.xml @@ -0,0 +1,31 @@ + + + + + + diff --git a/app/src/main/res/xml/kbd_turkish_f.xml b/app/src/main/res/xml/kbd_turkish_f.xml new file mode 100644 index 0000000..a691e92 --- /dev/null +++ b/app/src/main/res/xml/kbd_turkish_f.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_turkish_q.xml b/app/src/main/res/xml/kbd_turkish_q.xml new file mode 100644 index 0000000..d956738 --- /dev/null +++ b/app/src/main/res/xml/kbd_turkish_q.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_urdu.xml b/app/src/main/res/xml/kbd_urdu.xml new file mode 100644 index 0000000..882bbd5 --- /dev/null +++ b/app/src/main/res/xml/kbd_urdu.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/app/src/main/res/xml/kbd_uzbek.xml b/app/src/main/res/xml/kbd_uzbek.xml new file mode 100644 index 0000000..e73c4a7 --- /dev/null +++ b/app/src/main/res/xml/kbd_uzbek.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/kbd_workman.xml b/app/src/main/res/xml/kbd_workman.xml new file mode 100644 index 0000000..38fc1d4 --- /dev/null +++ b/app/src/main/res/xml/kbd_workman.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_armenian_sha.xml b/app/src/main/res/xml/key_armenian_sha.xml new file mode 100644 index 0000000..05779bb --- /dev/null +++ b/app/src/main/res/xml/key_armenian_sha.xml @@ -0,0 +1,27 @@ + + + + + + + diff --git a/app/src/main/res/xml/key_armenian_xeh.xml b/app/src/main/res/xml/key_armenian_xeh.xml new file mode 100644 index 0000000..72861c9 --- /dev/null +++ b/app/src/main/res/xml/key_armenian_xeh.xml @@ -0,0 +1,27 @@ + + + + + + + diff --git a/app/src/main/res/xml/key_comma.xml b/app/src/main/res/xml/key_comma.xml new file mode 100644 index 0000000..a1da517 --- /dev/null +++ b/app/src/main/res/xml/key_comma.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_method.xml b/app/src/main/res/xml/key_method.xml new file mode 100644 index 0000000..b657d9e --- /dev/null +++ b/app/src/main/res/xml/key_method.xml @@ -0,0 +1,7 @@ + + + + diff --git a/app/src/main/res/xml/key_period.xml b/app/src/main/res/xml/key_period.xml new file mode 100644 index 0000000..a7a56f1 --- /dev/null +++ b/app/src/main/res/xml/key_period.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_space_5kw.xml b/app/src/main/res/xml/key_space_5kw.xml new file mode 100644 index 0000000..062545e --- /dev/null +++ b/app/src/main/res/xml/key_space_5kw.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_space_7kw.xml b/app/src/main/res/xml/key_space_7kw.xml new file mode 100644 index 0000000..2c7641c --- /dev/null +++ b/app/src/main/res/xml/key_space_7kw.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_space_symbols.xml b/app/src/main/res/xml/key_space_symbols.xml new file mode 100644 index 0000000..d84783d --- /dev/null +++ b/app/src/main/res/xml/key_space_symbols.xml @@ -0,0 +1,27 @@ + + + + + + diff --git a/app/src/main/res/xml/key_styles_actions.xml b/app/src/main/res/xml/key_styles_actions.xml new file mode 100644 index 0000000..7a7b562 --- /dev/null +++ b/app/src/main/res/xml/key_styles_actions.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_styles_common.xml b/app/src/main/res/xml/key_styles_common.xml new file mode 100644 index 0000000..6173445 --- /dev/null +++ b/app/src/main/res/xml/key_styles_common.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_styles_currency.xml b/app/src/main/res/xml/key_styles_currency.xml new file mode 100644 index 0000000..192e925 --- /dev/null +++ b/app/src/main/res/xml/key_styles_currency.xml @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_styles_currency_dollar.xml b/app/src/main/res/xml/key_styles_currency_dollar.xml new file mode 100644 index 0000000..9a2f1d0 --- /dev/null +++ b/app/src/main/res/xml/key_styles_currency_dollar.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_styles_currency_euro.xml b/app/src/main/res/xml/key_styles_currency_euro.xml new file mode 100644 index 0000000..dfae201 --- /dev/null +++ b/app/src/main/res/xml/key_styles_currency_euro.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_styles_currency_generic.xml b/app/src/main/res/xml/key_styles_currency_generic.xml new file mode 100644 index 0000000..2f00525 --- /dev/null +++ b/app/src/main/res/xml/key_styles_currency_generic.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_styles_enter.xml b/app/src/main/res/xml/key_styles_enter.xml new file mode 100644 index 0000000..1a6b545 --- /dev/null +++ b/app/src/main/res/xml/key_styles_enter.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_styles_less_greater.xml b/app/src/main/res/xml/key_styles_less_greater.xml new file mode 100644 index 0000000..716838b --- /dev/null +++ b/app/src/main/res/xml/key_styles_less_greater.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_styles_number.xml b/app/src/main/res/xml/key_styles_number.xml new file mode 100644 index 0000000..7c69065 --- /dev/null +++ b/app/src/main/res/xml/key_styles_number.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/key_styles_settings.xml b/app/src/main/res/xml/key_styles_settings.xml new file mode 100644 index 0000000..1c2ff2f --- /dev/null +++ b/app/src/main/res/xml/key_styles_settings.xml @@ -0,0 +1,29 @@ + + + + + + diff --git a/app/src/main/res/xml/key_thai_kho_khuat.xml b/app/src/main/res/xml/key_thai_kho_khuat.xml new file mode 100644 index 0000000..d6277a0 --- /dev/null +++ b/app/src/main/res/xml/key_thai_kho_khuat.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_abc.xml b/app/src/main/res/xml/keyboard_layout_set_abc.xml new file mode 100644 index 0000000..e00604f --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_abc.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_arabic.xml b/app/src/main/res/xml/keyboard_layout_set_arabic.xml new file mode 100644 index 0000000..1a257a4 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_arabic.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_armenian_phonetic.xml b/app/src/main/res/xml/keyboard_layout_set_armenian_phonetic.xml new file mode 100644 index 0000000..204b4f2 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_armenian_phonetic.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_azerty.xml b/app/src/main/res/xml/keyboard_layout_set_azerty.xml new file mode 100644 index 0000000..abf4709 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_azerty.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_bengali.xml b/app/src/main/res/xml/keyboard_layout_set_bengali.xml new file mode 100644 index 0000000..e58c469 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_bengali.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_bengali_akkhor.xml b/app/src/main/res/xml/keyboard_layout_set_bengali_akkhor.xml new file mode 100644 index 0000000..d0d5282 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_bengali_akkhor.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_bengali_unijoy.xml b/app/src/main/res/xml/keyboard_layout_set_bengali_unijoy.xml new file mode 100644 index 0000000..445e112 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_bengali_unijoy.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_bulgarian.xml b/app/src/main/res/xml/keyboard_layout_set_bulgarian.xml new file mode 100644 index 0000000..06d26f0 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_bulgarian.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_bulgarian_bds.xml b/app/src/main/res/xml/keyboard_layout_set_bulgarian_bds.xml new file mode 100644 index 0000000..b8da8c0 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_bulgarian_bds.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_colemak.xml b/app/src/main/res/xml/keyboard_layout_set_colemak.xml new file mode 100644 index 0000000..f2a780a --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_colemak.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_dvorak.xml b/app/src/main/res/xml/keyboard_layout_set_dvorak.xml new file mode 100644 index 0000000..b45a553 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_dvorak.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_east_slavic.xml b/app/src/main/res/xml/keyboard_layout_set_east_slavic.xml new file mode 100644 index 0000000..7b1fe55 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_east_slavic.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_farsi.xml b/app/src/main/res/xml/keyboard_layout_set_farsi.xml new file mode 100644 index 0000000..1f68ca4 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_farsi.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_georgian.xml b/app/src/main/res/xml/keyboard_layout_set_georgian.xml new file mode 100644 index 0000000..7d3b39b --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_georgian.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_greek.xml b/app/src/main/res/xml/keyboard_layout_set_greek.xml new file mode 100644 index 0000000..bc8b40b --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_greek.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_hebrew.xml b/app/src/main/res/xml/keyboard_layout_set_hebrew.xml new file mode 100644 index 0000000..3406ae3 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_hebrew.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_hindi.xml b/app/src/main/res/xml/keyboard_layout_set_hindi.xml new file mode 100644 index 0000000..9d7d042 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_hindi.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_hindi_compact.xml b/app/src/main/res/xml/keyboard_layout_set_hindi_compact.xml new file mode 100644 index 0000000..a2f4daa --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_hindi_compact.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_kannada.xml b/app/src/main/res/xml/keyboard_layout_set_kannada.xml new file mode 100644 index 0000000..c438695 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_kannada.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_khmer.xml b/app/src/main/res/xml/keyboard_layout_set_khmer.xml new file mode 100644 index 0000000..c3d6c84 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_khmer.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_lao.xml b/app/src/main/res/xml/keyboard_layout_set_lao.xml new file mode 100644 index 0000000..5d4fccd --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_lao.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_macedonian.xml b/app/src/main/res/xml/keyboard_layout_set_macedonian.xml new file mode 100644 index 0000000..adc0a6e --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_macedonian.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_malayalam.xml b/app/src/main/res/xml/keyboard_layout_set_malayalam.xml new file mode 100644 index 0000000..635c0f0 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_malayalam.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_marathi.xml b/app/src/main/res/xml/keyboard_layout_set_marathi.xml new file mode 100644 index 0000000..8fa29d3 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_marathi.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_mongolian.xml b/app/src/main/res/xml/keyboard_layout_set_mongolian.xml new file mode 100644 index 0000000..318d26e --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_mongolian.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_nepali_romanized.xml b/app/src/main/res/xml/keyboard_layout_set_nepali_romanized.xml new file mode 100644 index 0000000..6003c6d --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_nepali_romanized.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_nepali_traditional.xml b/app/src/main/res/xml/keyboard_layout_set_nepali_traditional.xml new file mode 100644 index 0000000..8b50b32 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_nepali_traditional.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_nordic.xml b/app/src/main/res/xml/keyboard_layout_set_nordic.xml new file mode 100644 index 0000000..cc00fac --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_nordic.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_pcqwerty.xml b/app/src/main/res/xml/keyboard_layout_set_pcqwerty.xml new file mode 100644 index 0000000..d73e0df --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_pcqwerty.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_qwerty.xml b/app/src/main/res/xml/keyboard_layout_set_qwerty.xml new file mode 100644 index 0000000..83cc7f6 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_qwerty.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_qwertz.xml b/app/src/main/res/xml/keyboard_layout_set_qwertz.xml new file mode 100644 index 0000000..7df5d1f --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_qwertz.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_serbian.xml b/app/src/main/res/xml/keyboard_layout_set_serbian.xml new file mode 100644 index 0000000..1906fbb --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_serbian.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_serbian_qwertz.xml b/app/src/main/res/xml/keyboard_layout_set_serbian_qwertz.xml new file mode 100644 index 0000000..2fc052b --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_serbian_qwertz.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/keyboard_layout_set_spanish.xml b/app/src/main/res/xml/keyboard_layout_set_spanish.xml new file mode 100644 index 0000000..5181ccb --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_spanish.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_swiss.xml b/app/src/main/res/xml/keyboard_layout_set_swiss.xml new file mode 100644 index 0000000..046fec5 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_swiss.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_tamil.xml b/app/src/main/res/xml/keyboard_layout_set_tamil.xml new file mode 100644 index 0000000..66e29f1 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_tamil.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_telugu.xml b/app/src/main/res/xml/keyboard_layout_set_telugu.xml new file mode 100644 index 0000000..1c5820c --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_telugu.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_thai.xml b/app/src/main/res/xml/keyboard_layout_set_thai.xml new file mode 100644 index 0000000..6f58ce7 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_thai.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_turkish_f.xml b/app/src/main/res/xml/keyboard_layout_set_turkish_f.xml new file mode 100644 index 0000000..63dbdaa --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_turkish_f.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_turkish_q.xml b/app/src/main/res/xml/keyboard_layout_set_turkish_q.xml new file mode 100644 index 0000000..db0b9e6 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_turkish_q.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_urdu.xml b/app/src/main/res/xml/keyboard_layout_set_urdu.xml new file mode 100644 index 0000000..ebf9ecc --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_urdu.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_layout_set_uzbek.xml b/app/src/main/res/xml/keyboard_layout_set_uzbek.xml new file mode 100644 index 0000000..6d60061 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_uzbek.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/keyboard_layout_set_workman.xml b/app/src/main/res/xml/keyboard_layout_set_workman.xml new file mode 100644 index 0000000..2c8c000 --- /dev/null +++ b/app/src/main/res/xml/keyboard_layout_set_workman.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/keyboard_mode_change.xml b/app/src/main/res/xml/keyboard_mode_change.xml new file mode 100644 index 0000000..14749e2 --- /dev/null +++ b/app/src/main/res/xml/keyboard_mode_change.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/keyboard_more_symbol.xml b/app/src/main/res/xml/keyboard_more_symbol.xml new file mode 100644 index 0000000..899f29c --- /dev/null +++ b/app/src/main/res/xml/keyboard_more_symbol.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/keys_arabic3_left.xml b/app/src/main/res/xml/keys_arabic3_left.xml new file mode 100644 index 0000000..309a15f --- /dev/null +++ b/app/src/main/res/xml/keys_arabic3_left.xml @@ -0,0 +1,27 @@ + + + + + + + diff --git a/app/src/main/res/xml/keys_curly_brackets.xml b/app/src/main/res/xml/keys_curly_brackets.xml new file mode 100644 index 0000000..20e4604 --- /dev/null +++ b/app/src/main/res/xml/keys_curly_brackets.xml @@ -0,0 +1,28 @@ + + + + + + + diff --git a/app/src/main/res/xml/keys_dvorak_123.xml b/app/src/main/res/xml/keys_dvorak_123.xml new file mode 100644 index 0000000..5dd1ff0 --- /dev/null +++ b/app/src/main/res/xml/keys_dvorak_123.xml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keys_exclamation_question.xml b/app/src/main/res/xml/keys_exclamation_question.xml new file mode 100644 index 0000000..83a64d0 --- /dev/null +++ b/app/src/main/res/xml/keys_exclamation_question.xml @@ -0,0 +1,32 @@ + + + + + + + diff --git a/app/src/main/res/xml/keys_farsi3_right.xml b/app/src/main/res/xml/keys_farsi3_right.xml new file mode 100644 index 0000000..72607de --- /dev/null +++ b/app/src/main/res/xml/keys_farsi3_right.xml @@ -0,0 +1,27 @@ + + + + + + + diff --git a/app/src/main/res/xml/keys_parentheses.xml b/app/src/main/res/xml/keys_parentheses.xml new file mode 100644 index 0000000..98919d4 --- /dev/null +++ b/app/src/main/res/xml/keys_parentheses.xml @@ -0,0 +1,30 @@ + + + + + + + diff --git a/app/src/main/res/xml/keys_pcqwerty2_right3.xml b/app/src/main/res/xml/keys_pcqwerty2_right3.xml new file mode 100644 index 0000000..684409e --- /dev/null +++ b/app/src/main/res/xml/keys_pcqwerty2_right3.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keys_pcqwerty3_right2.xml b/app/src/main/res/xml/keys_pcqwerty3_right2.xml new file mode 100644 index 0000000..7a30f46 --- /dev/null +++ b/app/src/main/res/xml/keys_pcqwerty3_right2.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keys_pcqwerty4_right3.xml b/app/src/main/res/xml/keys_pcqwerty4_right3.xml new file mode 100644 index 0000000..770a951 --- /dev/null +++ b/app/src/main/res/xml/keys_pcqwerty4_right3.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keys_square_brackets.xml b/app/src/main/res/xml/keys_square_brackets.xml new file mode 100644 index 0000000..af78ffb --- /dev/null +++ b/app/src/main/res/xml/keys_square_brackets.xml @@ -0,0 +1,28 @@ + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_sign_anusvara.xml b/app/src/main/res/xml/keystyle_devanagari_sign_anusvara.xml new file mode 100644 index 0000000..439fda0 --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_sign_anusvara.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_sign_candrabindu.xml b/app/src/main/res/xml/keystyle_devanagari_sign_candrabindu.xml new file mode 100644 index 0000000..1c114b7 --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_sign_candrabindu.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_sign_nukta.xml b/app/src/main/res/xml/keystyle_devanagari_sign_nukta.xml new file mode 100644 index 0000000..b7eccfc --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_sign_nukta.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_sign_virama.xml b/app/src/main/res/xml/keystyle_devanagari_sign_virama.xml new file mode 100644 index 0000000..996a061 --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_sign_virama.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_sign_visarga.xml b/app/src/main/res/xml/keystyle_devanagari_sign_visarga.xml new file mode 100644 index 0000000..71befd9 --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_sign_visarga.xml @@ -0,0 +1,30 @@ + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_vowel_sign_aa.xml b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_aa.xml new file mode 100644 index 0000000..076db67 --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_aa.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_vowel_sign_ai.xml b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_ai.xml new file mode 100644 index 0000000..91d1de2 --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_ai.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_vowel_sign_au.xml b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_au.xml new file mode 100644 index 0000000..50cfd65 --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_au.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_vowel_sign_candra_e.xml b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_candra_e.xml new file mode 100644 index 0000000..805446a --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_candra_e.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_vowel_sign_candra_o.xml b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_candra_o.xml new file mode 100644 index 0000000..5e446c0 --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_candra_o.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_vowel_sign_e.xml b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_e.xml new file mode 100644 index 0000000..bed052e --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_e.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_vowel_sign_i.xml b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_i.xml new file mode 100644 index 0000000..60d2711 --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_i.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_vowel_sign_ii.xml b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_ii.xml new file mode 100644 index 0000000..3e3b56c --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_ii.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_vowel_sign_o.xml b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_o.xml new file mode 100644 index 0000000..608a098 --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_o.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_vowel_sign_u.xml b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_u.xml new file mode 100644 index 0000000..acb6071 --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_u.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_vowel_sign_uu.xml b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_uu.xml new file mode 100644 index 0000000..1adc3bb --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_uu.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/keystyle_devanagari_vowel_sign_vocalic_r.xml b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_vocalic_r.xml new file mode 100644 index 0000000..268c7d8 --- /dev/null +++ b/app/src/main/res/xml/keystyle_devanagari_vowel_sign_vocalic_r.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/method.xml b/app/src/main/res/xml/method.xml new file mode 100644 index 0000000..805a9e7 --- /dev/null +++ b/app/src/main/res/xml/method.xml @@ -0,0 +1,29 @@ + + + + + + + + + diff --git a/app/src/main/res/xml/my_custom_keyboard_layout.xml b/app/src/main/res/xml/my_custom_keyboard_layout.xml new file mode 100644 index 0000000..2d5e9cd --- /dev/null +++ b/app/src/main/res/xml/my_custom_keyboard_layout.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/prefs.xml b/app/src/main/res/xml/prefs.xml new file mode 100644 index 0000000..d68bdc7 --- /dev/null +++ b/app/src/main/res/xml/prefs.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/prefs_screen_appearance.xml b/app/src/main/res/xml/prefs_screen_appearance.xml new file mode 100644 index 0000000..c92f32b --- /dev/null +++ b/app/src/main/res/xml/prefs_screen_appearance.xml @@ -0,0 +1,39 @@ + + + + + + + + + diff --git a/app/src/main/res/xml/prefs_screen_key_press.xml b/app/src/main/res/xml/prefs_screen_key_press.xml new file mode 100644 index 0000000..60a0917 --- /dev/null +++ b/app/src/main/res/xml/prefs_screen_key_press.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/prefs_screen_preferences.xml b/app/src/main/res/xml/prefs_screen_preferences.xml new file mode 100644 index 0000000..d5be0cb --- /dev/null +++ b/app/src/main/res/xml/prefs_screen_preferences.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/xml/prefs_screen_theme.xml b/app/src/main/res/xml/prefs_screen_theme.xml new file mode 100644 index 0000000..ced378b --- /dev/null +++ b/app/src/main/res/xml/prefs_screen_theme.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/app/src/main/res/xml/row_pcqwerty5.xml b/app/src/main/res/xml/row_pcqwerty5.xml new file mode 100644 index 0000000..dcd8a40 --- /dev/null +++ b/app/src/main/res/xml/row_pcqwerty5.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/row_qwerty0.xml b/app/src/main/res/xml/row_qwerty0.xml new file mode 100644 index 0000000..4b46506 --- /dev/null +++ b/app/src/main/res/xml/row_qwerty0.xml @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/app/src/main/res/xml/row_qwerty4.xml b/app/src/main/res/xml/row_qwerty4.xml new file mode 100644 index 0000000..68b7ce4 --- /dev/null +++ b/app/src/main/res/xml/row_qwerty4.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/xml/row_symbols4.xml b/app/src/main/res/xml/row_symbols4.xml new file mode 100644 index 0000000..5d63403 --- /dev/null +++ b/app/src/main/res/xml/row_symbols4.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/row_symbols_shift4.xml b/app/src/main/res/xml/row_symbols_shift4.xml new file mode 100644 index 0000000..c0e4194 --- /dev/null +++ b/app/src/main/res/xml/row_symbols_shift4.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_abc1.xml b/app/src/main/res/xml/rowkeys_abc1.xml new file mode 100644 index 0000000..537a20c --- /dev/null +++ b/app/src/main/res/xml/rowkeys_abc1.xml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_abc2.xml b/app/src/main/res/xml/rowkeys_abc2.xml new file mode 100644 index 0000000..177b940 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_abc2.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_abc3.xml b/app/src/main/res/xml/rowkeys_abc3.xml new file mode 100644 index 0000000..eb7c408 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_abc3.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_arabic1.xml b/app/src/main/res/xml/rowkeys_arabic1.xml new file mode 100644 index 0000000..7d8046d --- /dev/null +++ b/app/src/main/res/xml/rowkeys_arabic1.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_arabic2.xml b/app/src/main/res/xml/rowkeys_arabic2.xml new file mode 100644 index 0000000..1f0b42f --- /dev/null +++ b/app/src/main/res/xml/rowkeys_arabic2.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_arabic3.xml b/app/src/main/res/xml/rowkeys_arabic3.xml new file mode 100644 index 0000000..c6abfb8 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_arabic3.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_armenian_phonetic1.xml b/app/src/main/res/xml/rowkeys_armenian_phonetic1.xml new file mode 100644 index 0000000..6289d3c --- /dev/null +++ b/app/src/main/res/xml/rowkeys_armenian_phonetic1.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_armenian_phonetic2.xml b/app/src/main/res/xml/rowkeys_armenian_phonetic2.xml new file mode 100644 index 0000000..174468e --- /dev/null +++ b/app/src/main/res/xml/rowkeys_armenian_phonetic2.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_armenian_phonetic3.xml b/app/src/main/res/xml/rowkeys_armenian_phonetic3.xml new file mode 100644 index 0000000..fe911b5 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_armenian_phonetic3.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_armenian_phonetic4.xml b/app/src/main/res/xml/rowkeys_armenian_phonetic4.xml new file mode 100644 index 0000000..4436dc4 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_armenian_phonetic4.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_azerty1.xml b/app/src/main/res/xml/rowkeys_azerty1.xml new file mode 100644 index 0000000..601ad38 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_azerty1.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_azerty2.xml b/app/src/main/res/xml/rowkeys_azerty2.xml new file mode 100644 index 0000000..d844150 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_azerty2.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_azerty3.xml b/app/src/main/res/xml/rowkeys_azerty3.xml new file mode 100644 index 0000000..bff2e63 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_azerty3.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bengali1.xml b/app/src/main/res/xml/rowkeys_bengali1.xml new file mode 100644 index 0000000..a153026 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bengali1.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bengali2.xml b/app/src/main/res/xml/rowkeys_bengali2.xml new file mode 100644 index 0000000..8908201 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bengali2.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bengali3.xml b/app/src/main/res/xml/rowkeys_bengali3.xml new file mode 100644 index 0000000..12fad6d --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bengali3.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bengali_akkhor1.xml b/app/src/main/res/xml/rowkeys_bengali_akkhor1.xml new file mode 100644 index 0000000..c2d4db2 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bengali_akkhor1.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bengali_akkhor2.xml b/app/src/main/res/xml/rowkeys_bengali_akkhor2.xml new file mode 100644 index 0000000..7c59ed2 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bengali_akkhor2.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bengali_akkhor3.xml b/app/src/main/res/xml/rowkeys_bengali_akkhor3.xml new file mode 100644 index 0000000..14d3d06 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bengali_akkhor3.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bengali_unijoy1.xml b/app/src/main/res/xml/rowkeys_bengali_unijoy1.xml new file mode 100644 index 0000000..a6498cf --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bengali_unijoy1.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bengali_unijoy2.xml b/app/src/main/res/xml/rowkeys_bengali_unijoy2.xml new file mode 100644 index 0000000..7f544e9 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bengali_unijoy2.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bengali_unijoy3.xml b/app/src/main/res/xml/rowkeys_bengali_unijoy3.xml new file mode 100644 index 0000000..a5e198d --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bengali_unijoy3.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bulgarian1.xml b/app/src/main/res/xml/rowkeys_bulgarian1.xml new file mode 100644 index 0000000..430e1c3 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bulgarian1.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + !-- U+044F: "я" CYRILLIC SMALL LETTER YA --> + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bulgarian2.xml b/app/src/main/res/xml/rowkeys_bulgarian2.xml new file mode 100644 index 0000000..f48b4cd --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bulgarian2.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bulgarian3.xml b/app/src/main/res/xml/rowkeys_bulgarian3.xml new file mode 100644 index 0000000..c14aabd --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bulgarian3.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bulgarian_bds1.xml b/app/src/main/res/xml/rowkeys_bulgarian_bds1.xml new file mode 100644 index 0000000..7161f42 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bulgarian_bds1.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bulgarian_bds2.xml b/app/src/main/res/xml/rowkeys_bulgarian_bds2.xml new file mode 100644 index 0000000..e61ee59 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bulgarian_bds2.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_bulgarian_bds3.xml b/app/src/main/res/xml/rowkeys_bulgarian_bds3.xml new file mode 100644 index 0000000..82f0bfe --- /dev/null +++ b/app/src/main/res/xml/rowkeys_bulgarian_bds3.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_colemak1.xml b/app/src/main/res/xml/rowkeys_colemak1.xml new file mode 100644 index 0000000..b09e96e --- /dev/null +++ b/app/src/main/res/xml/rowkeys_colemak1.xml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_colemak2.xml b/app/src/main/res/xml/rowkeys_colemak2.xml new file mode 100644 index 0000000..dc4f993 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_colemak2.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_colemak3.xml b/app/src/main/res/xml/rowkeys_colemak3.xml new file mode 100644 index 0000000..17191b6 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_colemak3.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_dvorak1.xml b/app/src/main/res/xml/rowkeys_dvorak1.xml new file mode 100644 index 0000000..cbad3bb --- /dev/null +++ b/app/src/main/res/xml/rowkeys_dvorak1.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_dvorak2.xml b/app/src/main/res/xml/rowkeys_dvorak2.xml new file mode 100644 index 0000000..91f90d6 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_dvorak2.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_dvorak3.xml b/app/src/main/res/xml/rowkeys_dvorak3.xml new file mode 100644 index 0000000..83813e6 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_dvorak3.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_east_slavic1.xml b/app/src/main/res/xml/rowkeys_east_slavic1.xml new file mode 100644 index 0000000..11509f9 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_east_slavic1.xml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_east_slavic2.xml b/app/src/main/res/xml/rowkeys_east_slavic2.xml new file mode 100644 index 0000000..f2f45f8 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_east_slavic2.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_east_slavic3.xml b/app/src/main/res/xml/rowkeys_east_slavic3.xml new file mode 100644 index 0000000..4868a0e --- /dev/null +++ b/app/src/main/res/xml/rowkeys_east_slavic3.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_farsi1.xml b/app/src/main/res/xml/rowkeys_farsi1.xml new file mode 100644 index 0000000..363c28e --- /dev/null +++ b/app/src/main/res/xml/rowkeys_farsi1.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_farsi2.xml b/app/src/main/res/xml/rowkeys_farsi2.xml new file mode 100644 index 0000000..bec654d --- /dev/null +++ b/app/src/main/res/xml/rowkeys_farsi2.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_farsi3.xml b/app/src/main/res/xml/rowkeys_farsi3.xml new file mode 100644 index 0000000..e82a1d5 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_farsi3.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_georgian1.xml b/app/src/main/res/xml/rowkeys_georgian1.xml new file mode 100644 index 0000000..5452bfc --- /dev/null +++ b/app/src/main/res/xml/rowkeys_georgian1.xml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_georgian2.xml b/app/src/main/res/xml/rowkeys_georgian2.xml new file mode 100644 index 0000000..5667781 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_georgian2.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_georgian3.xml b/app/src/main/res/xml/rowkeys_georgian3.xml new file mode 100644 index 0000000..decbdfc --- /dev/null +++ b/app/src/main/res/xml/rowkeys_georgian3.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_greek1.xml b/app/src/main/res/xml/rowkeys_greek1.xml new file mode 100644 index 0000000..cb20dc8 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_greek1.xml @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_greek2.xml b/app/src/main/res/xml/rowkeys_greek2.xml new file mode 100644 index 0000000..87e1460 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_greek2.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_greek3.xml b/app/src/main/res/xml/rowkeys_greek3.xml new file mode 100644 index 0000000..6bec17e --- /dev/null +++ b/app/src/main/res/xml/rowkeys_greek3.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_hebrew1.xml b/app/src/main/res/xml/rowkeys_hebrew1.xml new file mode 100644 index 0000000..b13f67a --- /dev/null +++ b/app/src/main/res/xml/rowkeys_hebrew1.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_hebrew2.xml b/app/src/main/res/xml/rowkeys_hebrew2.xml new file mode 100644 index 0000000..4c692f1 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_hebrew2.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_hebrew3.xml b/app/src/main/res/xml/rowkeys_hebrew3.xml new file mode 100644 index 0000000..6db9bac --- /dev/null +++ b/app/src/main/res/xml/rowkeys_hebrew3.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_hindi1.xml b/app/src/main/res/xml/rowkeys_hindi1.xml new file mode 100644 index 0000000..4887d81 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_hindi1.xml @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_hindi2.xml b/app/src/main/res/xml/rowkeys_hindi2.xml new file mode 100644 index 0000000..49794bc --- /dev/null +++ b/app/src/main/res/xml/rowkeys_hindi2.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_hindi3.xml b/app/src/main/res/xml/rowkeys_hindi3.xml new file mode 100644 index 0000000..33ec09a --- /dev/null +++ b/app/src/main/res/xml/rowkeys_hindi3.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_hindi_compact1.xml b/app/src/main/res/xml/rowkeys_hindi_compact1.xml new file mode 100644 index 0000000..89a493e --- /dev/null +++ b/app/src/main/res/xml/rowkeys_hindi_compact1.xml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_hindi_compact2.xml b/app/src/main/res/xml/rowkeys_hindi_compact2.xml new file mode 100644 index 0000000..9d7d795 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_hindi_compact2.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_hindi_compact3.xml b/app/src/main/res/xml/rowkeys_hindi_compact3.xml new file mode 100644 index 0000000..41b4808 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_hindi_compact3.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_kannada1.xml b/app/src/main/res/xml/rowkeys_kannada1.xml new file mode 100644 index 0000000..f86b176 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_kannada1.xml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_kannada2.xml b/app/src/main/res/xml/rowkeys_kannada2.xml new file mode 100644 index 0000000..89d2cfc --- /dev/null +++ b/app/src/main/res/xml/rowkeys_kannada2.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_kannada3.xml b/app/src/main/res/xml/rowkeys_kannada3.xml new file mode 100644 index 0000000..8cdaa25 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_kannada3.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_khmer1.xml b/app/src/main/res/xml/rowkeys_khmer1.xml new file mode 100644 index 0000000..559c2a5 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_khmer1.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_khmer2.xml b/app/src/main/res/xml/rowkeys_khmer2.xml new file mode 100644 index 0000000..4efa243 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_khmer2.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_khmer3.xml b/app/src/main/res/xml/rowkeys_khmer3.xml new file mode 100644 index 0000000..5ac056c --- /dev/null +++ b/app/src/main/res/xml/rowkeys_khmer3.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_khmer4.xml b/app/src/main/res/xml/rowkeys_khmer4.xml new file mode 100644 index 0000000..52d3318 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_khmer4.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_lao1.xml b/app/src/main/res/xml/rowkeys_lao1.xml new file mode 100644 index 0000000..5f1840c --- /dev/null +++ b/app/src/main/res/xml/rowkeys_lao1.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_lao2.xml b/app/src/main/res/xml/rowkeys_lao2.xml new file mode 100644 index 0000000..8065380 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_lao2.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_lao3.xml b/app/src/main/res/xml/rowkeys_lao3.xml new file mode 100644 index 0000000..911f8a2 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_lao3.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_lao4.xml b/app/src/main/res/xml/rowkeys_lao4.xml new file mode 100644 index 0000000..858cb42 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_lao4.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_malayalam1.xml b/app/src/main/res/xml/rowkeys_malayalam1.xml new file mode 100644 index 0000000..478289b --- /dev/null +++ b/app/src/main/res/xml/rowkeys_malayalam1.xml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_malayalam2.xml b/app/src/main/res/xml/rowkeys_malayalam2.xml new file mode 100644 index 0000000..0c9dd39 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_malayalam2.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_malayalam3.xml b/app/src/main/res/xml/rowkeys_malayalam3.xml new file mode 100644 index 0000000..5485f14 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_malayalam3.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_marathi1.xml b/app/src/main/res/xml/rowkeys_marathi1.xml new file mode 100644 index 0000000..6b9c92b --- /dev/null +++ b/app/src/main/res/xml/rowkeys_marathi1.xml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_marathi2.xml b/app/src/main/res/xml/rowkeys_marathi2.xml new file mode 100644 index 0000000..7517c49 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_marathi2.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_marathi3.xml b/app/src/main/res/xml/rowkeys_marathi3.xml new file mode 100644 index 0000000..9529ba1 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_marathi3.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_mongolian1.xml b/app/src/main/res/xml/rowkeys_mongolian1.xml new file mode 100644 index 0000000..e733bb5 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_mongolian1.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_mongolian2.xml b/app/src/main/res/xml/rowkeys_mongolian2.xml new file mode 100644 index 0000000..3426771 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_mongolian2.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_mongolian3.xml b/app/src/main/res/xml/rowkeys_mongolian3.xml new file mode 100644 index 0000000..5300b2c --- /dev/null +++ b/app/src/main/res/xml/rowkeys_mongolian3.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_nepali_romanized1.xml b/app/src/main/res/xml/rowkeys_nepali_romanized1.xml new file mode 100644 index 0000000..b4fc560 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_nepali_romanized1.xml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_nepali_romanized2.xml b/app/src/main/res/xml/rowkeys_nepali_romanized2.xml new file mode 100644 index 0000000..86fa6fe --- /dev/null +++ b/app/src/main/res/xml/rowkeys_nepali_romanized2.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_nepali_romanized3.xml b/app/src/main/res/xml/rowkeys_nepali_romanized3.xml new file mode 100644 index 0000000..a9ea15d --- /dev/null +++ b/app/src/main/res/xml/rowkeys_nepali_romanized3.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_nepali_traditional1.xml b/app/src/main/res/xml/rowkeys_nepali_traditional1.xml new file mode 100644 index 0000000..5d6ccd9 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_nepali_traditional1.xml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_nepali_traditional2.xml b/app/src/main/res/xml/rowkeys_nepali_traditional2.xml new file mode 100644 index 0000000..902923c --- /dev/null +++ b/app/src/main/res/xml/rowkeys_nepali_traditional2.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_nepali_traditional3.xml b/app/src/main/res/xml/rowkeys_nepali_traditional3.xml new file mode 100644 index 0000000..242948f --- /dev/null +++ b/app/src/main/res/xml/rowkeys_nepali_traditional3.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_nordic1.xml b/app/src/main/res/xml/rowkeys_nordic1.xml new file mode 100644 index 0000000..89f4358 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_nordic1.xml @@ -0,0 +1,28 @@ + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_nordic2.xml b/app/src/main/res/xml/rowkeys_nordic2.xml new file mode 100644 index 0000000..5cd8152 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_nordic2.xml @@ -0,0 +1,32 @@ + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_pcqwerty1.xml b/app/src/main/res/xml/rowkeys_pcqwerty1.xml new file mode 100644 index 0000000..880d8f6 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_pcqwerty1.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_pcqwerty1_shift.xml b/app/src/main/res/xml/rowkeys_pcqwerty1_shift.xml new file mode 100644 index 0000000..c925a86 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_pcqwerty1_shift.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_pcqwerty2.xml b/app/src/main/res/xml/rowkeys_pcqwerty2.xml new file mode 100644 index 0000000..781aec8 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_pcqwerty2.xml @@ -0,0 +1,31 @@ + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_pcqwerty3.xml b/app/src/main/res/xml/rowkeys_pcqwerty3.xml new file mode 100644 index 0000000..f888fe2 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_pcqwerty3.xml @@ -0,0 +1,30 @@ + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_pcqwerty4.xml b/app/src/main/res/xml/rowkeys_pcqwerty4.xml new file mode 100644 index 0000000..7e46828 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_pcqwerty4.xml @@ -0,0 +1,30 @@ + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_qwerty0.xml b/app/src/main/res/xml/rowkeys_qwerty0.xml new file mode 100644 index 0000000..c657d71 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_qwerty0.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_qwerty1.xml b/app/src/main/res/xml/rowkeys_qwerty1.xml new file mode 100644 index 0000000..2e03e6e --- /dev/null +++ b/app/src/main/res/xml/rowkeys_qwerty1.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_qwerty2.xml b/app/src/main/res/xml/rowkeys_qwerty2.xml new file mode 100644 index 0000000..71d8fbd --- /dev/null +++ b/app/src/main/res/xml/rowkeys_qwerty2.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_qwerty3.xml b/app/src/main/res/xml/rowkeys_qwerty3.xml new file mode 100644 index 0000000..a57b5ab --- /dev/null +++ b/app/src/main/res/xml/rowkeys_qwerty3.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_qwertz1.xml b/app/src/main/res/xml/rowkeys_qwertz1.xml new file mode 100644 index 0000000..0eb41c4 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_qwertz1.xml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_qwertz3.xml b/app/src/main/res/xml/rowkeys_qwertz3.xml new file mode 100644 index 0000000..f6f8995 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_qwertz3.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_serbian_qwertz1.xml b/app/src/main/res/xml/rowkeys_serbian_qwertz1.xml new file mode 100644 index 0000000..4cc58ca --- /dev/null +++ b/app/src/main/res/xml/rowkeys_serbian_qwertz1.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/rowkeys_serbian_qwertz2.xml b/app/src/main/res/xml/rowkeys_serbian_qwertz2.xml new file mode 100644 index 0000000..b008f80 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_serbian_qwertz2.xml @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_serbian_qwertz3.xml b/app/src/main/res/xml/rowkeys_serbian_qwertz3.xml new file mode 100644 index 0000000..8bf69d9 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_serbian_qwertz3.xml @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_south_slavic1.xml b/app/src/main/res/xml/rowkeys_south_slavic1.xml new file mode 100644 index 0000000..37bacbe --- /dev/null +++ b/app/src/main/res/xml/rowkeys_south_slavic1.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_south_slavic2.xml b/app/src/main/res/xml/rowkeys_south_slavic2.xml new file mode 100644 index 0000000..4a5e67d --- /dev/null +++ b/app/src/main/res/xml/rowkeys_south_slavic2.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_south_slavic3.xml b/app/src/main/res/xml/rowkeys_south_slavic3.xml new file mode 100644 index 0000000..ca32eb6 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_south_slavic3.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_spanish2.xml b/app/src/main/res/xml/rowkeys_spanish2.xml new file mode 100644 index 0000000..8866d32 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_spanish2.xml @@ -0,0 +1,29 @@ + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_swiss1.xml b/app/src/main/res/xml/rowkeys_swiss1.xml new file mode 100644 index 0000000..9c8e3bb --- /dev/null +++ b/app/src/main/res/xml/rowkeys_swiss1.xml @@ -0,0 +1,29 @@ + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_swiss2.xml b/app/src/main/res/xml/rowkeys_swiss2.xml new file mode 100644 index 0000000..b4f2c8e --- /dev/null +++ b/app/src/main/res/xml/rowkeys_swiss2.xml @@ -0,0 +1,32 @@ + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_symbols1.xml b/app/src/main/res/xml/rowkeys_symbols1.xml new file mode 100644 index 0000000..93937cf --- /dev/null +++ b/app/src/main/res/xml/rowkeys_symbols1.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_symbols2.xml b/app/src/main/res/xml/rowkeys_symbols2.xml new file mode 100644 index 0000000..40d4817 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_symbols2.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_symbols3.xml b/app/src/main/res/xml/rowkeys_symbols3.xml new file mode 100644 index 0000000..7b52b1f --- /dev/null +++ b/app/src/main/res/xml/rowkeys_symbols3.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_symbols_shift1.xml b/app/src/main/res/xml/rowkeys_symbols_shift1.xml new file mode 100644 index 0000000..9399209 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_symbols_shift1.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_symbols_shift2.xml b/app/src/main/res/xml/rowkeys_symbols_shift2.xml new file mode 100644 index 0000000..990a950 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_symbols_shift2.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_symbols_shift3.xml b/app/src/main/res/xml/rowkeys_symbols_shift3.xml new file mode 100644 index 0000000..4d1818e --- /dev/null +++ b/app/src/main/res/xml/rowkeys_symbols_shift3.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_tamil1.xml b/app/src/main/res/xml/rowkeys_tamil1.xml new file mode 100644 index 0000000..4116d6f --- /dev/null +++ b/app/src/main/res/xml/rowkeys_tamil1.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_tamil2.xml b/app/src/main/res/xml/rowkeys_tamil2.xml new file mode 100644 index 0000000..ccf98b3 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_tamil2.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_tamil3.xml b/app/src/main/res/xml/rowkeys_tamil3.xml new file mode 100644 index 0000000..281314d --- /dev/null +++ b/app/src/main/res/xml/rowkeys_tamil3.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_telugu1.xml b/app/src/main/res/xml/rowkeys_telugu1.xml new file mode 100644 index 0000000..abe2220 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_telugu1.xml @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_telugu2.xml b/app/src/main/res/xml/rowkeys_telugu2.xml new file mode 100644 index 0000000..c3c4a6b --- /dev/null +++ b/app/src/main/res/xml/rowkeys_telugu2.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_telugu3.xml b/app/src/main/res/xml/rowkeys_telugu3.xml new file mode 100644 index 0000000..e42eaa5 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_telugu3.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_thai1.xml b/app/src/main/res/xml/rowkeys_thai1.xml new file mode 100644 index 0000000..4da39bc --- /dev/null +++ b/app/src/main/res/xml/rowkeys_thai1.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_thai2.xml b/app/src/main/res/xml/rowkeys_thai2.xml new file mode 100644 index 0000000..c0b63ff --- /dev/null +++ b/app/src/main/res/xml/rowkeys_thai2.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_thai3.xml b/app/src/main/res/xml/rowkeys_thai3.xml new file mode 100644 index 0000000..d3ea527 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_thai3.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_thai4.xml b/app/src/main/res/xml/rowkeys_thai4.xml new file mode 100644 index 0000000..2c7194a --- /dev/null +++ b/app/src/main/res/xml/rowkeys_thai4.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_turkish_f1.xml b/app/src/main/res/xml/rowkeys_turkish_f1.xml new file mode 100644 index 0000000..9522897 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_turkish_f1.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_turkish_f2.xml b/app/src/main/res/xml/rowkeys_turkish_f2.xml new file mode 100644 index 0000000..be61178 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_turkish_f2.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_turkish_f3.xml b/app/src/main/res/xml/rowkeys_turkish_f3.xml new file mode 100644 index 0000000..943489e --- /dev/null +++ b/app/src/main/res/xml/rowkeys_turkish_f3.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_turkish_q1.xml b/app/src/main/res/xml/rowkeys_turkish_q1.xml new file mode 100644 index 0000000..879ff27 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_turkish_q1.xml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_turkish_q2.xml b/app/src/main/res/xml/rowkeys_turkish_q2.xml new file mode 100644 index 0000000..6f53aa9 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_turkish_q2.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_turkish_q3.xml b/app/src/main/res/xml/rowkeys_turkish_q3.xml new file mode 100644 index 0000000..2901bcd --- /dev/null +++ b/app/src/main/res/xml/rowkeys_turkish_q3.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_urdu1.xml b/app/src/main/res/xml/rowkeys_urdu1.xml new file mode 100644 index 0000000..0b6f642 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_urdu1.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_urdu2.xml b/app/src/main/res/xml/rowkeys_urdu2.xml new file mode 100644 index 0000000..8f0a3b7 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_urdu2.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_urdu3.xml b/app/src/main/res/xml/rowkeys_urdu3.xml new file mode 100644 index 0000000..33c1f59 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_urdu3.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_uzbek1.xml b/app/src/main/res/xml/rowkeys_uzbek1.xml new file mode 100644 index 0000000..1a12d33 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_uzbek1.xml @@ -0,0 +1,27 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/rowkeys_uzbek2.xml b/app/src/main/res/xml/rowkeys_uzbek2.xml new file mode 100644 index 0000000..171482b --- /dev/null +++ b/app/src/main/res/xml/rowkeys_uzbek2.xml @@ -0,0 +1,29 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/rowkeys_workman1.xml b/app/src/main/res/xml/rowkeys_workman1.xml new file mode 100644 index 0000000..6297c06 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_workman1.xml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_workman2.xml b/app/src/main/res/xml/rowkeys_workman2.xml new file mode 100644 index 0000000..78ea86e --- /dev/null +++ b/app/src/main/res/xml/rowkeys_workman2.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rowkeys_workman3.xml b/app/src/main/res/xml/rowkeys_workman3.xml new file mode 100644 index 0000000..d4a49c6 --- /dev/null +++ b/app/src/main/res/xml/rowkeys_workman3.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_abc.xml b/app/src/main/res/xml/rows_abc.xml new file mode 100644 index 0000000..495c32f --- /dev/null +++ b/app/src/main/res/xml/rows_abc.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_arabic.xml b/app/src/main/res/xml/rows_arabic.xml new file mode 100644 index 0000000..f45e3e0 --- /dev/null +++ b/app/src/main/res/xml/rows_arabic.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_armenian_phonetic.xml b/app/src/main/res/xml/rows_armenian_phonetic.xml new file mode 100644 index 0000000..d997f12 --- /dev/null +++ b/app/src/main/res/xml/rows_armenian_phonetic.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_azerty.xml b/app/src/main/res/xml/rows_azerty.xml new file mode 100644 index 0000000..ba10641 --- /dev/null +++ b/app/src/main/res/xml/rows_azerty.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_bengali.xml b/app/src/main/res/xml/rows_bengali.xml new file mode 100644 index 0000000..e4a4b92 --- /dev/null +++ b/app/src/main/res/xml/rows_bengali.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_bengali_akkhor.xml b/app/src/main/res/xml/rows_bengali_akkhor.xml new file mode 100644 index 0000000..6ace800 --- /dev/null +++ b/app/src/main/res/xml/rows_bengali_akkhor.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_bengali_unijoy.xml b/app/src/main/res/xml/rows_bengali_unijoy.xml new file mode 100644 index 0000000..5db3f77 --- /dev/null +++ b/app/src/main/res/xml/rows_bengali_unijoy.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_bulgarian.xml b/app/src/main/res/xml/rows_bulgarian.xml new file mode 100644 index 0000000..07b714e --- /dev/null +++ b/app/src/main/res/xml/rows_bulgarian.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_bulgarian_bds.xml b/app/src/main/res/xml/rows_bulgarian_bds.xml new file mode 100644 index 0000000..f3cefbe --- /dev/null +++ b/app/src/main/res/xml/rows_bulgarian_bds.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_colemak.xml b/app/src/main/res/xml/rows_colemak.xml new file mode 100644 index 0000000..5b5c7a6 --- /dev/null +++ b/app/src/main/res/xml/rows_colemak.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_dvorak.xml b/app/src/main/res/xml/rows_dvorak.xml new file mode 100644 index 0000000..a4c1f21 --- /dev/null +++ b/app/src/main/res/xml/rows_dvorak.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_east_slavic.xml b/app/src/main/res/xml/rows_east_slavic.xml new file mode 100644 index 0000000..01450df --- /dev/null +++ b/app/src/main/res/xml/rows_east_slavic.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_farsi.xml b/app/src/main/res/xml/rows_farsi.xml new file mode 100644 index 0000000..4c24772 --- /dev/null +++ b/app/src/main/res/xml/rows_farsi.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_georgian.xml b/app/src/main/res/xml/rows_georgian.xml new file mode 100644 index 0000000..7d00eca --- /dev/null +++ b/app/src/main/res/xml/rows_georgian.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_greek.xml b/app/src/main/res/xml/rows_greek.xml new file mode 100644 index 0000000..c51b9fe --- /dev/null +++ b/app/src/main/res/xml/rows_greek.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_hebrew.xml b/app/src/main/res/xml/rows_hebrew.xml new file mode 100644 index 0000000..92a8beb --- /dev/null +++ b/app/src/main/res/xml/rows_hebrew.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_hindi.xml b/app/src/main/res/xml/rows_hindi.xml new file mode 100644 index 0000000..c354a0c --- /dev/null +++ b/app/src/main/res/xml/rows_hindi.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_hindi_compact.xml b/app/src/main/res/xml/rows_hindi_compact.xml new file mode 100644 index 0000000..bf072ec --- /dev/null +++ b/app/src/main/res/xml/rows_hindi_compact.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_kannada.xml b/app/src/main/res/xml/rows_kannada.xml new file mode 100644 index 0000000..5304142 --- /dev/null +++ b/app/src/main/res/xml/rows_kannada.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/rows_khmer.xml b/app/src/main/res/xml/rows_khmer.xml new file mode 100644 index 0000000..0347bad --- /dev/null +++ b/app/src/main/res/xml/rows_khmer.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_lao.xml b/app/src/main/res/xml/rows_lao.xml new file mode 100644 index 0000000..f1fbaca --- /dev/null +++ b/app/src/main/res/xml/rows_lao.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_macedonian.xml b/app/src/main/res/xml/rows_macedonian.xml new file mode 100644 index 0000000..5e14fd2 --- /dev/null +++ b/app/src/main/res/xml/rows_macedonian.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_malayalam.xml b/app/src/main/res/xml/rows_malayalam.xml new file mode 100644 index 0000000..aa055ec --- /dev/null +++ b/app/src/main/res/xml/rows_malayalam.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/rows_marathi.xml b/app/src/main/res/xml/rows_marathi.xml new file mode 100644 index 0000000..1af6294 --- /dev/null +++ b/app/src/main/res/xml/rows_marathi.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/rows_mongolian.xml b/app/src/main/res/xml/rows_mongolian.xml new file mode 100644 index 0000000..5ee2fa8 --- /dev/null +++ b/app/src/main/res/xml/rows_mongolian.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_nepali_romanized.xml b/app/src/main/res/xml/rows_nepali_romanized.xml new file mode 100644 index 0000000..54a1d73 --- /dev/null +++ b/app/src/main/res/xml/rows_nepali_romanized.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_nepali_traditional.xml b/app/src/main/res/xml/rows_nepali_traditional.xml new file mode 100644 index 0000000..e8a8022 --- /dev/null +++ b/app/src/main/res/xml/rows_nepali_traditional.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_nordic.xml b/app/src/main/res/xml/rows_nordic.xml new file mode 100644 index 0000000..dcbd3ad --- /dev/null +++ b/app/src/main/res/xml/rows_nordic.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_number.xml b/app/src/main/res/xml/rows_number.xml new file mode 100644 index 0000000..0312b04 --- /dev/null +++ b/app/src/main/res/xml/rows_number.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_number_normal.xml b/app/src/main/res/xml/rows_number_normal.xml new file mode 100644 index 0000000..dbe77f1 --- /dev/null +++ b/app/src/main/res/xml/rows_number_normal.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_number_password.xml b/app/src/main/res/xml/rows_number_password.xml new file mode 100644 index 0000000..a59b8ef --- /dev/null +++ b/app/src/main/res/xml/rows_number_password.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_pcqwerty.xml b/app/src/main/res/xml/rows_pcqwerty.xml new file mode 100644 index 0000000..ca26769 --- /dev/null +++ b/app/src/main/res/xml/rows_pcqwerty.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_phone.xml b/app/src/main/res/xml/rows_phone.xml new file mode 100644 index 0000000..3ac9acf --- /dev/null +++ b/app/src/main/res/xml/rows_phone.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_phone_symbols.xml b/app/src/main/res/xml/rows_phone_symbols.xml new file mode 100644 index 0000000..e8ca7f0 --- /dev/null +++ b/app/src/main/res/xml/rows_phone_symbols.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_qwerty.xml b/app/src/main/res/xml/rows_qwerty.xml new file mode 100644 index 0000000..180d614 --- /dev/null +++ b/app/src/main/res/xml/rows_qwerty.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_qwertz.xml b/app/src/main/res/xml/rows_qwertz.xml new file mode 100644 index 0000000..dab754f --- /dev/null +++ b/app/src/main/res/xml/rows_qwertz.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_serbian.xml b/app/src/main/res/xml/rows_serbian.xml new file mode 100644 index 0000000..4f322ef --- /dev/null +++ b/app/src/main/res/xml/rows_serbian.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_serbian_qwertz.xml b/app/src/main/res/xml/rows_serbian_qwertz.xml new file mode 100644 index 0000000..1346cfc --- /dev/null +++ b/app/src/main/res/xml/rows_serbian_qwertz.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/rows_spanish.xml b/app/src/main/res/xml/rows_spanish.xml new file mode 100644 index 0000000..00f3aad --- /dev/null +++ b/app/src/main/res/xml/rows_spanish.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_swiss.xml b/app/src/main/res/xml/rows_swiss.xml new file mode 100644 index 0000000..70c9405 --- /dev/null +++ b/app/src/main/res/xml/rows_swiss.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_symbols.xml b/app/src/main/res/xml/rows_symbols.xml new file mode 100644 index 0000000..5a90ebf --- /dev/null +++ b/app/src/main/res/xml/rows_symbols.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_symbols_shift.xml b/app/src/main/res/xml/rows_symbols_shift.xml new file mode 100644 index 0000000..6b8121d --- /dev/null +++ b/app/src/main/res/xml/rows_symbols_shift.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_tamil.xml b/app/src/main/res/xml/rows_tamil.xml new file mode 100644 index 0000000..b068cc8 --- /dev/null +++ b/app/src/main/res/xml/rows_tamil.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/rows_telugu.xml b/app/src/main/res/xml/rows_telugu.xml new file mode 100644 index 0000000..9d1ceda --- /dev/null +++ b/app/src/main/res/xml/rows_telugu.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/rows_thai.xml b/app/src/main/res/xml/rows_thai.xml new file mode 100644 index 0000000..ef56a9a --- /dev/null +++ b/app/src/main/res/xml/rows_thai.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_turkish_f.xml b/app/src/main/res/xml/rows_turkish_f.xml new file mode 100644 index 0000000..08064ae --- /dev/null +++ b/app/src/main/res/xml/rows_turkish_f.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_turkish_q.xml b/app/src/main/res/xml/rows_turkish_q.xml new file mode 100644 index 0000000..99f6281 --- /dev/null +++ b/app/src/main/res/xml/rows_turkish_q.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_urdu.xml b/app/src/main/res/xml/rows_urdu.xml new file mode 100644 index 0000000..78d48d8 --- /dev/null +++ b/app/src/main/res/xml/rows_urdu.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/rows_uzbek.xml b/app/src/main/res/xml/rows_uzbek.xml new file mode 100644 index 0000000..ef187ea --- /dev/null +++ b/app/src/main/res/xml/rows_uzbek.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/rows_workman.xml b/app/src/main/res/xml/rows_workman.xml new file mode 100644 index 0000000..b97ccd5 --- /dev/null +++ b/app/src/main/res/xml/rows_workman.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/test/java/com/colorful/keyboard/theme/ExampleUnitTest.java b/app/src/test/java/com/colorful/keyboard/theme/ExampleUnitTest.java new file mode 100644 index 0000000..4d75d2d --- /dev/null +++ b/app/src/test/java/com/colorful/keyboard/theme/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.colorful.keyboard.theme; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/app/themes.jks b/app/themes.jks new file mode 100644 index 0000000..3edcdb1 Binary files /dev/null and b/app/themes.jks differ diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..e27674c --- /dev/null +++ b/build.gradle @@ -0,0 +1,21 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + maven { url 'https://artifacts.applovin.com/android' } + } + dependencies { + // Google Services plugin - firebase need + classpath 'com.google.gms:google-services:4.4.2' + // Add the dependency for the Crashlytics Gradle plugin + classpath 'com.google.firebase:firebase-crashlytics-gradle:3.0.2' + } +} + +plugins { + id 'com.android.application' version '8.1.0' apply false + id 'org.jetbrains.kotlin.android' version "1.8.0" apply false + // Add the dependency for the Google services Gradle plugin + id("com.google.gms.google-services") version "4.4.2" apply false + id("com.google.firebase.crashlytics") version "3.0.2" apply false +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..3ed43c7 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,23 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true +android.enableJetifier=true +android.injected.testOnly=false \ No newline at end of file diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..4f906e0 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..227708c --- /dev/null +++ b/settings.gradle @@ -0,0 +1,39 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + maven { url = uri("https://jitpack.io") } + maven { url = uri("https://android-sdk.is.com") } + maven { url = uri("https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea") } + maven { url = uri("https://artifact.bytedance.com/repository/pangle") } + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + maven { url = uri("https://jitpack.io") } + + maven { url = uri("https://android-sdk.is.com") } + maven { url = uri("https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea") } + maven { url = uri("https://artifact.bytedance.com/repository/pangle") } + + flatDir { + dirs("libs") + } + //Anythink(Core) + maven { url'https://jfrog.anythinktech.com/artifactory/overseas_sdk'} + //Ironsource + maven { url'https://android-sdk.is.com/'} + //Pangle + maven { url'https://artifact.bytedance.com/repository/pangle'} + //Mintegral + maven { url'https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea'} + + } +} + +rootProject.name = "inputKeyBoard" +include ':app'