Как добавить функцию "Назад" в WebView внутри фрагмента?
ОБНОВЛЕНИЕ: Решено! Проблема была связана с моим Viewpager, а не с WebView.
Я пытаюсь добавить функцию "Назад" в мой 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();
}
Любые идеи, как заставить это работать?
Ответы
Ответ 1
Возможно, это ограничение для андроида. Попробуйте сделать это с помощью обработчика.
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();
}
}
Ответ 2
На самом деле вы не можете делать непосредственно внутри фрагмента. onBackPressed
можно переопределить в FragmentActivity
. Что вы можете сделать, это:
- Переопределите
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();
}
}
Ответ 3
Вы можете проверить этот код:
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;
}
});
Ответ 4
В 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();
}
Ответ 5
мое решение было в фрагменте, которое я добавил в общедоступные методы
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 является статическим
Ответ 6
вы можете сделать это:
-
в Activity
put:
// Set WebView
public void setWebView(WebView web) {
this.web = web;
}
-
в веб-фрагменте после ActivityCreated()
put:
((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;
}
Ответ 7
@OmidAmnivia ответ правильный, ваше приложение решение проблемы с авариями
@Override
public void onBackPressed() {
if(webFragment.isInitialized && webFragment.canGoBack()){
webFragment.goBack();
}else{
super.onBackPressed();
}
}
Вы должны проверить, был ли ваш класс инициализирован или нет.
Ответ 8
@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
}
если вы хотите сделать это с возвратом, вам нужно добавить что-то вроде:
[email protected] true
Ответ 9
Я создал простой интерфейс:
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;
}
}
}
Ответ 10
Прежде всего, вернитесь назад в фрагменте
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;
}
} );
надеюсь, что это сработает.
Ответ 11
Вот как я это сделал в своем приложении. Я использую событие back press, пока веб-просмотр не может вернуться назад. Как только веб-просмотр не может вернуться, я показываю пользователю подсказку, что если он продолжит нажимать, приложение закроется.
Это даст пользователю возможность оставаться в вашем приложении, когда веб-просмотр не может вернуться. Я чувствовал это более удобным для пользователя:
private val TIME_INTERVAL = 200 //time passed between two back presses.
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()
[email protected] true
}
else
{
if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis())
{ // dont consume back press and pass to super
[email protected] 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();
[email protected] true
}
}
}
[email protected] false
})