Android 如何在 Fragment 内的 WebView 中添加“返回”功能?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10631425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add "Go Back" function in WebView inside Fragment?
提问by Markus Rubey
UPDATE: Solved! Problem was related to my Viewpager not WebView.
更新:解决了!问题与我的 Viewpager 而非 WebView 有关。
I'm trying to add a "Go Back" function to my WebView
which is inside a Fragment
. But I can't figure out how to:
我正在尝试将“返回”功能添加到我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;
}
});
}
}
I also tried something like:
我也尝试过类似的事情:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
mWeb.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
Another solution but same problem:
另一个解决方案,但同样的问题:
@Override
public void onBackPressed()
{
if(webView.canGoBack())
webView.goBack();
else
super.onBackPressed();
}
Any ideas how to get this working?
任何想法如何让这个工作?
回答by Roman Black
Perhaps its android restriction. Try to do this using handler.
也许它的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();
}
}
回答by XZandr
You can check this 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;
}
});
回答by Blackbelt
Actually you can not do directly inside the fragment. The onBackPressed
can be overridden in the FragmentActivity
. What you can do is:
其实你不能直接在fragment里面做。本onBackPressed
可以在被覆盖FragmentActivity
。你可以做的是:
- Override the
onBackPressed
inside the activity. - When the
onBackPressed
is called, check if the instance of the current fragment is the instance showing thewebview
. - If it is, ask the
fragment
if thewebview
can go back. - if it is not, call the
super
or whatever you need
- 覆盖
onBackPressed
活动的内部。 - 当
onBackPressed
被调用时,检查当前片段的实例是否是显示webview
. - 如果是,请问
fragment
是否webview
可以返回。 - 如果不是,请致电
super
或您需要的任何东西
Edit:
编辑:
@Override
public void onBackPressed() {
Fragment webview = getSupportFragmentManager().findFragmentByTag("webview");
if (webview instanceof MyWebViewFragment) {
boolean goback = ((MyWebViewFragment)webview).canGoBack();
if (!goback)
super.onBackPressed();
}
}
回答by Ram Patra
In WebViewActivity.java
, I added 1 method:
在 中WebViewActivity.java
,我添加了 1 个方法:
@Override
public void onBackPressed() {
WebViewFragment fragment = (WebViewFragment)
getSupportFragmentManager().findFragmentById(R.id.fragmentContainer);
if (fragment.canGoBack()) {
fragment.goBack();
} else {
super.onBackPressed();
}
}
In WebViewFragment.java
, I added 2 methods:
在 中WebViewFragment.java
,我添加了 2 个方法:
public boolean canGoBack() {
return mWebView.canGoBack();
}
public void goBack() {
mWebView.goBack();
}
回答by Mike T
@RomanBlack's answer gave me the right idea, but since we use kotlin I had to adapt the answer a little bit.
@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
}
if you want to do it with returns you have to add something like:
如果你想用退货来做,你必须添加如下内容:
return@setOnKeyListener true
回答by Omid Aminiva
my solution was in fragment I added to public methods
我的解决方案是在我添加到公共方法的片段中
public static boolean canGoBack(){
return mWebView.canGoBack();
}
public static void goBack(){
mWebView.goBack();
}
then from activity I call
然后从我打电话的活动中
@Override
public void onBackPressed() {
if(webFragment.canGoBack()){
webFragment.goBack();
}else{
super.onBackPressed();
}
}
note The mwebview is static
注意 mwebview 是静态的
回答by AndroMan
you can do this by :
你可以这样做:
in the
Activity
put :// Set WebView public void setWebView(WebView web) { this.web = web; }
in the web fragment after
ActivityCreated()
put:((Your_Activity) getActivity()).setWebView(webView);
Don't forget to set
webView
from theonCreateView()
like these:@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { webView = (WebView) inflater.inflate(R.layout.your_web_fragment, container, false); return web; }
在
Activity
放置:// Set WebView public void setWebView(WebView web) { this.web = web; }
在
ActivityCreated()
放置后的网络片段中:((Your_Activity) getActivity()).setWebView(webView);
不要忘记
webView
从onCreateView()
这些设置:@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { webView = (WebView) inflater.inflate(R.layout.your_web_fragment, container, false); return web; }
回答by Manuel Schmitzberger
I've created a simple interface:
我创建了一个简单的界面:
public interface IOnBackPressed {
boolean onBackPressed();
}
in the Activity:
在活动中:
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();
}
}
}
in the 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;
}
}
}
回答by Hitesh Sahu
This is how I did in my app. I consume back press event till web view can go back. Once web view cant go back I show hint to user that if he keep on pressing back then app will exit.
这就是我在我的应用程序中所做的。我消耗后按事件,直到网络视图可以返回。一旦 Web 视图无法返回,我会向用户显示提示,如果他继续按返回,则应用程序将退出。
It will give user a chance to stay in your app when webview cant go back. I felt it more user friendly:
当 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
})
回答by h_code
@OmidAmnivia answer is correct your app the solution to the crash is
@OmidAmnivia 回答正确您的应用程序崩溃的解决方案是
@Override
public void onBackPressed() {
if(webFragment.isInitialized && webFragment.canGoBack()){
webFragment.goBack();
}else{
super.onBackPressed();
}
}
You have to check whether your class has been initialised or not.
您必须检查您的类是否已初始化。