【发布时间】:2019-10-27 06:03:34
【问题描述】:
我正在使用绑定适配器在我的一个视图中包含可变文本。我相信我已经正确实现了它(并且它在其他地方工作),但是对于 mutableText 的情况,它得到了错误AAPT: error: attribute mutableText not found
我在这里查看了其他一些答案,但没有一个能够解决问题。
这是我的布局文件:
<?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="viewModel"
type="com.example.nhlstats.ui.game.GameViewModel" />
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/awayTeam"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="12dp">
<ImageView
android:id="@+id/awayTeamLogo"
android:layout_height="48dp"
android:layout_width="0dp"
android:layout_weight="1"
tools:src="@drawable/ic_launcher_background"/>
<TextView
android:id="@+id/awayTeamName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:layout_gravity="center_vertical"
app:mutableText="@{viewModel.getAwayTeamName()}"
tools:text="CHI Blackhawks"/>
<TextView
android:id="@+id/awayScore"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
app:mutableText="@{viewModel.getAwayTeamScore().toString()}"
tools:text="0"/>
<TextView
android:id="@+id/gameTime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
app:mutableText="@{viewModel.getTimeRemaining()"
tools:text="14:26 3rd"/>
</LinearLayout>
<LinearLayout
android:id="@+id/homeTeam"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp">
<ImageView
android:id="@+id/homeTeamLogo"
android:layout_height="48dp"
android:layout_width="0dp"
android:layout_weight="1"
tools:src="@drawable/ic_launcher_background"/>
<TextView
android:id="@+id/homeTeamName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:layout_gravity="center_vertical"
app:mutableText="@{viewModel.getHomeTeamName()}"
tools:text="CAR Hurricanes"/>
<TextView
android:id="@+id/homeScore"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
app:mutableText="@{viewModel.getHomeTeamScore().toString()}"
tools:text="4"/>
</LinearLayout>
</LinearLayout>
</layout>
还有我的 BindingAdpater 函数:
@BindingAdapter("mutableText")
fun setMutableText(view: TextView, text: MutableLiveData<String>?) {
val parentActivity:AppCompatActivity? = view.getParentActivity()
if (parentActivity != null && text != null) {
text.observe(parentActivity, Observer { value ->
view.text = value?:""
})
}
}
游戏视图模型:
class GameViewModel:BaseViewModel() {
private val awayTeamName = MutableLiveData<String>()
private val homeTeamName = MutableLiveData<String>()
private val awayTeamScore = MutableLiveData<Int>()
private val homeTeamScore = MutableLiveData<Int>()
private val timeRemaining = MutableLiveData<String>()
fun bind(response: Game) {
awayTeamName.value = response.gameData.teams.get(0).name
homeTeamName.value = response.gameData.teams.get(1).name
awayTeamScore.value = response.liveData.linescore.teams.get(1).goals
homeTeamScore.value = response.liveData.linescore.teams.get(0).goals
timeRemaining.value = response.liveData.linescore.currentPeriodOrdinal + " " + response.liveData.linescore.currentPeriodTimeRemaining
}
fun getAwayTeamName(): MutableLiveData<String> {
return awayTeamName
}
fun getHomeTeamName(): MutableLiveData<String> {
return homeTeamName
}
fun getAwayTeamScore(): MutableLiveData<Int> {
return awayTeamScore
}
fun getHomeTeamScore(): MutableLiveData<Int> {
return homeTeamScore
}
fun getTimeRemaining(): MutableLiveData<String> {
return timeRemaining
}
}
主活动:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel: GameListViewModel
private var errorSnackbar: Snackbar? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.gameList.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
viewModel = ViewModelProviders.of(this).get(GameListViewModel::class.java)
viewModel.errorMessage.observe(this, Observer { errorMessage ->
if (errorMessage != null)
showError(errorMessage)
else
hideError()
})
binding.viewModel = viewModel
}
private fun showError(@StringRes errorMessage:Int) {
errorSnackbar = Snackbar.make(binding.root, errorMessage, Snackbar.LENGTH_INDEFINITE)
errorSnackbar?.setAction(R.string.retry, viewModel.errorClickListener)
errorSnackbar?.show()
}
private fun hideError() {
errorSnackbar?.dismiss()
}
}
提前致谢。
【问题讨论】:
-
1.为什么需要 TextView + MutableLiveData 的自定义绑定适配器?您可以直接将 LiveData 分配给 XML 中的 TextView,例如
android:text="@{viewModel.getHomeTeamScore}",它应该可以工作 2. 您是否将setMutableText放入companion object和@JvmStatic -
1.我这样做是为了支持再次调用 API 时可能更改的数据,您的建议是否也支持这一点? 2. 我没有,但是我没有对 bindingadapter 中的其他绑定执行此操作,并且它们工作正常
-
是的,每当您的数据发生变化时,例如您通过API收到新数据,只需再次调用
MutableLiveData的setValue(),它就会自动反映。您能否也添加您的GameViewModel代码? -
我在上面添加了GameViewModel代码。我检查了 ActivityMainBindingImpl(生成的类),只有 setMutableVisibility 和 setAdapter 被使用(生成),setMutableText 没有,并表明 setMutableText 函数没有在任何地方使用
标签: android kotlin android-databinding