I want to disable menu button. I read a lot of articles and nothing works.
I can't even detect menu button pressed event. Overriding methods like
onKeyDown(), onKeyUp(), onPrepareOptionsMenu(), onCreateOptionsMenu() didn't
worked. I am really desperate here, please help.
public class MainActivity extends Activity{
TranslateAnimation animateTopLayer;
Button btnOk;
ImageView ivLockMechanism;
ViewGroup rlTopLayer;
FramesSequenceAnimation anim;
#Override
public void onAttachedToWindow() {
getWindow().addFlags(WindowManager.LayoutParams. FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent lockServiceIntent = new Intent(getApplicationContext(),LockService.class);
startService(lockServiceIntent);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.test);
rlTopLayer = (ViewGroup) findViewById(R.id.rlTopLayer);
ivLockMechanism = (ImageView) findViewById(R.id.ivLockMechanism);
btnOk = (Button) findViewById(R.id.btnOk);
btnOk.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
rlTopLayer.startAnimation(animateTopLayer);
}
});
Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.pg_0);
ivLockMechanism.setImageBitmap(b);
anim = AnimationsContainer.getInstance().unlockMechanismAnimation(ivLockMechanism);
animateTopLayer = new TranslateAnimation(0, 500,0, 0);
animateTopLayer.setDuration(1000);
animateTopLayer.setFillAfter(true);
animateTopLayer.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation) {
anim.start();
}
});
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ( Integer.valueOf(android.os.Build.VERSION.SDK) < 7
&& keyCode == KeyEvent.KEYCODE_BACK
&& event.getRepeatCount() == 0) {
onBackPressed();
}
if (keyCode == KeyEvent.KEYCODE_MENU){
return false;
}
return super.onKeyDown(keyCode, event);
}
#Override
public void onBackPressed() {
return;
}
#Override
protected void onPause() {
super.onPause();
finish();
}
}
This works for me:
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
return true;
}
return super.onKeyDown(keyCode, event);
}
Return true to prevent this event from being propagated further, or
false to indicate that you have not handled this event and it should
continue to be propagated.
#Override
public boolean onPrepareOptionsMenu (Menu menu) {
return false;
}
Related
The onKeyListener() in a Fragment is not working now. Here's the part of the code.
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, null);
...
view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener(new View.OnKeyListener() {
// true if the listener has consumed the event, false otherwise.
// the key event happens twice, when pressing and taking off.
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK && !touched) {
Log.i(TAG, "onKey() method");
touched = true;
return true;
} else {
return false;
}
}
});
return view;
}
Is there anything I am missing?
try this:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//go to previous fragemnt
//perform your fragment transaction here
//pass data as arguments
return true;
}
}
return false;
}
});
}
This worked for me, for both Fragment & DialogFragment.
For Fragment:
#Override
public void onResume() {
super.onResume();
// Disable back press
requireView().setFocusableInTouchMode(true);
requireView().requestFocus();
requireView().setOnKeyListener((v, keyCode, event) -> keyCode == KeyEvent.KEYCODE_BACK);
}
For DialogFragment:
#Override
public void onResume() {
super.onResume();
requireDialog().setOnKeyListener((dialog, keyCode, event) ->
// Disable back pressed
keyCode == android.view.KeyEvent.KEYCODE_BACK
);
}
i am trying to disable the back button in my device with the following code.
the code is working but i would like that the function that handle all the back button request in the fragments will derived from the Main Activity
this is the back button handler:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
Toast.makeText(getActivity(), "Please navigate via the menu", Toast.LENGTH_SHORT).show();
return true;
}
}
return false;
}
});
}
It's easier to override onBackPressed function:
private boolean disabled = true;
#Override
public void onBackPressed() {
if (!disabled) {
super.onBackPressed();
}
}
With this you can easy change disable flag and enable back button when needed.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_BACK) {
//leave it empty
}
return super.onKeyDown(keyCode, event);
}
It's generally not the best idea to disable the back button as the user expects that button to perform some sort of back navigation. Now that being said, if you have a specific reason you can disable the back button by overriding the onBackPressed at the activity level and not calling into super.
Put this code at your MainActivity:
#Override
public void onBackPressed() {
executeAtAndroidOnBackPressed();
}
#Override
public boolean onKeyDown(final int keyCode, final KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
executeAtAndroidOnBackPressed();
}
return false;
}
protected void executeAtAndroidOnBackPressed() {
// do nothing
}
I have defined four buttons that onclick event shows a content, now after click when press
back button that shows same four buttons but click event not working.
I defined a field that if user saw content isLooked=true so when clicked on back button I setContentView(R.layout.index) and I will not allow to exit of current activity.
why not working events after click on back button?
private boolean isLooked = false;
#Override
public void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.index);
initialEvents();
} catch (Exception e) {
new com.example.csharp.Log.Error().Save(e);
}
}
private void initialEvents() {
View v = findViewById(R.id.btnChapter1);
v.setOnClickListener(this);
v = findViewById(R.id.btnChapter2);
v.setOnClickListener(this);
v = findViewById(R.id.btnChapter3);
v.setOnClickListener(this);
v = findViewById(R.id.btnChapter4);
v.setOnClickListener(this);
}
#Override
public void onBackPressed() {
if (isLooked) {
setContentView(R.layout.index);
isLooked = false;
} else {
super.onBackPressed();
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && isLooked) {
setContentView(R.layout.index);
isLooked = false;
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnChapter1:
setContentView(R.layout.chapter1_index);
isLooked = true;
break;
case R.id.btnChapter2:
setContentView(R.layout.chapter2_index);
isLooked = true;
break;
case R.id.btnChapter3:
setContentView(R.layout.chapter3_index);
isLooked = true;
break;
case R.id.btnChapter4:
setContentView(R.layout.chapter4_index);
isLooked = true;
break;
}
}
You are setting new content view when back pressed, this is create a new instance of objects for the layout set. But your on click listener is set for the view set in onCreate.
If you really want to set content on back pressed, then you have to findViewById again and set the listener.
I am working in android... I am a newbie in this field... I developed a webview...i need to search for a particular text inside the webview... I searched about some questions like this but i didn't get a proper answer
I did this much code but when executed the webview is showing but the buttons i gave in the code are missing
*
private static final int SEARCH_MENU_ID = Menu.FIRST;
#Override
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);
menu.add(0, SEARCH_MENU_ID, 0, "Search");
return true;
}
public boolean onPrepareOptionsMenu(Menu menu){
super.onPrepareOptionsMenu(menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case SEARCH_MENU_ID:
search();
return true;
}
return true;
}
public void search(){
container = (LinearLayout)findViewById(R.id.lLayout1);
nextButton = new Button(this);
nextButton.setText("Next");
nextButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mWebView.findNext(true);
// TODO Auto-generated method stub
}
});
container.addView(nextButton);
closeButton = new Button(this);
closeButton.setText("Close");
closeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
container.removeAllViews();
// TODO Auto-generated method stub
}
});
container.addView(closeButton);
findBox = new EditText(this);
findBox.setMinEms(30);
findBox.setSingleLine(true);
findBox.setHint("Search");
findBox.setOnKeyListener(new OnKeyListener(){
public boolean onKey(View v, int keyCode, KeyEvent event){
if((event.getAction() == KeyEvent.ACTION_DOWN) && ((keyCode == KeyEvent.KEYCODE_ENTER))){
mWebView.findAll(findBox.getText().toString());
try{
Method m = WebView.class.getMethod("setFindIsUp", Boolean.TYPE);
m.invoke(mWebView, true);
}catch(Exception ignored){}
}
return false;
}
});
}
}
*
While this is an older question, based on AndroidEnthusiastic's version I managed to put together one that was actually working fairly decently. There is a minor error with the type of button on the Samsung Note I tested it on, but no matter how I was changing the IME types, it just got messed up. So I'm just hiding the soft-key keyboard. But the layout is better constructed.
public class SearchDemoActivity extends ActionBarActivity implements View.OnClickListener
{
WebView mWebView;
private RelativeLayout container;
private Button nextButton, closeButton;
private EditText findBox;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
getActionBar().setTitle(R.string.information_display);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.setWebViewClient(new WebViewClient());
mWebView.loadUrl("http://devemat-androidprogramming.blogspot.com/");
nextButton = (Button) findViewById(R.id.nextButton);
closeButton = (Button) findViewById(R.id.closeButton);
findBox = (EditText) findViewById(R.id.findBox);
findBox.setSingleLine(true);
findBox.setOnKeyListener(new OnKeyListener()
{
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if ((event.getAction() == KeyEvent.ACTION_DOWN) && ((keyCode == KeyEvent.KEYCODE_ENTER)))
{
mWebView.findAll(findBox.getText().toString());
try
{
// Can't use getMethod() as it's a private method
for (Method m : WebView.class.getDeclaredMethods())
{
if (m.getName().equals("setFindIsUp"))
{
m.setAccessible(true);
m.invoke(mWebView, true);
break;
}
}
}
catch (Exception ignored)
{
}
finally
{
InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// check if no view has focus:
View vv = getCurrentFocus();
if (vv != null)
{
inputManager.hideSoftInputFromWindow(v.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
return false;
}
});
nextButton.setOnClickListener(this);
closeButton.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.searchview_in_menu, menu);
return true;
}
public boolean onPrepareOptionsMenu(Menu menu)
{
super.onPrepareOptionsMenu(menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.action_search:
search();
return true;
}
return true;
}
public void search()
{
container = (RelativeLayout) findViewById(R.id.layoutId);
if (container.getVisibility() == RelativeLayout.GONE)
{
container.setVisibility(RelativeLayout.VISIBLE);
}
else if (container.getVisibility() == RelativeLayout.VISIBLE)
{
container.setVisibility(RelativeLayout.GONE);
}
}
#Override
public void onClick(View v)
{
if (v == nextButton)
{
mWebView.findNext(true);
}
else if (v == closeButton)
{
container.setVisibility(RelativeLayout.GONE);
}
}
}
The layout XML (activity_search.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<WebView
android:id="#+id/webview"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_below="#+id/layoutId" />
<RelativeLayout
android:id="#+id/layoutId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone" >
<Button
android:id="#+id/closeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Close" />
<Button
android:id="#+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/closeButton"
android:text="Next" />
<EditText
android:id="#+id/findBox"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/nextButton"
android:hint="Enter search keyword here."
android:singleLine="true" />
</RelativeLayout>
</RelativeLayout>
The menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/action_search"
android:icon="#android:drawable/ic_menu_search"
custom:showAsAction="always"
android:title="#string/action_search"/>
</menu>
Please try this snippet
package com.search.demo;
import java.lang.reflect.Method;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
public class SearchDemoActivity extends Activity {
WebView mWebView;
private LinearLayout container;
private Button nextButton, closeButton;
private EditText findBox;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mWebView = (WebView)findViewById(R.id.webview);
mWebView.loadUrl("http://devemat-androidprogramming.blogspot.com/");
}
private static final int SEARCH_MENU_ID = Menu.FIRST;
#Override
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);
menu.add(0, SEARCH_MENU_ID, 0, "Search");
return true;
}
public boolean onPrepareOptionsMenu(Menu menu){
super.onPrepareOptionsMenu(menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case SEARCH_MENU_ID:
search();
return true;
}
return true;
}
public void search() {
container = (LinearLayout) findViewById(R.id.layoutId);
nextButton = new Button(this);
nextButton.setText("Next");
nextButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mWebView.findNext(true);
}
});
container.addView(nextButton);
closeButton = new Button(this);
closeButton.setText("Close");
closeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
container.removeAllViews();
}
});
container.addView(closeButton);
findBox = new EditText(this);
findBox.setMinEms(30);
findBox.setSingleLine(true);
findBox.setHint("Search");
findBox.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) && ((keyCode == KeyEvent.KEYCODE_ENTER))) {
mWebView.findAll(findBox.getText().toString());
try {
Method m = WebView.class.getMethod("setFindIsUp", Boolean.TYPE);
m.invoke(mWebView, true);
} catch (Exception ignored) {
}
}
return false;
}
});
container.addView(findBox);
}
}
I simplified it for my usage
findBox.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
webView.findAll(findBox.getText().toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
nextButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
webView.findNext(true);
}
});
closeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
layoutId.setVisibility(View.GONE);
webView.clearMatches();
closeKeyboard(MainActivity.this);
}
});
To check continuously text from WebView use this code:
webView.setFindListener(new WebView.FindListener() {
#Override
public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches, boolean isDoneCounting) {
webView.findAllAsync("Search Text"); //find text for each foundresult
}
});
UPDATE: Solved! Problem was related to my Viewpager not 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:
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?
Perhaps its android restriction. Try to do this using 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();
}
}
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;
}
});
Actually you can not do directly inside the fragment. The onBackPressed can be overridden in the FragmentActivity. What you can do is:
Override the onBackPressed inside the activity.
When the onBackPressed is called, check if the instance of the current fragment is the instance showing the webview.
If it is, ask the fragment if the webview can go back.
if it is not, call the super or whatever you need
Edit:
#Override
public void onBackPressed() {
Fragment webview = getSupportFragmentManager().findFragmentByTag("webview");
if (webview instanceof MyWebViewFragment) {
boolean goback = ((MyWebViewFragment)webview).canGoBack();
if (!goback)
super.onBackPressed();
}
}
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;
}
}
}
In WebViewActivity.java, I added 1 method:
#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:
public boolean canGoBack() {
return mWebView.canGoBack();
}
public void goBack() {
mWebView.goBack();
}
#RomanBlack's answer gave me the right idea, but since we use kotlin I had to adapt the answer a little bit.
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
There is a simple way with BackPressedDispatcher
Fragment:
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)
}
Activity :
override fun onBackPressed() {
val fragment = supportFragmentManager.findFragmentByTag("WebViewFragment")
if (WebViewFragment::class.java.isInstance(fragment)) {
if (onBackPressedDispatcher.hasEnabledCallbacks()) {
onBackPressedDispatcher.onBackPressed()
return
}
super.onBackPressed()
}
}
Maybe these codes can be improved, but it works very well for me. For more information visit here.
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
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 the onCreateView() 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;
}
#OmidAmnivia answer is correct your app the solution to the crash is
#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.
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.
It will give user a chance to stay in your app when webview cant go back. I felt it more user friendly:
//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
})
First of all get back pressed in 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 && mWebView.canGoBack())
{
mWebView.goBack();
return true;
}
return false;
}
} );
hope it will works.
This worked in my case
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();
}
}
The simplest answer is jut to setOnKeyListeneron into webView itself:
webView.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey( View v, int keyCode, KeyEvent event ) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if( keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()){
webView.goBack();
return true;
}
}
return false;
}
});