Add alternative keyboard at the authentication screen

This commit is contained in:
Jonas Lochmann 2019-08-12 00:00:00 +00:00
parent 921393af1c
commit 54b124cde9
No known key found for this signature in database
GPG key ID: 8B8C9AEE10FA5B36
5 changed files with 176 additions and 8 deletions

View file

@ -16,6 +16,7 @@
package io.timelimit.android.ui.login package io.timelimit.android.ui.login
import android.content.Context import android.content.Context
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -32,6 +33,7 @@ import io.timelimit.android.data.model.User
import io.timelimit.android.databinding.NewLoginFragmentBinding import io.timelimit.android.databinding.NewLoginFragmentBinding
import io.timelimit.android.extensions.setOnEnterListenr import io.timelimit.android.extensions.setOnEnterListenr
import io.timelimit.android.ui.main.getActivityViewModel import io.timelimit.android.ui.main.getActivityViewModel
import io.timelimit.android.ui.view.KeyboardViewListener
class NewLoginFragment: DialogFragment() { class NewLoginFragment: DialogFragment() {
companion object { companion object {
@ -94,7 +96,21 @@ class NewLoginFragment: DialogFragment() {
binding.userList.recycler.layoutManager = LinearLayoutManager(context) binding.userList.recycler.layoutManager = LinearLayoutManager(context)
binding.enterPassword.apply { binding.enterPassword.apply {
password.setOnEnterListenr { showKeyboardButton.setOnClickListener {
showCustomKeyboard = !showCustomKeyboard
if (showCustomKeyboard) {
inputMethodManager.hideSoftInputFromWindow(password.windowToken, 0)
} else {
inputMethodManager.showSoftInput(password, 0)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
password.showSoftInputOnFocus = !showCustomKeyboard
}
}
fun go() {
model.tryParentLogin( model.tryParentLogin(
password = password.text.toString(), password = password.text.toString(),
keepSignedIn = checkDontAskAgain.isChecked, keepSignedIn = checkDontAskAgain.isChecked,
@ -102,6 +118,21 @@ class NewLoginFragment: DialogFragment() {
setAsDeviceUser = checkAssignMyself.isChecked setAsDeviceUser = checkAssignMyself.isChecked
) )
} }
keyboard.listener = object: KeyboardViewListener {
override fun onItemClicked(content: String) {
val start = Math.max(password.selectionStart, 0)
val end = Math.max(password.selectionEnd, 0)
password.text.replace(Math.min(start, end), Math.max(start, end), content, 0, content.length)
}
override fun onGoClicked() {
go()
}
}
password.setOnEnterListenr { go() }
} }
binding.childPassword.apply { binding.childPassword.apply {
@ -134,8 +165,10 @@ class NewLoginFragment: DialogFragment() {
binding.switcher.displayedChild = PARENT_AUTH binding.switcher.displayedChild = PARENT_AUTH
} }
binding.enterPassword.password.requestFocus() if (!binding.enterPassword.showCustomKeyboard) {
inputMethodManager.showSoftInput(binding.enterPassword.password, 0) binding.enterPassword.password.requestFocus()
inputMethodManager.showSoftInput(binding.enterPassword.password, 0)
}
binding.enterPassword.showKeepLoggedInOption = status.isConnectedMode binding.enterPassword.showKeepLoggedInOption = status.isConnectedMode

View file

@ -0,0 +1,82 @@
/*
* TimeLimit Copyright <C> 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package io.timelimit.android.ui.view
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.Button
import android.widget.HorizontalScrollView
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayout
import io.timelimit.android.R
class KeyboardView(context: Context, attributeSet: AttributeSet): HorizontalScrollView(context, attributeSet) {
companion object {
private const val chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789.,-"
}
var listener: KeyboardViewListener? = null
private val flexbox = FlexboxLayout(context)
private val inflater = LayoutInflater.from(context)
init {
flexbox.flexDirection = FlexDirection.COLUMN
flexbox.flexWrap = FlexWrap.WRAP
addView(flexbox)
chars.forEach { char ->
inflater.inflate(R.layout.keyboard_btn, flexbox, false).let { button ->
button as Button
button.apply {
transformationMethod = null
text = char.toString()
minWidth = 0
minHeight = 0
setOnClickListener {
listener?.onItemClicked(char.toString())
}
}
flexbox.addView(button)
}
}
inflater.inflate(R.layout.keyboard_btn, flexbox, false).let { button ->
button as Button
button.apply {
setText(R.string.generic_go)
setOnClickListener {
listener?.onGoClicked()
}
}
flexbox.addView(button)
}
}
}
interface KeyboardViewListener {
fun onItemClicked(content: String)
fun onGoClicked()
}

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,5L4,5c-1.1,0 -1.99,0.9 -1.99,2L2,17c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,7c0,-1.1 -0.9,-2 -2,-2zM11,8h2v2h-2L11,8zM11,11h2v2h-2v-2zM8,8h2v2L8,10L8,8zM8,11h2v2L8,13v-2zM7,13L5,13v-2h2v2zM7,10L5,10L5,8h2v2zM16,17L8,17v-2h8v2zM16,13h-2v-2h2v2zM16,10h-2L14,8h2v2zM19,13h-2v-2h2v2zM19,10h-2L17,8h2v2z"/>
</vector>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
TimeLimit Copyright <C> 2019 Jonas Lochmann
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<Button xmlns:android="http://schemas.android.com/apk/res/android"
style="?android:buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

View file

@ -23,6 +23,10 @@
name="canNotKeepLoggedIn" name="canNotKeepLoggedIn"
type="boolean" /> type="boolean" />
<variable
name="showCustomKeyboard"
type="boolean" />
<import type="android.view.View" /> <import type="android.view.View" />
</data> </data>
@ -60,11 +64,32 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<EditText <LinearLayout
android:imeOptions="actionGo" android:orientation="horizontal"
android:inputType="textPassword" android:layout_width="match_parent"
android:id="@+id/password" android:layout_height="wrap_content">
android:hint="@string/login_password_hint"
<EditText
android:layout_weight="1"
android:imeOptions="actionGo"
android:inputType="textPassword"
android:id="@+id/password"
android:hint="@string/login_password_hint"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<ImageButton
android:background="?selectableItemBackground"
android:id="@+id/show_keyboard_button"
android:src="@drawable/ic_keyboard_black_24dp"
android:layout_width="48dp"
android:layout_height="48dp" />
</LinearLayout>
<io.timelimit.android.ui.view.KeyboardView
android:visibility="@{showCustomKeyboard ? View.VISIBLE : View.GONE}"
android:id="@+id/keyboard"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />