Open k-kagurazaka opened 7 years ago
I have the same issue. @k-kagurazaka you found solution?
I use org.jetbrains.anko:anko-design:0.9.1
For example, simple code
class ActivityComponent : AnkoComponent<Activity> {
override fun createView(ui: AnkoContext<Activity>): View = with(ui) {
textInputLayout {
editText().lparams(width = matchParent)
}
}
}
throw java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.FrameLayout$LayoutParams
I use version:0.10.0-beta-1, throw java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.FrameLayout$LayoutParams
textInputLayout {
emailView = autoCompleteTextView {
hintResource = R.string.prompt_email
inputType = InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
maxLines = 1
}.lparams(width = matchParent)
}.lparams(width = matchParent)
I overrode the textInputLayout also and it solved the problem:
inline fun ViewManager.appCompatEditText(theme: Int = 0, init: AppCompatEditText.() -> Unit) = ankoView(::AppCompatEditText, theme, init)
inline fun ViewManager.textInputLayout(theme: Int = 0, init: TextInputLayout.() -> Unit) = ankoView(::TextInputLayout, theme, init)
@jonathanrz Could you please elaborate ? Why does this work ?
@Rahulkr2 actually I don't know. I can only think that the TextInputLayout that the native anko function textInputLayout creates is different from the TextInputLayout from android support library.
Reason for ClassCastException
=> setting layout params via anko's lparams
sets the params only after the view is added to its parent. While this works out for other ViewGroup
s, it doesn't work while adding an EditText
to a TextInputLayout
(which by itself is a LinearLayout
) because of its addView
method
@Override
public void addView(View child, int index, final ViewGroup.LayoutParams params) {
if (child instanceof EditText) {
// Make sure that the EditText is vertically at the bottom, so that it sits on the
// EditText's underline
FrameLayout.LayoutParams flp = new FrameLayout.LayoutParams(params);
flp.gravity = Gravity.CENTER_VERTICAL | (flp.gravity & ~Gravity.VERTICAL_GRAVITY_MASK);
mInputFrame.addView(child, flp);
// Now use the EditText's LayoutParams as our own and update them to make enough space
// for the label
mInputFrame.setLayoutParams(params);
updateInputLayoutMargins();
setEditText((EditText) child);
} else {
// Carry on adding the View...
super.addView(child, index, params);
}
}
As we can see from the implementation, instead of adding the child which is an EditText
to itself, it is instead added to a FrameLayout
(mInputFrame
). When params are set via lparams
for the EditText
added to TextInputLayout
, it creates an instance of LinearLayout.LayoutParams
& sets it on the view (which by now lives inside a FrameLayout
). During the measure pass, FrameLayout
assumes that all its children are going to have valid FrameLayout.LayoutParams
& so tries to cast but it blows up with an exception
Setting layoutParams this way works:
textInputLayout {
editText {
layoutParams = LinearLayout.LayoutParams(matchParent, wrapContent)
}
}
Why would you set lparams
on the editText
? The idea of the TextInputLayout
is to hold an EditText
, so you should set lparams
on the textInpuLayout
instead of the editText
.
Doing it this way you get no crashes.
pwdLayout = textInputLayout {
isPasswordVisibilityToggleEnabled = true
pwdEditText = editText {
inputType = TYPE_CLASS_TEXT or TYPE_TEXT_VARIATION_PASSWORD
hint = resources.getString(R.string.login_dialog_password_hint)
}
}.lparams(matchParent, wrapContent){
marginEnd = dip(24)
marginStart = dip(24)
bottomMargin = dip(8)
}
I found an issue that the below code throw
java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.FrameLayout$LayoutParams
:However the below code works well:
In my understanding, both codes roughly the same, what's happen? The issue is occurred when using Support Library version >= v 24.2.0.
Thanks.