Search code examples
androiddata-bindingwebview2-way-object-databinding

2 Way databinding for Webview and ProgressBar


I am trying to implement 2 way databinding for WebView and Progressbar.

Initially ProgressBar will continue to appear and as soon as webview finishes loading , progress bar should be GONE.

But I am not able to create that binding

I have created Binding adapter for webview to load url and also set WebViewClient to check page loading is finished but cannot update the visibility of progressbar

////////////// Post

@BindingAdapter({"app:webUrl"})
    public void configureWebView(WebView iWebView, String iUrl) {

        iWebView.getSettings().setJavaScriptEnabled(true);
        iWebView.setWebViewClient(new WebViewClient() {

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                // code to set visibility of progress bar
            }
        });

        iWebView.loadUrl(iUrl);
    }

//////////////////// Layout

<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" />

        <variable
            name="newsUrl"
            type="com.example.bindingdemo.data.model.Post" />
    </data>


    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <WebView
            android:id="@+id/news_web_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:webUrl="@{newsUrl.url}" />

        <ProgressBar
            android:id="@+id/news_prog_bar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="@{**<WhatConditionToWrite>** ? View.GONE: View.Visible}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </android.support.constraint.ConstraintLayout>
</layout>

Solution

  • In your BindingAdapter

    @BindingAdapter({ "setWebViewClient" })
    public static void setWebViewClient(WebView view, WebViewClient client) {
        view.setWebViewClient(client);
    }
    
    @BindingAdapter({ "loadUrl" })
    public static void loadUrl(WebView view, String url) {
        view.loadUrl(url);
    }
    

    In your ViewModel

    public class YourObjectModel extends BaseObservable {
    
        private class Client extends WebViewClient {
            @Override
            public void onReceivedError(WebView view, WebResourceRequest request,
                WebResourceError error) {
                super.onReceivedError(view, request, error);
                setHideProgress(true);
            }
    
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                setHideProgress(true);
            }
        }
    
        public WebViewClient getWebViewClient() {
            return new Client();
        }
    
        @Bindable
        public boolean isHideProgress() {
            return hideProgress;
        }
    
        private void setHideProgress(boolean hideProgress) {
            this.hideProgress = hideProgress;
            notifyPropertyChanged(BR.hideProgress);
        }
    }
    

    XML

    <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
        <data>
            <variable
                name="viewModel"
                type="YourObjectModel"
                />
        </data>
        <WebView 
                ... 
                app:loadUrl="@{viewModel.url}"  
                app:setWebViewClient="@{viewModel.webViewClient}" />
        <ProgressBar 
                ... 
                android:visibility="@{viewModel.hideProgress ? View.GONE : View.VISIBLE}" />
    
    </layout>