![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Keyboard-brightgreen.svg?style=flat-square)
- Simple research keyboard for Android
- Custom Keyboard
- Emoji Custom Keyboard
- Call API inside Keyboard
- Open Form inside Keyboard
- Support Dark Theme
- AutoText Feature
- Setup Toggle Feature
Version Release
This Is Latest Release
$version_release = 1.1.7
What's New??
* Avaiable in dark mode *
* Enhance Performance *
* Easy Change Background Keyboard *
* Setup Theme *
How To Use As Library (Coming Soon)
Step 1. Add the JitPack repository to your build file (build.gradle : Project)
<Option 1> Groovy Gradle
// Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
<Option 2> Kotlin DSL Gradle
// Add it in your root build.gradle.kts at the end of repositories:
allprojects {
repositories {
...
maven("https://jitpack.io")
}
}
Step 2. Add the dependency (build.gradle : Module)
<Option 1> Groovy Gradle
dependencies {
// library frogo-keyboard
implementation 'com.github.amirisback:keyboard:1.1.7'
}
<Option 2> Kotlin DSL Gradle
dependencies {
// library frogo-keyboard
implementation("com.github.amirisback:keyboard:1.1.7")
}
Step 3. Create Layout Keyboard IME
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/keyboard_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/keyboard_bg_root">
<!-- start of base keyboard-->
<LinearLayout
android:id="@+id/container_keyboard_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/keyboard_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/keyboard_bg_root"
android:minHeight="@dimen/frogo_dimen_64dp" />
<com.frogobox.libkeyboard.ui.main.MainKeyboard
android:id="@+id/keyboard_main"
style="@style/KwKeyboardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/theme_dark_background_color" />
</LinearLayout>
<!-- End of base keyboard-->
<!-- below is the layout for your header menu on top of your base keyboard -->
<com.frogobox.appkeyboard.ui.keyboard.autotext.AutoTextKeyboard
android:id="@+id/keyboard_autotext"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/container_keyboard_main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/container_keyboard_main" />
<com.frogobox.appkeyboard.ui.keyboard.templatetext.TemplateTextKeyboard
android:id="@+id/keyboard_template_text"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/container_keyboard_main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/container_keyboard_main" />
<com.frogobox.appkeyboard.ui.keyboard.news.NewsKeyboard
android:id="@+id/keyboard_news"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/container_keyboard_main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/container_keyboard_main" />
<com.frogobox.appkeyboard.ui.keyboard.movie.MovieKeyboard
android:id="@+id/keyboard_moview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/container_keyboard_main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/container_keyboard_main" />
<com.frogobox.appkeyboard.ui.keyboard.webview.WebiewKeyboard
android:id="@+id/keyboard_webview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/container_keyboard_main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/container_keyboard_main" />
<com.frogobox.appkeyboard.ui.keyboard.form.FormKeyboard
android:id="@+id/keyboard_form"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/container_keyboard_main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/container_keyboard_main" />
<!-- end of header menu layout -->
<com.frogobox.libkeyboard.ui.emoji.EmojiKeyboard
android:id="@+id/keyboard_emoji"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/container_keyboard_main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/container_keyboard_main" />
</androidx.constraintlayout.widget.ConstraintLayout>
Step 4. Create Service Keyboard IME
Create Class Keyboard IME
class KeyboardIME : BaseKeyboardIME<YourIMELayoutBinding>() {
// set your custom keyboard layout
override fun setupViewBinding(): YourIMELayoutBinding {
return YourIMELayoutBinding.inflate(LayoutInflater.from(this), null, false)
}
override fun initialSetupKeyboard() {
binding?.keyboardMain?.setKeyboard(keyboard!!) // your base keyboard
binding?.mockMeasureHeightKeyboardMain?.setKeyboard(keyboard!!) // this code is for your keyboard header menu
}
override fun setupBinding() {
initialSetupKeyboard()
binding?.keyboardMain?.mOnKeyboardActionListener = this
binding?.keyboardEmoji?.mOnKeyboardActionListener = this
}
// redraw keyboard for capslock on/off state
override fun invalidateAllKeys() {
binding?.keyboardMain?.invalidateAllKeys()
}
// call this function when navigating to your feature
override fun hideMainKeyboard() {
binding?.apply {
keyboardMain.gone()
keyboardHeader.gone()
mockMeasureHeightKeyboard.invisible()
}
}
override fun showOnlyKeyboard() {
binding?.keyboardMain?.visible()
}
override fun hideOnlyKeyboard() {
binding?.keyboardMain?.visible()
}
// setup emoji keyboard
override fun runEmojiBoard() {
binding?.keyboardEmoji?.visible()
hideMainKeyboard()
binding?.keyboardEmoji?.openEmojiPalette()
}
}
For Emoji Keyboard, dont forget to implement Dependency Injection to load emoji asset manager
@HiltAndroidApp
class App: Application() {
override fun onCreate() {
super.onCreate()
setupEmojiCompat()
}
private fun setupEmojiCompat() {
val config = BundledEmojiCompatConfig(this)
EmojiCompat.init(config)
}
}
Step 5. Add keyboard header menu
setup keyboard header icon & menu name
class KeyboardUtil {
private val pref: PreferenceDelegatesImpl by inject(PreferenceDelegatesImpl::class.java)
fun menuToggle(): List<KeyboardFeature> {
return listOf(
KeyboardFeature(
KeyboardFeatureType.AUTO_TEXT.id,
KeyboardFeatureType.AUTO_TEXT,
R.drawable.ic_menu_auto_text,
pref.getPrefBoolean(KeyboardFeatureType.AUTO_TEXT.id, true)
),
KeyboardFeature(
KeyboardFeatureType.TEMPLATE_TEXT_APP.id,
KeyboardFeatureType.TEMPLATE_TEXT_APP,
R.drawable.ic_menu_ps_app,
pref.getPrefBoolean(KeyboardFeatureType.TEMPLATE_TEXT_APP.id, true)
),
KeyboardFeature(
KeyboardFeatureType.TEMPLATE_TEXT_GAME.id,
KeyboardFeatureType.TEMPLATE_TEXT_GAME,
R.drawable.ic_menu_ps_game,
pref.getPrefBoolean(KeyboardFeatureType.TEMPLATE_TEXT_GAME.id, true)
),
KeyboardFeature(
KeyboardFeatureType.TEMPLATE_TEXT_LOVE.id,
KeyboardFeatureType.TEMPLATE_TEXT_LOVE,
R.drawable.ic_menu_ps_love,
pref.getPrefBoolean(KeyboardFeatureType.TEMPLATE_TEXT_LOVE.id, true)
),
KeyboardFeature(
KeyboardFeatureType.TEMPLATE_TEXT_GREETING.id,
KeyboardFeatureType.TEMPLATE_TEXT_GREETING,
R.drawable.ic_menu_ps_greeting,
pref.getPrefBoolean(KeyboardFeatureType.TEMPLATE_TEXT_GREETING.id, true)
),
KeyboardFeature(
KeyboardFeatureType.TEMPLATE_TEXT_SALE.id,
KeyboardFeatureType.TEMPLATE_TEXT_SALE,
R.drawable.ic_menu_ps_sale,
pref.getPrefBoolean(KeyboardFeatureType.TEMPLATE_TEXT_SALE.id, true)
),
KeyboardFeature(
KeyboardFeatureType.NEWS.id,
KeyboardFeatureType.NEWS,
R.drawable.ic_menu_news,
pref.getPrefBoolean(KeyboardFeatureType.NEWS.id, true)
),
KeyboardFeature(
KeyboardFeatureType.MOVIE.id,
KeyboardFeatureType.MOVIE,
R.drawable.ic_menu_movie,
pref.getPrefBoolean(KeyboardFeatureType.MOVIE.id, true)
),
KeyboardFeature(
KeyboardFeatureType.WEB.id,
KeyboardFeatureType.WEB,
R.drawable.ic_menu_website,
pref.getPrefBoolean(KeyboardFeatureType.WEB.id, true)
),
KeyboardFeature(
KeyboardFeatureType.FORM.id,
KeyboardFeatureType.FORM,
R.drawable.ic_menu_form,
pref.getPrefBoolean(KeyboardFeatureType.FORM.id, true)
),
KeyboardFeature(
KeyboardFeatureType.CHANGE_KEYBOARD.id,
KeyboardFeatureType.CHANGE_KEYBOARD,
R.drawable.ic_menu_keyboard,
pref.getPrefBoolean(KeyboardFeatureType.CHANGE_KEYBOARD.id, true)
),
KeyboardFeature(
KeyboardFeatureType.SETTING.id,
KeyboardFeatureType.SETTING,
R.drawable.ic_menu_setting,
pref.getPrefBoolean(KeyboardFeatureType.SETTING.id, true)
)
).sortedBy { it.state }
}
fun menuKeyboard(): List<KeyboardFeature> {
val listFeature = mutableListOf<KeyboardFeature>()
menuToggle().forEach { data ->
if (data.state) {
listFeature.add(data)
}
}
return listFeature
}
}
setup keyboard header feature on KeyboardIME class
class KeyboardIME : BaseKeyboardIME<YourIMELayoutBinding>() {
// ...
override fun setupFeatureKeyboard() {
val maxMenu = 4
val gridSize = if (KeyboardUtil().menuKeyboard().size <= maxMenu) {
KeyboardUtil().menuKeyboard().size
} else if (KeyboardUtil().menuKeyboard().size.mod(maxMenu) == 0) {
maxMenu
} else {
maxMenu + 1
}
binding?.apply {
if (KeyboardUtil().menuKeyboard().isEmpty()) {
keyboardHeader.gone()
mockKeyboardHeader.gone()
} else {
keyboardHeader.visible()
mockKeyboardHeader.visible()
keyboardHeader.injectorBinding<KeyboardFeature, ItemKeyboardHeaderBinding>()
.addData(KeyboardUtil().menuKeyboard())
.addCallback(object :
IFrogoBindingAdapter<KeyboardFeature, ItemKeyboardHeaderBinding> {
override fun setViewBinding(parent: ViewGroup): ItemKeyboardHeaderBinding {
return ItemKeyboardHeaderBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}
override fun setupInitComponent(
binding: ItemKeyboardHeaderBinding,
data: KeyboardFeature,
position: Int,
notifyListener: FrogoRecyclerNotifyListener<KeyboardFeature>,
) {
binding.ivIcon.setImageResource(data.icon)
binding.tvTitle.text = data.type.title
if (data.state) {
binding.root.visible()
} else {
binding.root.gone()
}
}
override fun onItemClicked(
binding: ItemKeyboardHeaderBinding,
data: KeyboardFeature,
position: Int,
notifyListener: FrogoRecyclerNotifyListener<KeyboardFeature>,
) {
when (data.type) {
KeyboardFeatureType.NEWS -> {
hideMainKeyboard()
keyboardNews.visible()
}
KeyboardFeatureType.MOVIE -> {
hideMainKeyboard()
keyboardMoview.visible()
}
KeyboardFeatureType.WEB -> {
mockMeasureHeightKeyboard.invisible()
keyboardHeader.gone()
keyboardWebview.visible()
}
KeyboardFeatureType.FORM -> {
hideMainKeyboard()
keyboardForm.visible()
keyboardForm.binding?.etText?.showKeyboardExt()
keyboardForm.binding?.etText2?.showKeyboardExt()
keyboardForm.binding?.etText3?.showKeyboardExt()
keyboardForm.setOnClickListener {
hideOnlyKeyboard()
}
}
KeyboardFeatureType.AUTO_TEXT -> {
hideMainKeyboard()
keyboardAutotext.visible()
}
KeyboardFeatureType.TEMPLATE_TEXT_GAME -> {
hideMainKeyboard()
keyboardTemplateText.setupTemplateTextType(KeyboardFeatureType.TEMPLATE_TEXT_GAME)
keyboardTemplateText.visible()
}
KeyboardFeatureType.TEMPLATE_TEXT_APP -> {
hideMainKeyboard()
keyboardTemplateText.setupTemplateTextType(KeyboardFeatureType.TEMPLATE_TEXT_APP)
keyboardTemplateText.visible()
}
KeyboardFeatureType.TEMPLATE_TEXT_SALE -> {
hideMainKeyboard()
keyboardTemplateText.setupTemplateTextType(KeyboardFeatureType.TEMPLATE_TEXT_SALE)
keyboardTemplateText.visible()
}
KeyboardFeatureType.TEMPLATE_TEXT_LOVE -> {
hideMainKeyboard()
keyboardTemplateText.setupTemplateTextType(KeyboardFeatureType.TEMPLATE_TEXT_LOVE)
keyboardTemplateText.visible()
}
KeyboardFeatureType.TEMPLATE_TEXT_GREETING -> {
hideMainKeyboard()
keyboardTemplateText.setupTemplateTextType(KeyboardFeatureType.TEMPLATE_TEXT_GREETING)
keyboardTemplateText.visible()
}
KeyboardFeatureType.CHANGE_KEYBOARD -> {
(getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager).showInputMethodPicker()
}
KeyboardFeatureType.SETTING -> {
binding.root.context.startActivity(
Intent(binding.root.context, MainActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
})
}
}
}
override fun onItemLongClicked(
binding: ItemKeyboardHeaderBinding,
data: KeyboardFeature,
position: Int,
notifyListener: FrogoRecyclerNotifyListener<KeyboardFeature>,
) {
}
})
.createLayoutGrid(gridSize)
.build()
}
}
}
// ...
}
if your feature is using a textfield, add below code to your KeyboardIME class
@RequiresApi(Build.VERSION_CODES.M)
override fun onKey(code: Int) {
val formView = binding?.keyboardForm
var inputConnection = currentInputConnection
if (formView?.visibility == View.VISIBLE) {
val et1 = formView.binding?.etText
val et1Connection = et1?.onCreateInputConnection(EditorInfo())
val et2 = formView.binding?.etText2
val et2Connection = et2?.onCreateInputConnection(EditorInfo())
val et3 = formView.binding?.etText3
val et3Connection = et3?.onCreateInputConnection(EditorInfo())
if (et1?.isFocused == true) {
inputConnection = et1Connection
} else if (et2?.isFocused == true) {
inputConnection = et2Connection
} else if (et3?.isFocused == true) {
inputConnection = et3Connection
}
} else if (binding?.keyboardWebview?.visibility == View.VISIBLE) {
inputConnection =
binding?.keyboardWebview?.binding?.webview?.onCreateInputConnection(EditorInfo())
} else {
inputConnection = currentInputConnection
}
onKeyExt(code, inputConnection)
}
Step 6. Create keys_config.xml inside xml folder
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:icon="@drawable/ic_frogobox"
android:settingsActivity="com.frogobox.appkeyboard.ui.main.MainActivity">
<subtype android:imeSubtypeMode="Keyboard" />
</input-method>
Step 7. Create Keyboard Service In Manifest inside application tag
<service
android:name=".services.KeyboardIME"
android:exported="true"
android:label="@string/app_name"
android:permission="android.permission.BIND_INPUT_METHOD">
<meta-data
android:name="android.view.im"
android:resource="@xml/keys_config" />
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
</service>
Video Play
https://user-images.githubusercontent.com/24654871/231431022-4410933f-7199-4967-9db1-24544f5593e0.mp4
Screen Shoot
How To Activated
Activated Keyboard
Welcome Page (Light) |
Activated Keyboard (Light) |
After Activated (Light) |
![](https://amirisback.github.io/keyboard/docs/image/ss/activated-keyboard/light/ss_1.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/activated-keyboard/light/ss_2-1.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/activated-keyboard/light/ss_2-2.png) |
Welcome Page (Dark) |
Activated Keyboard (Dark) |
After Activated (Dark) |
![](https://amirisback.github.io/keyboard/docs/image/ss/activated-keyboard/dark/ss_1.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/activated-keyboard/dark/ss_2-1.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/activated-keyboard/dark/ss_2-2.jpeg) |
Change Keyboard
Before Change Keyboard (Light) |
Change Keyboard (Light) |
After Change Keyboard (Light) |
![](https://amirisback.github.io/keyboard/docs/image/ss/activated-keyboard/light/ss_2-2.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/change-keyboard/light/ss_3-1.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/change-keyboard/light/ss_3-2.png) |
Before Change Keyboard (Dark) |
Change Keyboard (Dark) |
After Change Keyboard (Dark) |
![](https://amirisback.github.io/keyboard/docs/image/ss/activated-keyboard/dark/ss_2-2.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/change-keyboard/dark/ss_3-1.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/change-keyboard/dark/ss_3-2.jpeg) |
Normal Keyboard State
Alphabet Keyboard (Light) |
Numeric Keyboard (Light) |
![](https://amirisback.github.io/keyboard/docs/image/ss/normal-keyboard-state/light/ss_4-1.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/normal-keyboard-state/light/ss_4-2.png) |
Alphabet Keyboard (Dark) |
Numeric Keyboard (Dark) |
![](https://amirisback.github.io/keyboard/docs/image/ss/normal-keyboard-state/dark/ss_4-1.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/normal-keyboard-state/dark/ss_4-2.jpeg) |
Feature Keyboard
Using API
News API (Light) |
Movie API (Light) |
![](https://amirisback.github.io/keyboard/docs/image/ss/using-api/light/ss_5.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/using-api/light/ss_6.png) |
News API (Dark) |
Movie API (Dark) |
![](https://amirisback.github.io/keyboard/docs/image/ss/using-api/dark/ss_5.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/using-api/dark/ss_6.jpeg) |
Webview
Show Webview |
Input Webview |
![](https://amirisback.github.io/keyboard/docs/image/ss/webview/light/ss_7.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/webview/light/ss_8.png) |
Form
Show Form (Light) |
Input Form (Light) |
Hide Keyboard (Light) |
![](https://amirisback.github.io/keyboard/docs/image/ss/form/light/ss_9.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/form/light/ss_10.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/form/light/ss_11.png) |
Show Form (Dark) |
Input Form (Dark) |
Hide Keyboard (Dark) |
![](https://amirisback.github.io/keyboard/docs/image/ss/form/dark/ss_9.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/form/dark/ss_10.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/form/dark/ss_11.jpeg) |
Emojis
Emojis (Light) |
Emojis (Light) |
![](https://amirisback.github.io/keyboard/docs/image/ss/emojis/light/ss_1.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/emojis/light/ss_2.jpeg) |
Emojis (Dark) |
Emojis (Dark) |
![](https://amirisback.github.io/keyboard/docs/image/ss/emojis/dark/ss_1.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/emojis/dark/ss_2.jpeg) |
Auto Text
Menu Auto Text (Light) |
Auto Text Inputed (Light) |
Auto Text Dashboard (Light) |
![](https://amirisback.github.io/keyboard/docs/image/ss/auto-text/light/ss_16-1.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/auto-text/light/ss_16-2.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/auto-text/light/ss_16-3.png) |
Empty View Auto Text (Light) |
Auto Text Editor (Light) |
Auto Text Detail (Light) |
![](https://amirisback.github.io/keyboard/docs/image/ss/auto-text/light/ss_16-4.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/auto-text/light/ss_16-5.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/auto-text/light/ss_16-6.png) |
Menu Auto Text (Dark) |
Auto Text Inputed (Dark) |
Auto Text Dashboard (Dark) |
![](https://amirisback.github.io/keyboard/docs/image/ss/auto-text/dark/ss_16-1.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/auto-text/dark/ss_16-2.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/auto-text/dark/ss_16-3.jpeg) |
Empty View Auto Text (Dark) |
Auto Text Editor (Dark) |
Auto Text Detail (Dark) |
![](https://amirisback.github.io/keyboard/docs/image/ss/auto-text/dark/ss_16-4.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/auto-text/dark/ss_16-5.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/auto-text/dark/ss_16-6.jpeg) |
Open To Other App
Google Search (Light) |
Google Message (Light) |
Sign In Google (Light) |
![](https://amirisback.github.io/keyboard/docs/image/ss/open-to-other-app/light/ss_12.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/open-to-other-app/light/ss_13.png) |
![](https://amirisback.github.io/keyboard/docs/image/ss/open-to-other-app/light/ss_14.png) |
Google Search (Dark) |
Google Message (Dark) |
Sign In Google (Dark) |
![](https://amirisback.github.io/keyboard/docs/image/ss/open-to-other-app/dark/ss_12.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/open-to-other-app/dark/ss_13.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/open-to-other-app/dark/ss_14.jpeg) |
Toggle Feature
All Toggle Off (Light) |
Keyboard No Feature (Light) |
Some Toggle On (Light) |
Keyboard With Feature (Light) |
![](https://amirisback.github.io/keyboard/docs/image/ss/toggle/ss_light_1.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/toggle/ss_light_2.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/toggle/ss_light_3.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/toggle/ss_light_4.jpeg) |
All Toggle Off (Dark) |
Keyboard No Feature (Dark) |
Some Toggle On (Dark) |
Keyboard With Feature (Dark) |
![](https://amirisback.github.io/keyboard/docs/image/ss/toggle/ss_dark_1.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/toggle/ss_dark_2.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/toggle/ss_dark_3.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/toggle/ss_dark_4.jpeg) |
Multi Language Support
Menu Multi Language (Light) |
Change Language (Light) |
Menu Multi Language (Dark) |
Change Language (Dark) |
![](https://amirisback.github.io/keyboard/docs/image/ss/multi-language/light/ss-1.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/multi-language/light/ss-2.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/multi-language/dark/ss-1.jpeg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/multi-language/dark/ss-2.jpeg) |
Multi Theme Suppported
Setup Theme (Light) |
Theme Applied (Light) |
Setup Theme (Dark) |
Theme Applied (Dark) |
![](https://amirisback.github.io/keyboard/docs/image/ss/theme/light/ss_1.jpg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/theme/light/ss_2.jpg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/theme/dark/ss_1.jpg) |
![](https://amirisback.github.io/keyboard/docs/image/ss/theme/dark/ss_2.jpg) |
Documentation
Frogo Library
Colaborator
Very open to anyone, I'll write your name under this, please contribute by sending an email to me
- Mail To faisalamircs@gmail.com
- Subject : Github [Github-Username-Account] [Language] _ [Repository-Name]
- Example : Github_amirisback_kotlin_admob-helper-implementation
Name Of Contribute
- Muhammad Faisal Amir
- Waiting List
- Waiting List
Waiting for your contribute
Attention !!!
- Please enjoy and don't forget fork and give a star
- Don't Forget Follow My Github Account
![ScreenShoot Apps](https://raw.githubusercontent.com/amirisback/frogo-recycler-view/master/docs/image/mad_score.png)