web-dev-qa-db-fra.com

Comment ajouter la fonction "Retour" dans WebView dans Fragment?

MISE À JOUR: résolu! Le problème était lié à mon Viewpager et non à WebView.

J'essaie d'ajouter une fonction "Retour" à ma WebView qui se trouve dans une Fragment. Mais je n'arrive pas à comprendre comment:

public final class TestFragment extends Fragment {

    static WebView mWeb;
    private View mContentView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState)
    {   
        mContentView = inflater.inflate(R.layout.webview, null);
        mWeb = (WebView)mContentView.findViewById(R.id.webview);

        WebSettings settings = mWeb.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setSupportZoom(false);
        mWeb.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        mWeb.getSettings().setBuiltInZoomControls(false);
        mWeb.loadUrl("myurl...");
        mWeb.setOnKeyListener(new OnKeyListener(){
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
                    mWeb.goBack();
                    return true;
                }
                return false;
            }
        });
    }   
}

J'ai aussi essayé quelque chose comme:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
        mWeb.goBack();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

Une autre solution mais le même problème:

@Override
public void onBackPressed()
{
    if(webView.canGoBack())
        webView.goBack();
    else
        super.onBackPressed();
}

Des idées comment faire fonctionner cela?

25
Markus Rubey

Peut-être sa restriction Android. Essayez de faire cela en utilisant handler.

public final class TestFragment extends Fragment {


    static WebView mWeb;
    private View mContentView;

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message message) {
            switch (message.what) {
                case 1:{
                    webViewGoBack();
                }break;
            }
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {   

        mContentView = inflater.inflate(R.layout.webview, null);
        mWeb = (WebView)mContentView.findViewById(R.id.webview);

        WebSettings settings = mWeb.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setSupportZoom(false);
        mWeb.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        mWeb.getSettings().setBuiltInZoomControls(false);
        mWeb.loadUrl("myurl...");
        mWeb.setOnKeyListener(new OnKeyListener(){

            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK 
                        && event.getAction() == MotionEvent.ACTION_UP 
                        && mWeb.canGoBack()) {
                    handler.sendEmptyMessage(1);
                    return true;
                }

                return false;
            }

        });

    }   

    private void webViewGoBack(){
        mWeb.goBack();
    }
}
41
Roman Black

En fait, vous ne pouvez pas faire directement à l'intérieur du fragment. La onBackPressed peut être remplacée dans la FragmentActivity. Ce que vous pouvez faire c'est:

  1. Remplacez la onBackPressed dans l'activité.
  2. Lorsque la variable onBackPressed est appelée, vérifiez si l'instance du fragment actuel est l'instance affichant la variable webview.
  3. Si c'est le cas, demandez à la fragment si la webview peut remonter. 
  4. si ce n'est pas le cas, appelez le super ou ce dont vous avez besoin

Modifier:

 @Override
 public void onBackPressed() {
       Fragment webview = getSupportFragmentManager().findFragmentByTag("webview");
       if (webview instanceof MyWebViewFragment) {
              boolean goback = ((MyWebViewFragment)webview).canGoBack();
              if (!goback)
                super.onBackPressed();
       }
 }
21
Blackbelt

Vous pouvez vérifier ce code: 

    webView.canGoBack();
    webView.setOnKeyListener(new View.OnKeyListener() {

        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK
                    && event.getAction() == MotionEvent.ACTION_UP
                    && webView.canGoBack()) {
                webView.goBack();
                return true;
            }
            return false;
        }
    });
9
XZandr

Dans WebViewActivity.Java, j'ai ajouté 1 méthode:

@Override
public void onBackPressed() {

    WebViewFragment fragment = (WebViewFragment)
            getSupportFragmentManager().findFragmentById(R.id.fragmentContainer);
    if (fragment.canGoBack()) {
        fragment.goBack();
    } else {
        super.onBackPressed();
    }
}

Dans WebViewFragment.Java, j'ai ajouté 2 méthodes:

public boolean canGoBack() {
    return mWebView.canGoBack();
}

public void goBack() {
    mWebView.goBack();
}
5
Ram Patra

ma solution était dans le fragment que j'ai ajouté aux méthodes publiques

public static boolean canGoBack(){
        return mWebView.canGoBack();
    }

    public static void goBack(){
        mWebView.goBack();
    }

puis de l'activité que j'appelle

