aboutsummaryrefslogtreecommitdiff
path: root/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CustomVirtualView.kt
diff options
context:
space:
mode:
Diffstat (limited to 'input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CustomVirtualView.kt')
-rw-r--r--input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CustomVirtualView.kt186
1 files changed, 86 insertions, 100 deletions
diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CustomVirtualView.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CustomVirtualView.kt
index c737fe4c..36c43439 100644
--- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CustomVirtualView.kt
+++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CustomVirtualView.kt
@@ -21,7 +21,6 @@ import android.graphics.Color
import android.graphics.Paint
import android.graphics.Paint.Style
import android.graphics.Rect
-import android.text.TextUtils
import android.util.AttributeSet
import android.util.Log
import android.util.SparseArray
@@ -32,6 +31,7 @@ import android.view.autofill.AutofillManager
import android.view.autofill.AutofillValue
import android.widget.EditText
import android.widget.TextView
+import com.example.android.autofillframework.CommonUtil.TAG
import com.example.android.autofillframework.CommonUtil.bundleToString
import com.example.android.autofillframework.R
import java.util.Arrays
@@ -42,33 +42,30 @@ import java.util.Arrays
*/
class CustomVirtualView(context: Context, attrs: AttributeSet) : View(context, attrs) {
- private val mLines = ArrayList<Line>()
- private val mItems = SparseArray<Item>()
- private val mAfm: AutofillManager = context.getSystemService(AutofillManager::class.java)
-
- private var mFocusedLine: Line? = null
- private val mTextPaint: Paint = Paint()
- private val mTextHeight: Int = 90
- private val mTopMargin: Int = 100
- private val mLeftMargin: Int = 100
- private val mVerticalGap: Int = 10
- private val mLineLength: Int = mTextHeight + mVerticalGap
- private val mFocusedColor: Int = Color.RED
- private val mUnfocusedColor: Int = Color.BLACK
-
- private val mUsernameLine: Line
- private val mPasswordLine: Line
-
- init {
- mTextPaint.style = Style.FILL
- mTextPaint.textSize = mTextHeight.toFloat()
- mUsernameLine = addLine("usernameField", context.getString(R.string.username_label),
- arrayOf(View.AUTOFILL_HINT_USERNAME), " ", true)
- mPasswordLine = addLine("passwordField", context.getString(R.string.password_label),
- arrayOf(View.AUTOFILL_HINT_PASSWORD), " ", false)
-
- Log.d(TAG, "Text height: " + mTextHeight)
+ val usernameText: CharSequence
+ get() = usernameLine.fieldTextItem.text
+ val passwordText: CharSequence
+ get() = passwordLine.fieldTextItem.text
+ private var nextId: Int = 0
+ private val lines = ArrayList<Line>()
+ private val items = SparseArray<Item>()
+ private val autofillManager = context.getSystemService(AutofillManager::class.java)
+ private var focusedLine: Line? = null
+ private val textHeight = 90
+ private val textPaint = Paint().apply {
+ style = Style.FILL
+ textSize = textHeight.toFloat()
}
+ private val topMargin = 100
+ private val leftMargin = 100
+ private val verticalGap = 10
+ private val lineLength = textHeight + verticalGap
+ private val focusedColor = Color.RED
+ private val unfocusedColor = Color.BLACK
+ private val usernameLine = addLine("usernameField", context.getString(R.string.username_label),
+ arrayOf(View.AUTOFILL_HINT_USERNAME), " ", true)
+ private val passwordLine = addLine("passwordField", context.getString(R.string.password_label),
+ arrayOf(View.AUTOFILL_HINT_PASSWORD), " ", false)
override fun autofill(values: SparseArray<AutofillValue>) {
// User has just selected a Dataset from the list of autofill suggestions.
@@ -76,15 +73,15 @@ class CustomVirtualView(context: Context, attrs: AttributeSet) : View(context, a
// to fill a specific autofillable view. Now we have to update the UI based on the
// AutofillValues in the list.
Log.d(TAG, "autofill(): " + values)
- for (i in 0..values.size() - 1) {
+ for (i in 0 until values.size()) {
val id = values.keyAt(i)
val value = values.valueAt(i)
- mItems[id]?.let { item ->
- if (item.editable) {
+ items[id]?.apply {
+ if (editable) {
// Set the item's text to the text wrapped in the AutofillValue.
- item.text = value.textValue
+ text = value.textValue
} else {
- Log.w(TAG, "Item for autofillId $id is not editable: $item")
+ Log.w(TAG, "Item for autofillId $id is not editable: $this")
}
}
}
@@ -94,24 +91,23 @@ class CustomVirtualView(context: Context, attrs: AttributeSet) : View(context, a
override fun onProvideAutofillVirtualStructure(structure: ViewStructure, flags: Int) {
// Build a ViewStructure to pack in AutoFillService requests.
structure.setClassName(javaClass.name)
- val childrenSize = mItems.size()
+ val childrenSize = items.size()
Log.d(TAG, "onProvideAutofillVirtualStructure(): flags = " + flags + ", items = "
+ childrenSize + ", extras: " + bundleToString(structure.extras))
var index = structure.addChildCount(childrenSize)
- for (i in 0..childrenSize - 1) {
- val item = mItems.valueAt(i)
+ for (i in 0 until childrenSize) {
+ val item = items.valueAt(i)
Log.d(TAG, "Adding new child at index $index: $item")
- val child = structure.newChild(index)
- child.setAutofillId(structure.getAutofillId(), item.id)
- child.setAutofillHints(item.hints)
- child.setAutofillType(item.type)
- child.setDataIsSensitive(!item.sanitized)
- if (TextUtils.getTrimmedLength(item.text) > 0) {
- child.setAutofillValue(AutofillValue.forText(item.text))
+ structure.newChild(index).apply {
+ setAutofillId(structure.autofillId, item.id)
+ setAutofillHints(item.hints)
+ setAutofillType(item.type)
+ setDataIsSensitive(!item.sanitized)
+ setAutofillValue(AutofillValue.forText(item.text))
+ setFocused(item.focused)
+ setId(item.id, context.packageName, null, item.line.idEntry)
+ setClassName(item.className)
}
- child.setFocused(item.focused)
- child.setId(item.id, context.packageName, null, item.line.idEntry)
- child.setClassName(item.className)
index++
}
}
@@ -119,74 +115,71 @@ class CustomVirtualView(context: Context, attrs: AttributeSet) : View(context, a
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
- Log.d(TAG, "onDraw: " + mLines.size + " lines; canvas:" + canvas)
+ Log.d(TAG, "onDraw: " + lines.size + " lines; canvas:" + canvas)
var x: Float
- var y = (mTopMargin + mLineLength).toFloat()
- for (line in mLines) {
- x = mLeftMargin.toFloat()
- Log.v(TAG, "Drawing '" + line + "' at " + x + "x" + y)
- mTextPaint.color = if (line.fieldTextItem.focused) mFocusedColor else mUnfocusedColor
- val readOnlyText = line.labelItem.text.toString() + ": ["
- val writeText = line.fieldTextItem.text.toString() + "]"
+ var y = (topMargin + lineLength).toFloat()
+
+ lines.forEach {
+ x = leftMargin.toFloat()
+ Log.v(TAG, "Drawing $it at x=$x, y=$y")
+ textPaint.color = if (it.fieldTextItem.focused) focusedColor else unfocusedColor
+ val readOnlyText = it.labelItem.text.toString() + ": ["
+ val writeText = it.fieldTextItem.text.toString() + "]"
// Paints the label first...
- canvas.drawText(readOnlyText, x, y, mTextPaint)
+ canvas.drawText(readOnlyText, x, y, textPaint)
// ...then paints the edit text and sets the proper boundary
- val deltaX = mTextPaint.measureText(readOnlyText)
+ val deltaX = textPaint.measureText(readOnlyText)
x += deltaX
- line.bounds.set(x.toInt(), (y - mLineLength).toInt(),
- (x + mTextPaint.measureText(writeText)).toInt(), y.toInt())
- Log.d(TAG, "setBounds(" + x + ", " + y + "): " + line.bounds)
- canvas.drawText(writeText, x, y, mTextPaint)
- y += mLineLength.toFloat()
+ it.bounds.set(x.toInt(), (y - lineLength).toInt(),
+ (x + textPaint.measureText(writeText)).toInt(), y.toInt())
+ Log.d(TAG, "setBounds(" + x + ", " + y + "): " + it.bounds)
+ canvas.drawText(writeText, x, y, textPaint)
+ y += lineLength.toFloat()
}
}
override fun onTouchEvent(event: MotionEvent): Boolean {
val y = event.y.toInt()
- Log.d(TAG, "Touched: y=$y, range=$mLineLength, top=$mTopMargin")
- var lowerY = mTopMargin
+ Log.d(TAG, "Touched: y=$y, range=$lineLength, top=$topMargin")
+ var lowerY = topMargin
var upperY = -1
- for (i in mLines.indices) {
- upperY = lowerY + mLineLength
- val line = mLines[i]
- Log.d(TAG, "Line $i ranges from $lowerY to $upperY")
- if (lowerY <= y && y <= upperY) {
- Log.d(TAG, "Removing focus from " + mFocusedLine)
- mFocusedLine?.changeFocus(false)
+ for (line in lines) {
+ upperY = lowerY + lineLength
+ Log.d(TAG, "Line $line ranges from $lowerY to $upperY")
+ if (y in lowerY..upperY) {
+ Log.d(TAG, "Removing focus from " + focusedLine)
+ focusedLine?.changeFocus(false)
Log.d(TAG, "Changing focus to " + line)
- mFocusedLine = line
- mFocusedLine?.changeFocus(true)
+ focusedLine = line.apply { changeFocus(true) }
invalidate()
break
}
- lowerY += mLineLength
+ lowerY += lineLength
}
return super.onTouchEvent(event)
}
- val usernameText: CharSequence
- get() = mUsernameLine.fieldTextItem.text
-
- val passwordText: CharSequence
- get() = mPasswordLine.fieldTextItem.text
-
fun resetFields() {
- mUsernameLine.reset()
- mPasswordLine.reset()
+ usernameLine.reset()
+ passwordLine.reset()
postInvalidate()
}
- private fun addLine(idEntry: String, label: String, hints: Array<String>, text: String, sanitized: Boolean): Line {
- val line = Line(idEntry, label, hints, text, sanitized)
- mLines.add(line)
- mItems.put(line.labelItem.id, line.labelItem)
- mItems.put(line.fieldTextItem.id, line.fieldTextItem)
- return line
+ private fun addLine(idEntry: String, label: String, hints: Array<String>, text: String,
+ sanitized: Boolean) = Line(idEntry, label, hints, text, sanitized).also {
+ lines.add(it)
+ items.apply {
+ put(it.labelItem.id, it.labelItem)
+ put(it.fieldTextItem.id, it.fieldTextItem)
+ }
}
- private class Item internal constructor(val line: Line, val id: Int, val hints: Array<String>?,
- val type: Int, var text: CharSequence,
- val editable: Boolean, val sanitized: Boolean) {
+ private inner class Item internal constructor(
+ val line: Line,
+ val id: Int,
+ val hints: Array<String>?,
+ val type: Int, var text: CharSequence, val editable: Boolean,
+ val sanitized: Boolean) {
var focused = false
override fun toString(): String {
@@ -213,15 +206,15 @@ class CustomVirtualView(context: Context, attrs: AttributeSet) : View(context, a
if (focused) {
val absBounds = absCoordinates
Log.d(TAG, "focus gained on " + fieldTextItem.id + "; absBounds=" + absBounds)
- mAfm.notifyViewEntered(this@CustomVirtualView, fieldTextItem.id, absBounds)
+ autofillManager.notifyViewEntered(this@CustomVirtualView, fieldTextItem.id, absBounds)
} else {
Log.d(TAG, "focus lost on " + fieldTextItem.id)
- mAfm.notifyViewExited(this@CustomVirtualView, fieldTextItem.id)
+ autofillManager.notifyViewExited(this@CustomVirtualView, fieldTextItem.id)
}
}
- private // Must offset the boundaries so they're relative to the CustomView.
- val absCoordinates: Rect
+ private val absCoordinates: Rect
+ // Must offset the boundaries so they're relative to the CustomView.
get() {
val offset = IntArray(2)
getLocationOnScreen(offset)
@@ -242,11 +235,4 @@ class CustomVirtualView(context: Context, attrs: AttributeSet) : View(context, a
fieldTextItem.focused
}
}
-
- companion object {
-
- private val TAG = "CustomView"
-
- private var nextId: Int = 0
- }
} \ No newline at end of file