WebViewFragment webView is null after doing a FragmentTransaction

Issue

I currently have my application set up with a ListFragment on the left and a DetailsFragment on the right (similar to the layout on the tablet below).

layout

On the details fragment (fragment next to the list) I have a goto deal button, which when pressed should replace the detailsFragment with a WebViewFragment.

The problem I am having is that when trying to load a url in the webviewfragment the WebView is null.

WebViewFragment webViewFragment  new WebViewFragment();

FragmentTransaction transaction  getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.deal_details_fragment, webViewFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

// Set the url
if (webViewFragment.getWebView()null)
    Log.d("webviewfragment", "is null");
webViewFragment.getWebView().loadUrl("http://www.google.com");

Below is my main layout which has the original two fragments defined.

<?xml version"1.0" encoding"utf-8"?>
<LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"
          android:id"@+id/main_activity_layout"

    android:layout_width"fill_parent"
    android:layout_height"fill_parent"
    android:orientation"horizontal" >

  <fragment
      android:name"com.bencallis.dealpad.DealListFragment"
      android:id"@+id/deal_list_fragment"
      android:layout_weight"1"
      android:layout_width"0px"
      android:layout_height"match_parent" >
      <!-- Preview: layout@layout/deal_list_fragment -->
  </fragment>
  <fragment
      android:name"com.bencallis.dealpad.DealDetailsFragment"
      android:id"@+id/deal_details_fragment"
      android:layout_weight"2"
      android:layout_width"0px"
      android:layout_height"match_parent" >
      <!-- Preview: layout@layout/deal_details_fragment -->
  </fragment>

</LinearLayout>

It seems that the webViewFragment is not being created fully as the WebView has not been initialised. I have looked online but there is very little information regarding the WebViewFragment.

Any ideas how to ensure WebView is initialised in the WebViewFragment?

Solution

With great help from Espiandev I have managed to get a working WebView. To ensure that links opened in the fragment and not in a web browser application I created a simple InnerWebView client which extends WebViewClinet.

public class DealWebViewFragment extends Fragment {

    private WebView mWebView;
    private boolean mIsWebViewAvailable;
    private String mUrl  null;

    /**
     * Creates a new fragment which loads the supplied url as soon as it can
     * @param url the url to load once initialised
     */
    public DealWebViewFragment(String url) {
        super();
        mUrl  url;
    }

    /**
     * Called to instantiate the view. Creates and returns the WebView.
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        if (mWebView ! null) {
            mWebView.destroy();
        }
        mWebView  new WebView(getActivity());
        mWebView.setOnKeyListener(new OnKeyListener(){


            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                  if ((keyCode  KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
                        mWebView.goBack();
                        return true;
                    }
                    return false;
            }

        });
        mWebView.setWebViewClient(new InnerWebViewClient()); // forces it to open in app
        mWebView.loadUrl(mUrl);
        mIsWebViewAvailable  true;
        WebSettings settings  mWebView.getSettings();
        settings.setJavaScriptEnabled(true);
        return mWebView;
    }

    /**
     * Convenience method for loading a url. Will fail if {@link View} is not initialised (but won't throw an {@link Exception})
     * @param url
     */
    public void loadUrl(String url) {
        if (mIsWebViewAvailable) getWebView().loadUrl(mUrl  url);
        else Log.w("ImprovedWebViewFragment", "WebView cannot be found. Check the view and fragment have been loaded.");
    }

    /**
     * Called when the fragment is visible to the user and actively running. Resumes the WebView.
     */
    @Override
    public void onPause() {
        super.onPause();
        mWebView.onPause();
    }

    /**
     * Called when the fragment is no longer resumed. Pauses the WebView.
     */
    @Override
    public void onResume() {
        mWebView.onResume();
        super.onResume();
    }

    /**
     * Called when the WebView has been detached from the fragment.
     * The WebView is no longer available after this time.
     */
    @Override
    public void onDestroyView() {
        mIsWebViewAvailable  false;
        super.onDestroyView();
    }

    /**
     * Called when the fragment is no longer in use. Destroys the internal state of the WebView.
     */
    @Override
    public void onDestroy() {
        if (mWebView ! null) {
            mWebView.destroy();
            mWebView  null;
        }
        super.onDestroy();
    }

    /**
     * Gets the WebView.
     */
    public WebView getWebView() {
        return mIsWebViewAvailable ? mWebView : null;
    }

    /* To ensure links open within the application */
    private class InnerWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }


    }

Hopefully this is useful to someone in the future.

Answered By – bencallis

Leave a Comment