Search code examples
androidsearchviewandroid-databinding

Android Databinding Query property of SearchView inside Toolbar


I want to change the query parameter of a SearchView via Androids data binding capabilities in an old fashioned ViewModel (not from Google new Architecture Components). The SearchView resides in a Toolbar.

In the ViewModel I want to call setQuery(String) and onSubmit of the query I want to use it for processing. In the current implementation (see code parts below) the SearchViews query value stays empty. This is clear, because the field query is not used anywhere near of the BindingAdapter for SearchView.setQuery(). But I have no idea how to change its query value from code. The BindingAdapter setQuery(SearchView, String) cannot be called, because there is no SearchView in the ViewModel and shouldn't to keep it clean for a MVVM architecture.

Binding other directly available attributes of SearchView like: QueryHint and queryTextListener works fine. The query attribute is not available directly in SearchView, despite it has a setter (SearchView.setQuery(String)).

What can I do?

The XML part and the corresponding MainViewModel looks something like this:

<data>
    <variable
        name="vm"
        type="com.example.MainViewModel"/>
</data>

<android.support.v7.widget.Toolbar
        android:id="@+id/activity_toolbar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="0dp"
        android:layout_marginRight="0dp"
        android:layout_marginTop="0dp"
        android:background="@color/colorPrimary"
        android:title="@string/app_name"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:subtitleTextColor="@color/white"
        app:title="@string/app_name"
        app:titleTextColor="@color/white" >

<android.support.v7.widget.SearchView
        android:id="@+id/searchView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:iconifiedByDefault="false"
        android:queryHint="@{vm.queryHint}"
        app:iconifiedByDefault="false"
        app:queryTextListener="@{vm.onQueryTextListener}"
        app:query="@{vm.query}" />
</android.support.v7.widget.Toolbar>

The ViewModel:

public class MainViewModel extends BaseObservable {

    private doSomething() {
        setQueryHint("TheHintText")
        setQuery("MyQuery");        
    }

    private void setQueryHint(String queryHint) {
        this.queryHint = queryHint;
        notifyPropertyChanged(BR._all);
    }

    private String query;

    @Bindable
    public String getQuery() {
        return query;
    }

//    private void setQuery(String query) {
//        this.query = query;
//    }

    @BindingAdapter("query")
    public static void setQuery(SearchView searchView, String queryText) {
        searchView.setQuery(queryText, false);
    }

    @Bindable
    public String getQueryHint() {
        return queryHint;
    }

    public SearchView.OnQueryTextListener getOnQueryTextListener() {
        return onQueryTextListener;
    }

    @BindingAdapter("queryTextListener")
    public static void setOnQueryTextListener(SearchView searchView, SearchView.OnQueryTextListener listener) {
        searchView.setOnQueryTextListener(listener);
    }

    private final SearchView.OnQueryTextListener onQueryTextListener = new SearchView.OnQueryTextListener() {
    @Override
        public boolean onQueryTextSubmit(String query) {
            Log.("Test", "query = " + query); // <- query is empty.
        }
    @Override
        public boolean onQueryTextChange(String newText) {
            return false;
        }
    };              
}

Solution

  • You need to notify when you set query. It will working

    private void setQuery(String query) {
        this.query = query;
        notifyPropertyChanged(BR.query);
    }