user1574268
user1574268

Reputation:

Saving the state of fragments?

I have a fragment class. Here is it below:

public class FragmentA extends Fragment {

Button button;
WebView myWebView;
int mCurCheckPosition;

 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);

 }

 @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("curChoice", mCurCheckPosition);
    }

 @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    if (savedInstanceState != null) {
            // Restore last state for checked position.
            mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
        }
}



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved)
{
     View mainView = (View) inflater.inflate(R.layout.frag_a, group, false);
     myWebView = (WebView) mainView.findViewById(R.id.webview);
    myWebView.setWebViewClient(new MyWebViewClient());
    myWebView.getSettings().setPluginsEnabled(true);
    myWebView.getSettings().setBuiltInZoomControls(false); 
    myWebView.getSettings().setSupportZoom(false);
    myWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);   
    myWebView.getSettings().setAllowFileAccess(true); 
    myWebView.getSettings().setDomStorageEnabled(true);
    myWebView.loadUrl("http://www.bbc.co.uk");       
    return mainView;
}


public class MyWebViewClient extends WebViewClient {        
    /* (non-Java doc)
     * @see android.webkit.WebViewClient#shouldOverrideUrlLoading(android.webkit.WebView, java.lang.String)
     */


    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.endsWith(".mp4")) 
        {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.parse(url), "video/*");

            view.getContext().startActivity(intent);
            return true;
        } 
        else {
            return super.shouldOverrideUrlLoading(view, url);
        }
    }

}

}

The problem is when I move to and from another fragment, the state of the original fragment (what web page it was on) is lost.

How can I prevent this? I want the state of the web page to remain switching to and from each fragment.

Thanks

Upvotes: 5

Views: 9863

Answers (2)

sirFunkenstine
sirFunkenstine

Reputation: 8495

I was having the same problem with webView content in a fragment. What worked for me was hiding the current fragment when loading a new one instead of replacing it. This causes the view to remain in the previous fragment and not be destroyed. View code below.

protected void showTableFragment( Fragment fragment, boolean allowBack, Asset table ) {

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    if (table != null)
        tableSection = (SectionTable) table;


        Fragment lastFragment = fragmentManager.findFragmentByTag("first_frag" );
        if ( lastFragment != null ) {
            transaction.hide( lastFragment );
        }


    if ( fragment.isAdded() ) {
        transaction.show( fragment );
    }
    else {
        transaction.add( R.id.fragment, fragment, "second_frag" ).setBreadCrumbShortTitle( "second_frag" );
    }

    if ( allowBack ) {
        transaction.addToBackStack( "second_frag" );
    }

    transaction.commit();
}

Upvotes: 0

Akos Cz
Akos Cz

Reputation: 12790

You should use the WebView.saveState(Bundle state) method to in your onSaveInstanceState(Bundle outState) method and then restore the state using WebView.restoreState(Bundle state) in your onActivityCreated(Bundle savedInstanceState) method

@Override
public void onSaveInstanceState(Bundle outState) {
   super.onSaveInstanceState(outState);
   mWebView.saveState(outState);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
   super.onActivityCreated(savedInstanceState);
   mWebView.restoreState(savedInstanceState);
}

Also keep in mind the Fragment Lifecycle. If your unsure where to restore the state (onCreate, onCreateView, onActivityCreated), take a look at the Fragment Lifecycle documentation to figure out the right place. http://developer.android.com/guide/components/fragments.html

enter image description here

onCreate()

The system calls this when creating the fragment. Within your implementation, you should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.

onCreateView()

The system calls this when it's time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a View from this method that is the root of your fragment's layout. You can return null if the fragment does not provide a UI.

onActivityCreated()

Called when the fragment's activity has been created and this fragment's view hierarchy instantiated. It can be used to do final initialization once these pieces are in place, such as retrieving views or restoring state. It is also useful for fragments that use setRetainInstance(boolean) to retain their instance, as this callback tells the fragment when it is fully associated with the new activity instance. This is called after onCreateView(LayoutInflater, ViewGroup, Bundle) and before onStart().

Upvotes: 5

Related Questions