Im getting the following error when using the below code
The method onKeyDown(int, KeyEvent) is undefined for the type SherlockFragment
public boolean onKeyDown(int KeyCode, KeyEvent event) {
if ((KeyCode == KeyEvent.KEYCODE_BACK) && web.canGoBack()) {
web.goBack();
return true;
}
return super.onKeyDown(KeyCode, event);
}
I would keep this kind of thing out of your fragment. The following code worked for me in my MainActivity with 4 tabs that each have their own web view.
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
int currPage = mPager.getCurrentItem();
WebView wv = null;
switch (currPage) {
case 0:
wv = (WebView) mPager.getChildAt(currPage).findViewById(R.id.webView1);
break;
case 1:
wv = (WebView) mPager.getChildAt(currPage).findViewById(R.id.webView2);
break;
case 2:
wv = (WebView) mPager.getChildAt(currPage).findViewById(R.id.webView3);
break;
case 3:
wv = (WebView) mPager.getChildAt(currPage).findViewById(R.id.webView4);
break;
}
if (wv != null) {
if (wv.canGoBack()) {
wv.goBack();
} else {
super.onBackPressed();
}
} else {
super.onBackPressed();
}
}
edit: I ran into trouble on my 4th tab and the solution for me was to set the webView in my fragment(Tab0.java) static. Then directly referencing it in my main activity.
switch (currPage) {
case 0:
wv = Tab0.webView;
break;
case 1:
wv = Tab1.webView;
break;
case 2:
wv = Tab2.webView;
break;
case 3:
wv = Tab3.webView;
break;
}
The Activity should manage the back button not the fragment. If you want the fragment to manage the onKeyDown, you can attach the OnKeyListener, on the view returned by getView()
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.left, container, false);
view.setOnKeyListener( new OnKeyListener() {
#Override
public boolean onKey( View v, int keyCode, KeyEvent event ) {
// here your code
}
});
return view;
}
After done few research. i found this !
Hopefully its help.
root =(ViewGroup) inflater.inflate(R.layout.setting_f_other, container, false);
root.setOnKeyListener( new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event ) {
if (keyCode == KeyEvent.KEYCODE_BACK){
//Do something
}
return false;
}
});
Related
Sorry for my bad English. I have BottomNavigationView in my app such as in Facebook and viewPager to scrool the fragments with swipe but I have some problems in function onPageSelected, it always set position to 4. This is the code of MainActivity:
private static final int NUM_PAGES = 5;
BottomNavigationView bottomNavigationView;
ViewPager viewPager;
PagerAdapter pagerAdapter;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_tests:
viewPager.setCurrentItem(0);
return true;
case R.id.navigation_courses:
viewPager.setCurrentItem(1);
return true;
case R.id.navigation_profile:
viewPager.setCurrentItem(2);
return true;
case R.id.navigation_leaderboard:
viewPager.setCurrentItem(3);
return true;
case R.id.navigation_settings:
viewPager.setCurrentItem(4);
return true;
}
return false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.pager);
pagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
bottomNavigationView = findViewById(R.id.navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
viewPager.setCurrentItem(2);
bottomNavigationView.getMenu().findItem(R.id.navigation_profile).setChecked(true);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
switch (position) {
case 0:
setTitle("Tests");
bottomNavigationView.setSelectedItemId(R.id.navigation_tests);
case 1:
setTitle("Courses");
bottomNavigationView.setSelectedItemId(R.id.navigation_courses);
case 2:
setTitle("Profile");
bottomNavigationView.setSelectedItemId(R.id.navigation_profile);
case 3:
setTitle("Leaderboard");
bottomNavigationView.setSelectedItemId(R.id.navigation_leaderboard);
case 4:
setTitle("Settings");
bottomNavigationView.setSelectedItemId(R.id.navigation_settings);
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
#Override
public void onBackPressed() {
if (viewPager.getCurrentItem() == 2) {
super.onBackPressed();
} else if (viewPager.getCurrentItem() >= 3) {
viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);
} else {
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
}
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FragmentTests();
case 1:
return new FragmentCourses();
case 2:
return new FragmentProfile();
case 3:
return new FragmentLeaderboard();
case 4:
return new FragmentSettings();
}
return null;
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
}
This is the image of app
Then it it again move me to settings .And when I tap on profile
You need to write break statement in switch case of ViewPager onPageSelected method like below
#Override
public void onPageSelected(int position) {
switch (position) {
case 0:
setTitle("Tests");
bottomNavigationView.setSelectedItemId(R.id.navigation_tests);
break;
case 1:
setTitle("Courses");
bottomNavigationView.setSelectedItemId(R.id.navigation_courses);
break;
case 2:
setTitle("Profile");
bottomNavigationView.setSelectedItemId(R.id.navigation_profile);
break;
case 3:
setTitle("Leaderboard");
bottomNavigationView.setSelectedItemId(R.id.navigation_leaderboard);
break;
case 4:
setTitle("Settings");
bottomNavigationView.setSelectedItemId(R.id.navigation_settings);
break;
}
}
I created an onTouchListener for my ImageView "car" and want to do the same for another ImageView, however I can't figure out how. So my question is:
How do you use one onTouchListener that detects the MotionEvents of two separate ImageViews and makes something happen accordingly?
#Override
public boolean onTouch(View view, MotionEvent event) {
//int action = event.getAction();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
carcolor.setBackgroundColor(this.getResources().getColor(R.color.colorPrimary));
car.startAnimation(pressdown);
pressdown.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
carback.setScaleX((float) 0.9);
carback.setScaleY((float) 0.9);
}
#Override
public void onAnimationEnd(Animation animation) {
carback.setVisibility(View.VISIBLE);
car.setVisibility(View.INVISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
car.startAnimation(release);
carcolor.setBackgroundColor(this.getResources().getColor(R.color.unpressed));
release.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
carback.setVisibility(View.INVISIBLE);
}
#Override
public void onAnimationEnd(Animation animation) {
car.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
You should implement the onTouchListener like:
imageView.setOnTouchListener(this);
and init it like :
#Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
switch (view.getId()){
case R.id.car1: // example id
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_CANCEL:
break;
}
break;
case R.id.car2: // example id
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_CANCEL:
break;
}
break;
}
return true;
}
If your activity is implementing the onTouchListener event (I'm assuming based on the override), on your other ImageView just do the following
imageView.setOnTouchListener(this);
Where this is the current activity.
EDIT: Based on your comment
public class ImageView1Listener implements OnTouchListener
{
**** OVERRIDES****
}
public class ImageView2Listener implements OnTouchListener{
**** OVERRIDS FOR THIS IMAGE****
}
then in your main remove the implements OnTouchListener and use bind it programatically
imageView1.setOnClickListener(new ImageViewListener1());
imageView2.setOnClickListener(new ImageViewListener2());
Attach the listener to the parent of them.
Than, use gesturesDetector as stated here:
https://developer.android.com/training/gestures/detector.html
public class MainActivity extends Activity implements
GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener{
private static final String DEBUG_TAG = "Gestures";
private GestureDetectorCompat mDetector;
// Called when the activity is first created.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Instantiate the gesture detector with the
// application context and an implementation of
// GestureDetector.OnGestureListener
mDetector = new GestureDetectorCompat(this,this);
// Set the gesture detector as the double tap
// listener.
mDetector.setOnDoubleTapListener(this);
}
#Override
public boolean onTouchEvent(MotionEvent event){
this.mDetector.onTouchEvent(event);
// Be sure to call the superclass implementation
return super.onTouchEvent(event);
}
#Override
public boolean onSingleTapConfirmed(MotionEvent event) {
Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());
return true;
}
....
}
I have a Click function and long press on the same button. Implemented the long press event but, I need to find the button UP_EVENT and DOWN_EVENTS separately.
How can I implement by using the OnLongClickListener
View.OnLongClickListener listener = new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
return true;
}
};
Implement a TouchListener within the onLongClickListener:
View.OnLongClickListener listener = new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// PRESSED
return true; // if you want to handle the touch event
case MotionEvent.ACTION_UP:
// RELEASED
return true; // if you want to handle the touch event
}
return false;
}
});
return true;
}
};
To detect ACTION_UP and ACTION_DOWN events you need to implement OnTouchListener.
to sepate , you can do this way
#Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (isOnClick) {
//TODO onClick code
}
break;
case MotionEvent.ACTION_MOVE:
}
break;
default:
break;
}
return true;
}
In my fragment activity am using the webview.when i am clicking on the hyperlink on the webview its redirecting to the specified url its fine.but the problem is when i am clicking on back it is redirected to the home fragment instead of the previos page.Can anyone help me how to redirect to the previous page on the webview.Below is my code in the mainactivity where i am handling the fragment onback press events.
private void selectItem(int position) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
// Locate Position
Fragment fragment = null;
switch (position) {
case 0:
//ft.replace(R.id.content_frame, frag,"home");
fragment=new Fagmentmain();
/*startActivity(new Intent(MainActivity.this,Category.class));*/
break;
case 1:
//ft.replace(R.id.content_frame, webfrag,"web");
fragment=new WebFragment();
/*Intent intent=new Intent(MainActivity.this,News.class);
intent.putExtra("pos",0);
startActivity(intent);*/
//startActivity(new Intent(MainActivity.this,News.class));
break;
case 2:
//ft.replace(R.id.content_frame, aboutfrag,"about");
Intent intent1=new Intent(MainActivity.this,News.class);
intent1.putExtra("pos",1);
startActivity(intent1);
break;
case 3:
Intent intent2=new Intent(MainActivity.this,News.class);
intent2.putExtra("pos",2);
startActivity(intent2);
break;
}
/*ft.commit();
mDrawerList.setItemChecked(position, true);
setTitle(title[position]);
mDrawerLayout.closeDrawer(mDrawerList);*/
if(fragment != null){
FragmentManager fragmanager=getSupportFragmentManager();
fragmanager.beginTransaction().replace(R.id.content_frame,fragment).addToBackStack("").commit();
mDrawerList.setItemChecked(position, true);
setTitle(title[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
FragmentManager fm = getSupportFragmentManager();
//FragmentTab1 frag=(FragmentTab1)getSupportFragmentManager().findFragmentById(arg0)
if (fm.getBackStackEntryCount() > 0) {
Log.e("back stack entry", fm.getBackStackEntryCount() + "");
fm.popBackStack();
}
}
solved the problem by adding following code in my Fragment
webview.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack() ){
webview.goBack();
return true;
}
return false;
}
});
I have created an app which shows multiple webpages. I want that app to share image which is displayed on that webpage with whatsapp and other IM messengers, for that i have added a context menu and have implemented ACTION_SEND but it didn't work. When i try to share image it gives me error "sharing failed please try again" Here is my code
public class TopRatedFragment extends Fragment {
private ProgressBar progress;
private WebView myWebView2;
private Menu optionsMenu;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_top_rated, container, false);
String url = "http://images.google.com";
myWebView2 = (WebView) rootView.findViewById(R.id.webViewTop);
myWebView2.setWebChromeClient(new myWebViewClient());
myWebView2.getSettings().setJavaScriptEnabled(true);
progress = (ProgressBar) rootView.findViewById(R.id.progressBar3);
progress.setMax(100);
setHasOptionsMenu(true);
myWebView2.loadUrl(url);
myWebView2.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView View, String url) {
View.loadUrl(url);
TopRatedFragment.this.progress.setProgress(0);
return true;
}
});
myWebView2.setOnKeyListener(new android.view.View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
WebView webView = (WebView) v;
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
if (webView.canGoBack()) {
webView.goBack();
return true;
}
break;
}
}
return false;
}
});
return rootView;
}
#Override
public void onCreateOptionsMenu(
Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main, menu);
optionsMenu = menu;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle item selection
switch (item.getItemId()) {
case R.id.airport_menuRefresh:
TopRatedFragment.this.myWebView2.reload();
setRefreshActionButtonState(true);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, v.getId(), 0, "Call");
menu.add(0, v.getId(), 0, "share image");
}
#Override
public boolean onContextItemSelected(MenuItem item){
if(item.getTitle()=="Call"){
Toast.makeText(getActivity(), "calling code", Toast.LENGTH_LONG).show();
}
else if(item.getTitle()=="share image")
{
// This is the code which i am using for share intent
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("image/*");
share.putExtra(Intent.EXTRA_STREAM, Uri.parse(Environment.getExternalStorageState()));
startActivity(Intent.createChooser(share, "Share image using"));
}else{
return false;
}
return true;
}
Thanks for your help!
This line looks strange
share.putExtra(Intent.EXTRA_STREAM, Uri.parse(Environment.getExternalStorageState()));
The stream extra is supposed to contain the uri to the image you want to share, but you are setting it to something I don't even understand what it's supposed to do - that wouldn't even evaluate to a uri.
Currently you are not supplying the intent with any information on WHAT content you want to send. Set the stream extra to the image location uri and you should be fine.
(Btw you really should compare strings using equals() rather than ==. And you shouldn't identify menu item on titles as it would fail when localized etc. Use the menu item id.)