Android 如何加上「;“回去”;WebView内部片段中的函数?
更新:已解决!问题与我的Viewpager而不是WebView有关。 我试图在Android 如何加上「;“回去”;WebView内部片段中的函数?,android,android-fragments,android-webview,Android,Android Fragments,Android Webview,更新:已解决!问题与我的Viewpager而不是WebView有关。 我试图在片段中的WebView中添加一个“返回”函数。但我不知道如何: public final class TestFragment extends Fragment { static WebView mWeb; private View mContentView; @Override public View onCreateView(LayoutInflater inflater, Vi
片段
中的WebView
中添加一个“返回”函数。但我不知道如何:
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);
}
return@setOnKeyListener true
另一个解决方案,但同样的问题:
@Override
public void onBackPressed()
{
if(webView.canGoBack())
webView.goBack();
else
super.onBackPressed();
}
有什么办法可以让它工作吗?实际上,你不能直接在片段内部完成。可在
碎片活动
中覆盖onBackPressed
。您可以做的是:
onBackPressed
时,检查当前片段的实例是否是显示webview
的实例片段是否可以返回webview
李>
如果不是,请拨打super
或任何您需要的电话
编辑:
也许是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();
}
}
您可以通过以下方式完成此操作:
- 在
活动中
输入:
// Set WebView
public void setWebView(WebView web) {
this.web = web;
}
- 在
ActivityCreated()
put之后的web片段中:
((您的活动)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;
}
我的解决方案是添加到公共方法中的片段
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();
}
}
注意mwebview是静态的在WebViewActivity.java
中,我添加了一个方法:
@Override
public void onBackPressed() {
WebViewFragment fragment = (WebViewFragment)
getSupportFragmentManager().findFragmentById(R.id.fragmentContainer);
if (fragment.canGoBack()) {
fragment.goBack();
} else {
super.onBackPressed();
}
}
在WebViewFragment.java
中,我添加了两种方法:
public boolean canGoBack() {
return mWebView.canGoBack();
}
public void goBack() {
mWebView.goBack();
}
@OmidAmnivia回答正确您的应用程序崩溃的解决方案是
@Override
public void onBackPressed() {
if(webFragment.isInitialized && webFragment.canGoBack()){
webFragment.goBack();
}else{
super.onBackPressed();
}
}
您必须检查您的类是否已初始化 首先,在碎片中被压回去
mContentView.setFocusableInTouchMode(true);
mContentView.requestFocus();
mContentView.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;
}
} );
希望它能起作用。@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
}
如果您想使用退货,您必须添加以下内容:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
mWeb.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
return@setOnKeyListener true
您可以检查以下代码:
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;
}
});
我创建了一个简单的界面:
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;
}
}
}
这就是我在我的应用程序中所做的。我使用back press事件,直到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
})
使用BackPressedDispatcher有一种简单的方法
片段:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if(webView.canGoBack()){
webView.goBack()
} else {
isEnabled = false
requireActivity().onBackPressed()
}
}
}
requireActivity().onBackPressedDispatcher.addCallback(this,callback)
}
override fun onBackPressed() {
val fragment = supportFragmentManager.findFragmentByTag("WebViewFragment")
if (WebViewFragment::class.java.isInstance(fragment)) {
if (onBackPressedDispatcher.hasEnabledCallbacks()) {
onBackPressedDispatcher.onBackPressed()
return
}
super.onBackPressed()
}
}
活动:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if(webView.canGoBack()){
webView.goBack()
} else {
isEnabled = false
requireActivity().onBackPressed()
}
}
}
requireActivity().onBackPressedDispatcher.addCallback(this,callback)
}
override fun onBackPressed() {
val fragment = supportFragmentManager.findFragmentByTag("WebViewFragment")
if (WebViewFragment::class.java.isInstance(fragment)) {
if (onBackPressedDispatcher.hasEnabledCallbacks()) {
onBackPressedDispatcher.onBackPressed()
return
}
super.onBackPressed()
}
}
也许这些代码可以改进,但对我来说效果很好。欲了解更多信息,请访问。这在我的情况下有效
public class FantasyFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
WebView webview;
SwipeRefreshLayout swipeLayout;
String currentUrl="https://www.stackoverflow.com/";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_stadium, container, false);
swipeLayout = (SwipeRefreshLayout) root.findViewById(R.id.swipescreen);
swipeLayout.setOnRefreshListener(this);
return root;
}
@Override
public void onStart() {
super.onStart();
LoadWeb();
}
public void LoadWeb() {
webview = (WebView) getActivity().findViewById(R.id.webview786);
swipeLayout.setRefreshing(true);
webview.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
webview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webview.getSettings().setAppCacheEnabled(true);
WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
webSettings.setUseWideViewPort(true);
webSettings.setSavePassword(true);
webSettings.setSaveFormData(true);
webSettings.setEnableSmoothTransition(true);
webview.loadUrl(currentUrl);
webview.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Snackbar.make(view, "Connection Error", Snackbar.LENGTH_LONG)
.setAction("Retry", new View.OnClickListener() {
@Override
public void onClick(View v) {
LoadWeb();
}
}).show();
}
@Override
public void onPageFinished(WebView view, String url) {
swipeLayout.setRefreshing(false);
currentUrl = url;
super.onPageFinished(view, url);
}
});
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;
}
});
}
@Override
public void onRefresh() {
LoadWeb();
}
}
会发生什么?实现onBackPressed()的第三个选项适用于我,请确保您确实有一些东西要返回。问题是?我有一个非常相似的情况:)感谢这段代码,真的帮助我提供了一个快速解决问题的导航抽屉和片段webview。对我来说也是如此,这应该被选为答案!这是可行的,但是有一个缺陷。您只检测到了keyCode,而不是KeyEvent。因此,当你按下后退按钮时,你的on键将被呼叫两次,按下一次,向上一次。所以它应该是:如果(keyCode==KeyEvent.keyCode\u BACK&&event.getAction()==MotionEvent.ACTION\u UP){你能告诉我为什么要使用handler!