Я хочу использовать двустороннюю привязку данных с компонентами Android LiveData
(в качестве альтернативы наблюдаемым полям. Вот код для простого проекта с CalendarView
и EditText
, который отображает обе информации при нажатии кнопки.
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="testDate"
type="android.arch.lifecycle.MutableLiveData<Long>" />
<variable
name="testString"
type="android.arch.lifecycle.MutableLiveData<String>" />
</data>
<LinearLayout 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="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onButtonClick"
android:text="Show data"/>
<CalendarView
android:id="@+id/cal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:date="@={testDate}"/>
<EditText
android:id="@+id/str"
android:text="@={testString}"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</layout>
И код активности:
class MainActivity : AppCompatActivity() {
val liveDate = MutableLiveData<Long>().apply { value = System.currentTimeMillis() }
val liveString = MutableLiveData<String>().apply { value = "Date: " }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
.also {
it.testDate = liveDate
it.testString = liveString
it.cal.setOnDateChangeListener { view, year, month, dayOfMonth ->
Toast.makeText(applicationContext, "${view.date}", Toast.LENGTH_SHORT).show()
}
}
}
@TargetApi(Build.VERSION_CODES.O)
fun onButtonClick(view: View) {
Toast.makeText(this, liveString.value +
Instant.ofEpochMilli(liveDate.value!!).atZone(ZoneId.systemDefault()).toLocalDate()
, Toast.LENGTH_SHORT)
.show()
}
}
Двусторонняя привязка отлично работает для String, но не для даты. Я нашел этот пост , в котором говорится, что выбранная дата на самом деле отличается от даты, используемой android:date
... Достаточно честно, вы можете зафиксировать это действие по изменению даты в прослушивателе. Проблема в том, что прослушиватель setOnDateChangeListener
(примененный в also {}
выше) вообще не запускается, когда есть настройка двусторонней привязки.
Поправьте меня, если я ошибаюсь, но если я хочу получить выбранную дату, я должен использовать OnDateChangeListener
. Он также кажется несовместимым с android:date@={...}
, потому что использование двусторонней привязки переопределяет наш слушатель. Было бы разумно, если бы android:date@={...}
обеспечивал ту же функциональность, что и OnDateChangeListener
, но это не так.
Итак, последний вопрос: можно ли как-то получить выбранную дату с помощью двусторонней привязки данных?