我有一个自定义视图,该视图扩展了LinearLayout并放大了包含几个视图的Layout。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
xmlns:android="http://schemas.android.com/apk/res/android">
<EditText
android:id="@+id/voice_edittext"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:hint="Add answer here"
/>
<ImageButton
android:id="@+id/microphone_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_mic_black_24dp"
/>
<ImageButton
android:id="@+id/delete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_cancel_black_24dp"
android:visibility="gone"
/>
</LinearLayout>
现在,当我使用此视图时,我想双向绑定Edittext的文本值,如下所示:
<com.sunilson.quizcreator.presentation.views.EditTextWithVoiceInput
android:id="@+id/form_question"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
app:editTextValue="@={viewModel.observableText}"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
为此,我创建了一些绑定适配器
@BindingAdapter("editTextValueAttrChanged")
fun setListener(editTextWithVoiceInput: EditTextWithVoiceInput, listener: InverseBindingListener) {
editTextWithVoiceInput.voice_edittext.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
listener.onChange()
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
})
}
@BindingAdapter("editTextValue")
fun setTextValue(editTextWithVoiceInput: EditTextWithVoiceInput, value: String?) {
if (value != editTextWithVoiceInput.voice_edittext.text.toString()) editTextWithVoiceInput.voice_edittext.setText(value)
}
@InverseBindingAdapter(attribute = "editTextValue")
fun getTextValue(editTextWithVoiceInput: EditTextWithVoiceInput): String? {
return editTextWithVoiceInput.voice_edittext.text.toString()
}
这是视图的代码:
class EditTextWithVoiceInput(context: Context, attributeSet: AttributeSet) : LinearLayout(context, attributeSet) {
init {
val inflater = context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val view = inflater.inflate(R.layout.voice_edittext, this, true)
view.microphone_button.setOnTouchListener { p0, p1 ->
...
}
}
}
现在的问题是,启动包含视图的Fragment时,出现此错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sunilson.quizcreator, PID: 12627
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.sunilson.quizcreator.presentation.views.EditTextWithVoiceInput.setTag(java.lang.Object)' on a null object reference
at com.sunilson.quizcreator.databinding.FragmentAddQuestionBinding.<init>(FragmentAddQuestionBinding.java:112)
at android.databinding.DataBinderMapperImpl.getDataBinder(DataBinderMapperImpl.java:15)
at android.databinding.DataBindingUtil.bind(DataBindingUtil.java:199)
at android.databinding.DataBindingUtil.inflate(DataBindingUtil.java:130)
at android.databinding.DataBindingUtil.inflate(DataBindingUtil.java:95)
at com.sunilson.quizcreator.presentation.SingleActivity.fragments.AddQuestionFragment.AddQuestionFragment.onCreateView(AddQuestionFragment.kt:34)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2425)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2623)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2410)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2365)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2272)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:733)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:180)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:835)
我在这里想念什么?
答案 0 :(得分:0)
好,所以我的问题是我的自定义视图错误地实现了构造函数。在用XML扩展此视图时,我需要一个构造函数,在该构造函数中我传递了Attributeset来将该属性集传递给超级构造函数,而我没有这样做。没有这些,我的视图就没有属性,也无法通过其ID等找到。
现在我有两个构造函数,具体取决于我是从XML还是从代码中膨胀:
constructor(context: Context, optional: Boolean) : super(context) {
...
}
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) {
...
}