Reputation: 4350
I have a custom view with three controls inside (an ImageView
, a TextInputLayout
and a TextInputEditText
) and would like to delegate attributes of the xml tags for my custom views to the corresponding views inside of my custom view. Is it possible to have my custom view accept an android:text = "Some string" xml tag and then make it show the string in the corresponding TextInputEditText
inside my custom view?
My custom view (InputView.kt):
class InputView(context: Context, attrs: AttributeSet?, @AttrRes defStyleAttr: Int) : ConstraintLayout(context, attrs, defStyleAttr) {
private lateinit var textInputLayout: TextInputLayout
private lateinit var textView: TextInputEditText
private lateinit var imageView: ImageView
// var drawableRes = imageView.drawable ?: 0
var text = textView.text
var hint = textInputLayout.hint
var error = textInputLayout.error
var helperText = textInputLayout.helperText
var ellipsize = textView.ellipsize ?: null
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
init {
val view = LayoutInflater.from(context).inflate(R.layout.custom_inputview, this, true)
textInputLayout = view.custom_inputview_text_input_layout
textView = view.custom_inputview_text_input_edit_text
imageView = view.custom_inputview_image_view
attrs.let {
context.theme.obtainStyledAttributes(
attrs,
R.styleable.InputView,
0, 0).apply {
try {
// mShowText = getString(R.styleable.InputView_text)
} finally {
recycle()
}
}
}
}
}
Layout file for the view (custom_inputview.xml):
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:parentTag="com.lucasurbas.masterdetail.ui.persondetails.InputView"
tools:ignore="ContentDescription">
<ImageView
android:id="@+id/custom_inputview_image_view"
android:layout_width="40dp"
android:layout_height="40dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:tint="@color/bg_action_mode"
tools:src="@drawable/ic_vd_hospital_24dp"/>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/custom_inputview_text_input_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
app:layout_constraintBottom_toBottomOf="@+id/custom_inputview_image_view"
app:layout_constraintStart_toEndOf="@+id/custom_inputview_image_view"
app:layout_constraintTop_toTopOf="@+id/custom_inputview_image_view">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/custom_inputview_text_input_edit_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:hint="Department"/>
</com.google.android.material.textfield.TextInputLayout>
</merge>
Upvotes: 1
Views: 1406
Reputation: 4350
To help others here's my working solution.
class InputView(context: Context, attrs: AttributeSet?, @AttrRes defStyleAttr: Int) : ConstraintLayout(context, attrs, defStyleAttr) {
private var textInputLayout: TextInputLayout
private var textView: TextInputEditText
private var imageView: ImageView
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
init {
val view = LayoutInflater.from(context).inflate(R.layout.custom_inputview, this, true)
textInputLayout = view.custom_inputview_text_input_layout
textView = view.custom_inputview_text_input_edit_text
imageView = view.custom_inputview_image_view
attrs.let {
context.theme.obtainStyledAttributes(
it,
R.styleable.InputView,
defStyleAttr, 0).apply {
try {
textView.setText(getText(R.styleable.InputView_android_text))
textInputLayout.hint = getText(R.styleable.InputView_android_hint)
Log.d("InputView", "attrs " + textView.text)
} finally {
recycle()
}
}
}
}
}
With the attributes defined in attr.xml:
<declare-styleable name="InputView">
<attr name="android:text" format="string" />
<attr name="android:hint" format="string"/>
</declare-styleable>
Upvotes: 1
Reputation: 2362
If you want to just use the android style attributes you could do something like the following.
In this example it should pick up the text attribute if you defined it in the xml when creating the InputView.
init {
attrs?.let {
val typedArray = context.obtainStyledAttributes(attrs, STYLE_ATTRIBUTES)
val text = typedArray.getText(0)
typedArray.recycle()
}
}
companion object {
private val STYLE_ATTRIBUTES = intArrayOf(
android.R.attr.text
)
}
Upvotes: 1