mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Fix focus by manual view creation
This commit is contained in:
@@ -223,7 +223,12 @@ class EntryEditActivity : LockingActivity(),
|
||||
adapter = TemplatesSelectorAdapter(this@EntryEditActivity, mDatabase, templates)
|
||||
onItemSelectedListener = object: AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
entryEditFragment?.assignTemplate(templates[position])
|
||||
val newTemplate = templates[position]
|
||||
entryEditFragment?.apply {
|
||||
if (getTemplate() != newTemplate) {
|
||||
assignTemplate(newTemplate)
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
@@ -64,7 +63,7 @@ import kotlin.collections.LinkedHashMap
|
||||
|
||||
class EntryEditFragment : StylishFragment() {
|
||||
|
||||
private var mTemplate: Template? = null
|
||||
private var mTemplate: Template = Template.STANDARD
|
||||
|
||||
private var mInflater: LayoutInflater? = null
|
||||
|
||||
@@ -89,8 +88,6 @@ class EntryEditFragment : StylishFragment() {
|
||||
|
||||
// Elements to modify the current entry
|
||||
private var mEntryInfo = EntryInfo()
|
||||
private var mLastFocusedEditField: FocusedEditField? = null
|
||||
private var mExtraViewToRequestFocus: EditText? = null
|
||||
|
||||
// Current date time selection
|
||||
@IdRes
|
||||
@@ -148,14 +145,15 @@ class EntryEditFragment : StylishFragment() {
|
||||
mEntryInfo = savedInstanceState.getParcelable(KEY_TEMP_ENTRY_INFO) ?: mEntryInfo
|
||||
}
|
||||
|
||||
if (savedInstanceState?.containsKey(KEY_LAST_FOCUSED_FIELD) == true) {
|
||||
mLastFocusedEditField = savedInstanceState.getParcelable(KEY_LAST_FOCUSED_FIELD)
|
||||
?: mLastFocusedEditField
|
||||
if (savedInstanceState?.containsKey(KEY_TEMPLATE) == true) {
|
||||
mTemplate = savedInstanceState.getParcelable(KEY_TEMPLATE) ?: mTemplate
|
||||
}
|
||||
if (savedInstanceState?.containsKey(KEY_SELECTION_DATE_TIME_ID) == true) {
|
||||
mTempDateTimeViewId = savedInstanceState.getInt(KEY_SELECTION_DATE_TIME_ID)
|
||||
}
|
||||
|
||||
populateViewsWithEntry()
|
||||
|
||||
assignAttachments(mEntryInfo.attachments, StreamDirection.UPLOAD) { attachment ->
|
||||
onRemoveAttachment?.invoke(attachment)
|
||||
}
|
||||
@@ -204,6 +202,10 @@ class EntryEditFragment : StylishFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
fun getTemplate(): Template {
|
||||
return mTemplate
|
||||
}
|
||||
|
||||
fun assignTemplate(template: Template) {
|
||||
this.mTemplate = template
|
||||
populateViewsWithEntry()
|
||||
@@ -211,6 +213,10 @@ class EntryEditFragment : StylishFragment() {
|
||||
|
||||
private fun populateViewsWithEntry() {
|
||||
context?.let { context ->
|
||||
// Build each template section
|
||||
templateContainerView.removeAllViews()
|
||||
customFieldsContainerView.clear()
|
||||
mCustomFields.clear()
|
||||
|
||||
// Set info in view
|
||||
setIcon(mEntryInfo.icon)
|
||||
@@ -219,13 +225,8 @@ class EntryEditFragment : StylishFragment() {
|
||||
setValue(mEntryInfo.title, EntryEditFieldView.TextType.NORMAL)
|
||||
}
|
||||
|
||||
// Build each template section
|
||||
templateContainerView.removeAllViews()
|
||||
customFieldsContainerView.clear()
|
||||
mCustomFields.clear()
|
||||
|
||||
val customFieldsNotConsumed = ArrayList(mEntryInfo.customFields)
|
||||
mTemplate?.sections?.forEach { templateSection ->
|
||||
mTemplate.sections.forEach { templateSection ->
|
||||
|
||||
val sectionView = SectionView(context)
|
||||
|
||||
@@ -291,18 +292,6 @@ class EntryEditFragment : StylishFragment() {
|
||||
val fieldView = buildViewForCustomField(customDynamicField)
|
||||
customFieldsContainerView.addAttributeView(fieldView)
|
||||
}
|
||||
|
||||
/*
|
||||
// Request last focus
|
||||
mLastFocusedEditField?.let { focusField ->
|
||||
mExtraViewToRequestFocus?.apply {
|
||||
requestFocus()
|
||||
setSelection(focusField.cursorSelectionStart,
|
||||
focusField.cursorSelectionEnd)
|
||||
}
|
||||
}
|
||||
mLastFocusedEditField = null
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,9 +363,6 @@ class EntryEditFragment : StylishFragment() {
|
||||
templateAttribute.options.forEach { option ->
|
||||
// TODO options
|
||||
}
|
||||
if (mLastFocusedEditField?.field == field) {
|
||||
// TODO mExtraViewToRequestFocus = fieldTextView
|
||||
}
|
||||
applyFontVisibility(fontInVisibility)
|
||||
}
|
||||
}
|
||||
@@ -550,7 +536,6 @@ class EntryEditFragment : StylishFragment() {
|
||||
}
|
||||
|
||||
private fun getCustomFields(): List<Field> {
|
||||
// TODO focus ?
|
||||
return mCustomFields.map {
|
||||
getCustomField(it.key)
|
||||
}
|
||||
@@ -685,7 +670,7 @@ class EntryEditFragment : StylishFragment() {
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
populateEntryWithViews()
|
||||
outState.putParcelable(KEY_TEMP_ENTRY_INFO, mEntryInfo)
|
||||
outState.putParcelable(KEY_LAST_FOCUSED_FIELD, mLastFocusedEditField)
|
||||
outState.putParcelable(KEY_TEMPLATE, mTemplate)
|
||||
mTempDateTimeViewId?.let {
|
||||
outState.putInt(KEY_SELECTION_DATE_TIME_ID, it)
|
||||
}
|
||||
@@ -695,8 +680,8 @@ class EntryEditFragment : StylishFragment() {
|
||||
|
||||
companion object {
|
||||
const val KEY_TEMP_ENTRY_INFO = "KEY_TEMP_ENTRY_INFO"
|
||||
const val KEY_TEMPLATE = "KEY_TEMPLATE"
|
||||
const val KEY_DATABASE = "KEY_DATABASE"
|
||||
const val KEY_LAST_FOCUSED_FIELD = "KEY_LAST_FOCUSED_FIELD"
|
||||
const val KEY_SELECTION_DATE_TIME_ID = "KEY_SELECTION_DATE_TIME_ID"
|
||||
|
||||
private const val FIELD_USERNAME_TAG = "FIELD_USERNAME_TAG"
|
||||
|
||||
@@ -121,16 +121,5 @@ class Template : Parcelable {
|
||||
sections.add(mainSection)
|
||||
return Template(DatabaseVersioned.UUID_ZERO, "Standard", IconImage(), sections)
|
||||
}
|
||||
|
||||
fun isStandardFieldName(name: String): Boolean {
|
||||
return ArrayList<String>().apply {
|
||||
add(STANDARD_TITLE)
|
||||
add(STANDARD_USERNAME)
|
||||
add(STANDARD_PASSWORD)
|
||||
add(STANDARD_URL)
|
||||
add(STANDARD_EXPIRATION)
|
||||
add(STANDARD_NOTES)
|
||||
}.firstOrNull { it.equals(name, true) } != null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,23 +21,16 @@ class EntryEditFieldView @JvmOverloads constructor(context: Context,
|
||||
defStyle: Int = 0)
|
||||
: RelativeLayout(context, attrs, defStyle) {
|
||||
|
||||
private val labelViewId = ViewCompat.generateViewId()
|
||||
private val valueViewId = ViewCompat.generateViewId()
|
||||
private val actionImageButtonId = ViewCompat.generateViewId()
|
||||
private var labelViewId = ViewCompat.generateViewId()
|
||||
private var valueViewId = ViewCompat.generateViewId()
|
||||
private var actionImageButtonId = ViewCompat.generateViewId()
|
||||
|
||||
private val labelView = TextInputLayout(context).apply {
|
||||
id = labelViewId
|
||||
layoutParams = LayoutParams(
|
||||
LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.WRAP_CONTENT).also {
|
||||
it.addRule(LEFT_OF, actionImageButtonId)
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
it.addRule(START_OF, actionImageButtonId)
|
||||
}
|
||||
}
|
||||
LayoutParams.WRAP_CONTENT)
|
||||
}
|
||||
private val valueView = TextInputEditText(context).apply {
|
||||
id = valueViewId
|
||||
layoutParams = LinearLayout.LayoutParams(
|
||||
LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.WRAP_CONTENT)
|
||||
@@ -53,7 +46,6 @@ class EntryEditFieldView @JvmOverloads constructor(context: Context,
|
||||
}
|
||||
private var actionImageButton = AppCompatImageButton(
|
||||
ContextThemeWrapper(context, R.style.KeepassDXStyle_ImageButton_Simple), null, 0).apply {
|
||||
id = actionImageButtonId
|
||||
layoutParams = LayoutParams(
|
||||
LayoutParams.WRAP_CONTENT,
|
||||
LayoutParams.WRAP_CONTENT).also {
|
||||
@@ -73,11 +65,30 @@ class EntryEditFieldView @JvmOverloads constructor(context: Context,
|
||||
|
||||
init {
|
||||
// Manually write view to avoid view id bugs
|
||||
buildViews()
|
||||
labelView.addView(valueView)
|
||||
addView(labelView)
|
||||
addView(actionImageButton)
|
||||
}
|
||||
|
||||
private fun buildViews() {
|
||||
labelView.apply {
|
||||
id = labelViewId
|
||||
layoutParams = (layoutParams as LayoutParams?).also {
|
||||
it?.addRule(LEFT_OF, actionImageButtonId)
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
it?.addRule(START_OF, actionImageButtonId)
|
||||
}
|
||||
}
|
||||
}
|
||||
valueView.apply {
|
||||
id = valueViewId
|
||||
}
|
||||
actionImageButton.apply {
|
||||
id = actionImageButtonId
|
||||
}
|
||||
}
|
||||
|
||||
fun applyFontVisibility(fontInVisibility: Boolean) {
|
||||
if (fontInVisibility)
|
||||
valueView.applyFontVisibility()
|
||||
@@ -93,6 +104,11 @@ class EntryEditFieldView @JvmOverloads constructor(context: Context,
|
||||
}
|
||||
set(value) {
|
||||
labelView.hint = value
|
||||
// Define views Ids with label value
|
||||
labelViewId = "labelViewId $value".hashCode()
|
||||
valueViewId = "valueViewId $value".hashCode()
|
||||
actionImageButtonId = "actionImageButtonId $value".hashCode()
|
||||
buildViews()
|
||||
}
|
||||
|
||||
var value: String
|
||||
|
||||
@@ -43,7 +43,7 @@ class SectionView @JvmOverloads constructor(context: Context,
|
||||
}
|
||||
|
||||
fun addAttributeView(view: View?) {
|
||||
containerSectionView.postDelayed({
|
||||
//TODO containerSectionView.postDelayed({
|
||||
containerSectionView.apply {
|
||||
alpha = 0f
|
||||
visibility = View.VISIBLE
|
||||
@@ -53,7 +53,7 @@ class SectionView @JvmOverloads constructor(context: Context,
|
||||
.setDuration(200)
|
||||
.setListener(null)
|
||||
}
|
||||
}, 200)
|
||||
//}, 200)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
|
||||
Reference in New Issue
Block a user