我在应用程序中使用遵循MVP模式的 Android 数据绑定库。谈话中中,有以下与事件处理程序一起使用的表达式示例:
\n\n<Button android:onClick="@{isAdult ? handlers.adultClick : handlers.childClick}" \xe2\x80\xa6/>\nRun Code Online (Sandbox Code Playgroud)\n\n有没有什么方法可以不使用方法引用而是使用侦听器绑定来具有相同的功能(即根据条件不同的“onClick”事件)?或者也许我的方法完全错误,逻辑应该转移给演示者?
\n当我尝试使用地图为标记片段添加可见性时,我遇到了数据绑定问题:
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<data>
<import type="android.view.View"/>
<import type="xxx.xxx.MapContract.ViewModel"/>
<variable
name="vm"
type="ViewModel"
/>
</data>
<FrameLayout
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<fragment
android:id="@+id/map_fragment"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="@{vm.showMap}" // here problem
/>
Run Code Online (Sandbox Code Playgroud)
如何使用数据绑定解决这个问题?为什么片段不支持数据绑定?
我正在尝试绑定以下元素:
xml:
<android.support.v7.widget.SwitchCompat
...
bind:onCheckedChanged="@{(isChecked) -> viewModel.onCheckedChanged(isChecked)}"
.../>
Run Code Online (Sandbox Code Playgroud)
视图模型:
class MyViewModel() {
fun onCheckedChanged(isChecked: Boolean) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
使用 BindingAdapter:
@BindingAdapter("onCheckedChanged")
fun bindOnCheckedChanged(view: SwitchCompat, onCheckedChanged: (Boolean) -> Unit) {
view.setOnCheckedChangeListener(
{ _, isChecked ->
if (view.isPressed) onCheckedChanged(isChecked)
}
)
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是这个:
数据绑定错误****msg:在类 MyViewModel 中找不到方法 onCheckedChanged(java.lang.Object)
数据绑定器似乎无法识别isChecked为Boolean. 我试图强制在 xml 中输入,isChecked:Boolean但我收到了一堆不同的错误。
现在我通过使用Any而不是让它工作,Boolean但我觉得这是错误的:
@BindingAdapter("onCheckedChanged")
fun bindOnCheckedChanged(view: SwitchCompat, onCheckedChanged: (Any) -> Unit) {
...
Run Code Online (Sandbox Code Playgroud)
和
fun onCheckedChanged(isChecked: Any) {
val isSwitchChecked = isChecked …Run Code Online (Sandbox Code Playgroud) 我有一个活动,CoordinatorLayout其中包含一个CollapsingToolbarLayout. 我已将活动的标题绑定到 的title属性CollapsingToolbarLayout,如下所示(由于布局太大,仅发布代码的相关部分):
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable name="viewModel"
type="com.android.myapp.ui.activity.home.HomeActivityViewModel"/>
</data>
<RelativeLayout 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">
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="com.android.myapp.ui.behavior.scroll.appbar.DisableableAppBarLayoutBehavior"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:title="@{viewModel.pageTitle}"
app:collapsedTitleTextAppearance="@style/CollapsedAppBarTitleStyle"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="bottom|center_horizontal"
app:expandedTitleMarginBottom="85dp"
app:expandedTitleTextAppearance="@style/ExpandedAppBarTitleStyle"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<!--Remaining layout-->
</layout>
Run Code Online (Sandbox Code Playgroud)
如您所见,该pageTitle属性绑定到 xmlCollapsingToolbarLayout title属性。
现在在HomeActivityViewModel:
class HomeActivityViewModel(application: Application) : AndroidViewModel(application) {
var isToolbarExpandable = MutableLiveData<Boolean>() // For handling the …Run Code Online (Sandbox Code Playgroud) android android-databinding android-livedata android-viewmodel android-architecture-components
我第一次尝试在 kotlin 中实现 mvvm 和数据绑定。我遵循了一些教程并能够实现相同的。但是现在我在 mvvm 中编写的按钮单击不起作用。
这是activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewmodel"
type="com.abc.abc.presentation.user.viewmodels.LoginViewModel"/>
</data>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.user.views.LoginActivity"
android:layout_margin="24dip">
<Button
android:layout_width="match_parent"
android:layout_height="40dip"
android:background="@drawable/btn_user_create_account"
android:layout_above="@+id/or_layout"
android:layout_marginBottom="24dp"
android:text="@string/create_account"
android:id="@+id/btn_create_account"
android:layout_marginEnd="12dip"
android:layout_marginStart="12dip"
android:gravity="center_horizontal|center_vertical"
android:textColor="@color/text_color"
android:textAllCaps="false"
android:onClick="@{() -> viewmodel.redirectToRegisterActivity()}"
android:fontFamily="@font/vollkron"
android:textStyle="bold"
/>
<Button
android:layout_width="match_parent"
android:layout_height="40dip"
android:background="@drawable/btn_user_login_reg"
android:layout_above="@+id/btn_create_account"
android:layout_marginBottom="12dp"
android:text="@string/login"
android:id="@+id/btn_login"
android:layout_marginEnd="12dip"
android:layout_marginStart="12dip"
android:gravity="center_horizontal|center_vertical"
android:textColor="@color/white"
android:textAllCaps="false"
android:onClick="@{() -> viewmodel.executeEmailLogin(context)}"
android:fontFamily="@font/vollkron"
android:textStyle="bold"/>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
这是我的 ViewModel 代码:
class LoginViewModel(application: Application) : AndroidViewModel(application) {
var email: ObservableField<String>? = null
var password: ObservableField<String>? …Run Code Online (Sandbox Code Playgroud) 我想在我的 android 应用程序中使用片段,但我无法FragmentTitleBinding在片段类中导入我在互联网上尝试了所有可能的解决方案
import com.example.android.navigation.databinding.FragmentTitleBinding
class TitleFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val binding : com.example.android.navigation.databinding.FragmentTitleBinding=
DataBindingUtil.inflate(inflater,R.layout.fragment_title,container,false)
return binding.root;
}
}
Run Code Online (Sandbox Code Playgroud)
片段 XML
<?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"
tools:context="com.example.android.navigation.TitleFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/titleConstraint"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/playButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/horizontal_margin"
android:layout_marginEnd="@dimen/horizontal_margin"
android:paddingStart="@dimen/button_padding"
android:paddingEnd="@dimen/button_padding"
android:text="Play"
android:textColor="@color/colorAccent"
android:textSize="@dimen/button_text_size"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleImage" />
<ImageView
android:id="@+id/titleImage"
android:layout_width="0dp"
android:layout_height="@dimen/image_header_height"
android:layout_marginStart="@dimen/horizontal_margin"
android:layout_marginEnd="@dimen/horizontal_margin"
android:scaleType="fitCenter"
app:layout_constraintBottom_toTopOf="@+id/playButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent" …Run Code Online (Sandbox Code Playgroud) 想象一个 StackOverflow 问题的列表,这些问题可以单独被赞成和反对。他们每个人都有一个计数,显示其投票数。单击 upvote 将该计数加一,单击 downvote 将该计数减一。这就是我要实现的目标的总体思路。rv_item.xmlRecyclerView 中单个项目的布局(为简洁起见):
data>
<variable
name="item"
type="com.mycodez.Item"/>
<variable
name="vm"
type="com.mycodez.ListViewModel" />
</data>
<Button
android:id="@+id/decrease_quantity"
android:onClick="@{() -> vm.decrementItemQuantity(item)}"/>
<TextView
android:id="@+id/quantity"
android:text="@{String.valueOf(item.quantity)}"
tools:text="1" />
<Button
android:id="@+id/increase_quantity"
android:onClick="@{() -> vm.incrementItemQuantity(item)}"/>
Run Code Online (Sandbox Code Playgroud)
Where@+id/decrease_quantity类似于downvote,@+id/quantity类似于投票计数,@+id/increase_quantity类似于upvote。适配器:
class ListRvAdapter extends RecyclerView.Adapter<ListRvAdapter.ViewHolder> {
private List<Item> items;
private ListViewModel viewModel;
private LifecycleOwner lifecycleOwner;
ListRvAdapter(List<Item> items, ListViewModel viewModel, LifecycleOwner lifecycleOwner) {
this.items = items;
this.viewModel = viewModel;
this.lifecycleOwner = lifecycleOwner;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int …Run Code Online (Sandbox Code Playgroud) android android-databinding android-livedata android-viewmodel
我想按LiveData原样传递给BindingAdapter.
在BindingAdapterI want to do a 中Transformations.map并显示用户可以选择的不同选项,并在单击时使用相同的LiveData.
为了观察LiveData在BindingAdapter我需要访问LifecycleOwner,片段视图的理想。如果我想调用.observeliveData 或设置LifecycleOwner我在BindingAdapter.
知道我该怎么做吗?
我是 DataBinding 的新手。我想在 Fragment 中使用 ViewModel 和 DataBinding。当我在 Activity 中使用时,它可以工作,但在 Fragment 中不起作用。请帮助使用数据绑定获取编辑文本内容。先感谢您。主活动.kt
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportFragmentManager.beginTransaction().add(R.id.main,BlankFragment()).commit()
}
}
Run Code Online (Sandbox Code Playgroud)
活动.main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/main"
tools:context=".MainActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)
空白片段.kt
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import com.resocoder.databinding.databinding.FragmentBlankBinding
class BlankFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val binding: FragmentBlankBinding = DataBindingUtil.inflate(inflater,
R.layout.fragment_blank, container, …Run Code Online (Sandbox Code Playgroud) 刚刚了解到DataBinding并发现toString()Kotlin的强大内置功能不可用:
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="student"
type="com.example.databindingtest2.Student" />
</data>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{student.name}"
android:textColor="@android:color/black"
android:textSize="30sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@{student.age.toString()}" //doesn't work, age is integer
android:textColor="@android:color/black"
android:textSize="30sp" />
</layout>
Run Code Online (Sandbox Code Playgroud)
我知道String.valueOf()会起作用,但这不是 Kotlin 的方式。任何帮助,将不胜感激。
android kotlin kotlin-extension android-databinding android-jetpack
android ×10
kotlin ×5
data-binding ×2
android-architecture-components ×1
fragment ×1
mvp ×1
mvvm ×1