web-dev-qa-db-ja.com

Fragment内のWebViewに「戻る」機能を追加する方法

更新:解決済み!問題はWebViewではなくViewpagerに関連していました。

WebView内にあるFragmentに「戻る」機能を追加しようとしています。しかし、私は方法を理解できません:

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;
            }
        });
    }   
}

私は次のようなものも試しました:

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

別の解決策ですが、同じ問題:

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

これを機能させる方法はありますか?

31
Markus Rubey

おそらくそのAndroid制限。ハンドラーを使用してこれを実行してみてください。

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();
    }
}
46
Roman Black

実際には、フラグメント内で直接行うことはできません。 onBackPressedは、FragmentActivityでオーバーライドできます。できることは:

  1. アクティビティ内のonBackPressedをオーバーライドします。
  2. onBackPressedが呼び出されたら、現在のフラグメントのインスタンスがwebviewを示すインスタンスであるかどうかを確認します。
  3. もしそうなら、fragmentが戻ることができるかどうかwebviewに尋ねてください。
  4. そうでない場合は、superまたは必要なものを呼び出します

編集:

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

このコードを確認できます:

    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;
        }
    });
18
XZandr

WebViewActivity.Java、1つのメソッドを追加しました。

@Override
public void onBackPressed() {

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

WebViewFragment.Java、2つのメソッドを追加しました。

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

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

私のソリューションはパブリックメソッドに追加したフラグメントにありました

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

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

その後、私が呼び出す活動から

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

}

note mwebviewは静的です

3
Omid Aminiva

これを行うには:

  • Activity putで:

    _// Set WebView
    
    public void setWebView(WebView web) {
    
        this.web = web;
    }
    _
  • ActivityCreated() putの後のWebフラグメント:

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

  • 次のようにonCreateView()からwebViewを設定することを忘れないでください:

    _@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

これは私が私のアプリでやった方法です。 Webビューが戻るまで、バックプレスイベントを使用します。 Webビューが戻れない場合、ユーザーが押し続けると、アプリが終了するというヒントをユーザーに表示します。

webviewが戻れないときにユーザーがアプリにとどまる機会をユーザーに与えます。ユーザーフレンドリーであると感じました:

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

        })
1
Hitesh Sahu

@RomanBlackの答えは正しい考えを与えてくれましたが、kotlinを使用しているので、少し答えを調整する必要がありました。

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
    }

リターンでそれをしたい場合は、次のようなものを追加する必要があります。

return@setOnKeyListener true
1
Mike T

@OmidAmniviaの答えはあなたのアプリが正しいですクラッシュの解決策は

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

クラスが初期化されているかどうかを確認する必要があります。

1
h_code

シンプルなインターフェースを作成しました:

public interface IOnBackPressed {
    boolean onBackPressed();
}

アクティビティ内:

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();
       }
    }
}

フラグメント内:

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;
        }
    }
}

まずフラグメントで押し戻されます

 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;
  }
 } );

それが機能することを願っています。

0
Dalvinder Singh