Я столкнулся с проблемой, над которой я так долго работал, по крайней мере, 2 недели, и я был настолько ошеломлен, что через столько лет я как-то забыл, как работает привязка данных и как правильно настроить ее для "ПОЛНЫХ ВИДОВ",Я решил проверить это на очень простом проекте, чтобы изолировать его от моего текущего проекта.Очень простое приложение HelloWorld, которое в основном выводит Hello World на экран, используя привязку данных.Проект содержит следующие файлы:
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(LayoutInflater.from(this))
setContentView(binding.root)
binding.message = "Hello World!"
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="message" type="String" />
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.neonapps.android.sample.databinding.CustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<!-- Please take note I am data binding on my custom view -->
app:message="@{message}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
</layout>
А теперь вот самая важная часть проблемы.Это пользовательское представление CustomView
. Я хочу связать определенные данные 'String' с этим представлением, поэтому оно может выводить "Hello World" в этом CustomView:
class CustomView(context : Context, attrs : AttributeSet, defStyleAttrs : Int, defStylRes : Int) : RelativeLayout(context){
constructor(context : Context, attrs : AttributeSet) : this(context, attrs, 0, 0)
constructor(context : Context, attrs : AttributeSet, defStyleAttrs : Int) : this(context, attrs, defStyleAttrs, 0)
private var myMessage : String? = null
set(value){
value.let{
field = it
binding.message = field
}
}
private val binding : LayoutCustomViewBinding = LayoutCustomViewBinding.inflate(LayoutInflater.from(context), this, true)
init {
binding.message?.let{
binding.message = it
}
}
fun setMessage(message : String?){
myMessage = message
}
}
@BindingAdapter(value = ["message"])
fun setMessage(view : TextView, message : String?)
{
message?.let{
view.text = it
}
}
@BindingAdapter(value = ["message"])
fun setMessage(view : CustomView, message : String?)
{
message?.let{
view.message = it
}
}
Здесь подвох.Это CustomView
надувает представление, которое можно связать :
<?xml version="1.0" encoding="utf-8"?>
<layout
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">
<data>
<variable name="message" type="String" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:message="@{message}"
tools:text="Hello World"/>
</RelativeLayout>
</layout>
Так что я в основном привязываю a Строку к этому пользовательскому представлению (которое состоит (предположительно) из многих представлений)в его макете), как только я установил его снаружи, как activity_main.xml
выше.
activity_main.kt
<layout
...>
<data>
...
</data>
<android.support.constraint.ConstraintLayout
...>
<com.neonapps.android.sample.databinding.CustomView
...
<!-- Please take note I am data binding on my custom view -->
app:message="@{message}"
.../>
</android.support.constraint.ConstraintLayout>
</layout>
Как только я собрал весь проект, кажется, все работает нормально.Теперь я запускаю приложение и получаю следующую ошибку:
Attempt to invoke virtual method 'void ******.databinding.CustomView.setTag(java.lang.Object)' on a null object reference
at com.neonapps.android.sample.databinding.databinding.ActivityMainBindingImpl.<init>(ActivityMainBindingImpl.java:37)
at com.neonapps.android.sample.databinding.databinding.ActivityMainBindingImpl.<init>(ActivityMainBindingImpl.java:29)
at com.neonapps.android.sample.databinding.DataBinderMapperImpl.getDataBinder(DataBinderMapperImpl.java:44)
at android.databinding.MergedDataBinderMapper.getDataBinder(MergedDataBinderMapper.java:74)
at android.databinding.DataBindingUtil.bind(DataBindingUtil.java:199)
at android.databinding.DataBindingUtil.inflate(DataBindingUtil.java:130)
at com.neonapps.android.sample.databinding.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:49)
at com.neonapps.android.sample.databinding.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:43)
at *****.MainActivity.onCreate(MainActivity.kt:12)
at android.app.Activity.performCreate(Activity.java:6904)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1136)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3266)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415)
at android.app.ActivityThread.access$1100(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7406)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Мое приложение неожиданно падает, я внезапно впал в панику.Я просто больше не знаю основ DataBinding.Это прекрасно работает, когда я просто привязываю данные к представлениям, но мне не везет на связывание данных для моих собственных пользовательских представлений. Единственное, что сводит меня с ума, это то, что это приводит к сбою в коде, который генерируется автоматически.Я абсолютно не представляю, как он сгенерировал код, ссылающийся на ноль, который он сгенерировал, не присвоив ему ссылкуЯ сдаюсь, есть кое-что, что я сильно упустил.
Я определенно что-то упустил, и я не могу этого заметить.Я продолжал ссылаться на документы библиотеки DataBinding, но мне ничего не помогло.
Я пробовал этот код на
Android Studio: 3.4 Canary 7
Kotlin: 1.3.11
Android Studio: 3.2.1
Kotlin: 1.2.71
Сначала я подумал, что это может быть проблема, связанная с Kotlin / Build config / gradleДо тех пор, пока я не построю этот проект в стабильных средах, и они будут вести себя одинаково независимо.
Это мое проклятие.Любая помощь, чтобы уменьшить мои страдания будет принята с благодарностью!