【问题标题】:How to Get R.string in ViewModel Class of DataBinding in Android如何在Android中DataBinding的ViewModel类中获取R.string
【发布时间】:2017-10-10 12:19:13
【问题描述】:

我目前正在为我的 android 应用程序项目使用 databinding。我想从R.string.txtOldPassWordError 在我的CustomTextView 上设置error 消息,并从另一个名为ViewModelClass 的类中设置它。

这是我的 XML 代码

<com.horseproject.widget.CustomEditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:layout_marginTop="@dimen/dp_20"
    android:drawablePadding="@dimen/dp_10"
    android:hint="@string/enter_old_password"
    android:inputType="textPassword"
    android:lines="1"
    android:text="@={ChangePasswordVM.userOldPassword}"
    android:textColorHint="@color/gray_text"
    app:drawableLeftCompat="@drawable/ic_password_lock"
    app:drawableTintCompat="@color/gray_app"
    app:error="@{ChangePasswordVM.userOldPasswordError}" />

这是 ViewModelClass.java

public class ChangePasswordViewModel extends BaseObservable {

    public ObservableField<String> userOldPassword = new ObservableField<>("");

    public void userPasswordChange() {

        if ((TextUtils.isEmpty(userOldPassword.get()))) {
            userOldPasswordError.set("Please enter your old password");
            return;
        } else if (userOldPassword.get().length() <= 5) {
            userOldPasswordError.set("Password should contain minimum 6 characters");
            return;
        } else {
            userOldPasswordError.set(null);
        }
    }
}

这是来自strings.xml的字符串

<string name="select">Please Enter Old Password</string>

所以,我想在我的 viewModel 类中访问这个字符串并将其设置为错误消息而不是 hardcoded it directly as string

那么我该如何实现呢?我正在使用 Android Studio 3.0 测试版。任何帮助将不胜感激。

【问题讨论】:

  • getResources().getString(R.string.select);或参考此stackoverflow.com/questions/7493287/…
  • 我试过这个@SagarAghara,但说“无法解析方法'getResources'”,谢谢你的努力
  • 那是因为 getResources 需要上下文。您是否有机会使用 MVVM 架构。您不能通过构造函数从活动或片段中传递字符串吗?

标签: android data-binding textview


【解决方案1】:

创建ResourceProvider

public class ResourceProvider {

    private Context mContext;

    public ResourceProvider(Context mContext) {
        this.mContext = mContext;
    }

    public String getString(int resId) {
        return mContext.getString(resId);
    }

    public String getString(int resId, String value) {
        return mContext.getString(resId, value);
    }
}

现在转到您的ApplicationClass 并粘贴

public class YourAppName extends Application {
  // Resource Provider
    private ResourceProvider mResourceProvider;
    public ResourceProvider getResourceProvider() {
        if (mResourceProvider == null)
            mResourceProvider = new ResourceProvider(this);

        return mResourceProvider;
    }
}

现在转到您的ChangePasswordViewModel 并创建 ResourceProvider 对象

private ResourceProvider mResourceProvider;

并将其传递给constroctorChangePasswordViewModel

你可以通过它访问它

 userOldPasswordError.set(mResourceProvider.getString(R.string.select));

【讨论】:

  • 如果我想在我的视图模型@Ray 上应用 Junit 测试,这是一个好方法吗?
  • 听说将Context的实例传递给ViewModel类并不是一个好办法。
  • 使用 dagger 2 实现这种方法真的很有用而且很好!谢谢!
  • 此外,使用这种方法您将遇到字符串本地化问题
【解决方案2】:

您可以像这样将上下文发送到布局中:

XML:

<!-- 
<data>
     <variable 
          name="observable"
          type="...MyBaseObservableClass"
     />
</data>
 -->

android:text="@{observable.getDescription(context)}"

MyBaseObservableClass.kt:

@Bindable
fun getDescription(context: Context): String {
    return context.getString(R.string.my_string)
}

fun setNewData(data: Object) {
     this.data = data
     notifyPropertyChanged(BR.description)
}

【讨论】:

    【解决方案3】:

    使用 ObservableInt 对我有用。将此添加到 ViewModel

    private final ObservableInt mErrorText = new ObservableInt(R.string.empty_text);
    
    public ObservableInt getErrorText() {
       return mErrorText;
    }
    

    而且只是设置一个新的字符串值

    mErrorText.set(R.string.text_not_valid);
    

    在 xml 中将以下内容添加到 TextView

    android:text="@{viewModel.errorText}"
    

    【讨论】:

    • 我同意这应该是正确的答案。因为接受的答案依赖于视图模型中的上下文。有什么办法可以使用这种方法清除字符串或将字符串设置为“”?
    • 我得到 android.content.res.Resources$NotFoundException: String resource ID #0x0 by apply the same
    • @SrishtiRoy 你的strings.xml 中有R.string.empty_text 吗?更改为您自己的字符串或添加此
    • @AlexGray 如果你有 empty_text 你应该可以设置它来清除文本字段。您还可以创建一个 BindingAdapter 来检查文本是否为空或为空,在这种情况下将 textView 可见性设置为 GONE
    • ObservableInt 类型似乎不适用于TextInputLayout 上的"tools:error"。唯一有效的是BindableString。如何将ObservableIntBindableString 绑定?
    猜你喜欢
    • 2018-05-17
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    • 2020-12-24
    • 2021-08-20
    • 2019-04-17
    • 1970-01-01
    相关资源
    最近更新 更多