@Override
public void onBackPressed() {
    if(webFragment.canGoBack()){
        webFragment.goBack();
    }else{
        super.onBackPressed();
    }

}

note la mwebview est statique

3
Omid Aminiva

vous pouvez le faire en:

  • dans la Activity put:

    // Set WebView
    
    public void setWebView(WebView web) {
    
        this.web = web;
    }
    
  • dans le fragment Web après ActivityCreated() put:

    ((Your_Activity) getActivity()).setWebView(webView);

  • N'oubliez pas de définir webView de la onCreateView() comme ceci:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        webView = (WebView) inflater.inflate(R.layout.your_web_fragment, container,
                false);
        return web;
    }
    
2
AndroMan

La réponse de @ RomanBlack m'a donné la bonne idée, mais puisque nous utilisons kotlin, j'ai dû adapter un peu la réponse. 

webView.setOnKeyListener { _, _, keyEvent ->
        if (keyEvent.keyCode == KeyEvent.KEYCODE_BACK && !webView.canGoBack()) {
            false
        } else if (keyEvent.keyCode == KeyEvent.KEYCODE_BACK && keyEvent.action == MotionEvent.ACTION_UP) {
            webView.goBack()
            true
        } else true
    }

si vous voulez le faire avec des déclarations, vous devez ajouter quelque chose comme:

return@setOnKeyListener true
1
Mike T

@OmidAmnivia answer est correcte, votre application la solution au crash

@Override
public void onBackPressed() {
if(webFragment.isInitialized && webFragment.canGoBack()){
    webFragment.goBack();
}else{
    super.onBackPressed();
}
}

Vous devez vérifier si votre classe a été initialisée ou non. 

1
h_code

J'ai créé une interface simple:

public interface IOnBackPressed {
    boolean onBackPressed();
}

dans l'activité:

public class MyActivity extends Activity {
    @Override public void onBackPressed() {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_container);
       if (!(fragment instanceof IOnBackPressed) || !((IOnBackPressed) fragment).onBackPressed()) {
          super.onBackPressed();
       }
    }
}

dans le fragment:

public class MyFragment extends Fragment implements IOnBackPressed {
   @Override
    public boolean onBackPressed() {
        if (webview.canGoBack()) {
            webview.goBack();
            // backpress is not considered in the Activity
            return true;
        } else {
            // activity will act normal
            return false;
        }
    }
}
1

Tout d'abord, retourne pressé dans le fragment

 mContentView.setFocusableInTouchMode(true);
 mContentView.requestFocus();
 mContentView.setOnKeyListener( new OnKeyListener()
 {
   @Override
   public boolean onKey( View v, int keyCode, KeyEvent event )
  {
      if( keyCode == KeyEvent.KEYCODE_BACK )
      {
        if (mWebView.canGoBack()) {
                mWebView.goBack();
                retune false;
            } else {
               return true;
            }

      }
      return false;
  }
 } );

j'espère que ça va marcher.

0
Dalvinder Singh

Voici comment je l'ai fait dans mon application. Je consomme des événements de presse jusqu'à ce que la vue Web puisse revenir. Une fois que l'affichage Web ne peut plus revenir en arrière, je montre à l'utilisateur que s'il continue d'appuyer en arrière, l'application se ferme. 

Il donnera à l'utilisateur une chance de rester dans votre application lorsque la visualisation Web ne peut pas revenir en arrière. Je le sentais plus convivial:

          //time passed between two back presses.
          private val TIME_INTERVAL = 200 
           // variable to keep track of last back press
          private var mBackPressed: Long = 0


        webView!!.requestFocus()
        webView.setOnKeyListener(View.OnKeyListener { v, keyCode, event ->
            if (keyCode == KeyEvent.KEYCODE_BACK
                    && event.action == MotionEvent.ACTION_UP
                  ) {
                if(webView.canGoBack()) {
                    //go back in previous page
                    webView.goBack()
                    return@OnKeyListener true
                }
                else
                {
                    if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis())
                    {   // dont consume back press and pass to super
                        return@OnKeyListener false
                    }
                    else {
                        // show hint for double back press
                        Toast.makeText(context, " Double Tap back button to exit the demo", Toast.LENGTH_SHORT).show();
                        mBackPressed = System.currentTimeMillis();
                        return@OnKeyListener true
                    }
                }
            }
            return@OnKeyListener false

        })
0
Hitesh Sahu