30

I want to set the text of my TextView conditionally to either one or the other.

Android Data Binding documentation suggests that you can set the text conditionally if the text is a property of the view model. e.g.

android:text="@{user.displayName != null ? user.displayName : user.lastName}"

But is there any way to set the text from the strings.xml rather than adding it in my view model? I want something like this-

android:text="@{viewModel.expanded ? @string/collapse : @string/expand}"

The XML looks somewhat like this:

<?xml version="1.0" encoding="UTF-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:bind="http://schemas.android.com/apk/res-auto">
   <data class="TravellerInfoBinding">
      <import type="android.view.View" />
      <variable name="viewModel" type="com.myproject.viewmodel.TravellerInfoViewModel" />

   </data>
   <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal">
      <ImageView android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center_vertical"
        android:src="@drawable/expandable_arrow_blue" />

      <TextView style="@style/primary_pair_element_value" 
        android:layout_width="wrap_content"   
        android:layout_height="wrap_content" 
        android:text="@{viewModel.expanded ? @string/taxes_fees_detail : @string/hide_taxes_fees_detail}"
        android:textSize="12sp" />

   </LinearLayout>
</layout>

And this is my View Model-

package com.myproject.viewmodel;

imports...

public class TravellerInfoViewModel extends BaseObservable {

  @Bindable
  private final TaxDetailsViewModel taxDetailsViewModel;

  @Bindable
  private boolean expanded;

  Constructor....

  public boolean isExpanded() {
    return expanded;
  }

  public void setExpanded(boolean expanded) {
    this.expanded = expanded;
    notifyPropertyChanged(BR.expanded);
  }

  public void toggleExpanded() {
    setExpanded(!expanded);
  }

}
11
  • 1
    I thought that syntax worked. What problems are you encountering? Commented Jun 9, 2016 at 12:27
  • It is correct, have you got any error? Commented Jun 9, 2016 at 12:33
  • @CommonsWare Getting this compilation error Error: Identifiers must have user defined types from the XML file. viewModel is missing it Commented Jun 9, 2016 at 12:52
  • 1
    can you please post your xml file, something is missing in <data> Commented Jun 9, 2016 at 12:54
  • @RRR Thanks. Updated the question. Commented Jun 9, 2016 at 12:59

2 Answers 2

31

Actually, this works fine for me

<TextView
    android:id="@+id/btnEdit"
    style="@style/Common.Toolbar.Action.Text"
    android:onClickListener="@{onEditClick}"
    android:text="@{vm.editMode ? @string/contacts_done : @string/contacts_edit}"
    tools:text="@string/contacts_edit"/>

Where vm - it's a ViewModel and editMode - it's ObservableBoolean

Sign up to request clarification or add additional context in comments.

7 Comments

How to achieve this using 2-way binding?
What do you mean - "2-way binding"?
I still don't understand your question. The answer was about using resources with conditions. I don't understand how do you want to use two-way binding with resources
I wanted to ask if I make a change to the 'vm.editMode', how will the visibility be computed again. Is it possible?
|
2

Here's a fix/work-around :

  1. define a duplicate Xml definition of the layout where you want a conditional value
  2. for each block, set one of the condition values
  3. set the visibility of each Xml definition according to the data binding boolean value

Not the ideal solution, not very pretty .. but functionally equivalent - and works in the interim until proper solution is found.

Here's how I solved it for android:textStyle, where I had a special case requirement for showing values in bold.

    <variable
        name="viewModel"
        type="com.demo.app.SomeViewModel"/>

        ...

    <TextView
        style="@style/RowValue"
        android:visibility="@{ ! viewModel.boldRow ? View.VISIBLE : View.GONE}"
        android:text="@{viewModel.currentValue}"
        />

    <TextView
        style="@style/RowValue"
        android:visibility="@{ viewModel.boldRow ? View.VISIBLE : View.GONE}"
        android:text="@{viewModel.currentValue}"
        android:textStyle="bold"
        />

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.