I have a MainActivity which has 3 fragments. 2 of these fragments have lists in them and on click of a list item I go to another activity (ie. NewActivity). I have an ActionBar implemented on the NewActivity and want to go back to the calling fragment from this activity.
I have the following code:
MainActivity.cs
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
SupportActionBar.SetDisplayShowHomeEnabled(true);
var ft = SupportFragmentManager.BeginTransaction();
ft.Add(Resource.Id.fragment_container, homeFragment, "FRAG_HOME").SetBreadCrumbShortTitle("FRAG_HOME");
ft.Add(Resource.Id.fragment_container, FragmentList1, "FRAG_LIST1").SetBreadCrumbShortTitle("FRAG_LIST1");
ft.Hide(FragmentList1);
ft.Add(Resource.Id.fragment_container, FragmentList2, "FRAG_LIST2").SetBreadCrumbShortTitle("FRAG_LIST2");
ft.AddToBackStack(null);
ft.Hide(FragmentList2);
ft.Commit();
FragmentList1.cs
void LvLatestArticles_ItemClick (object sender, AdapterView.ItemClickEventArgs e)
{
Intent intent = new Intent(Activity, typeof(NewActivity));
StartActivity(intent);
}
NewActivity.cs
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch(item.ItemId)
{
case Android.Resource.Id.Home:
SupportFragmentManager.PopBackStackImmediate();
break;
}
return base.OnOptionsItemSelected(item);
}
In the above code, I override the Home button functionality on ActionBar. But it simply does not do anything. How do I go forward with this? Any help would be appreciated
Try calling OnBackPressed() on the Home button. Something like so :-
public override bool OnOptionsItemSelected(IMenuItem item){
switch(item.ItemId){
case Android.Resource.Id.Home:
base.OnBackPressed();
break;
}
return base.OnOptionsItemSelected(item);
}
Related
I'm trying to link the hardware back button into my WebViews in Xamarin for Android. My WebViews are contained within OnCreate instances of TabHost (which is deprecated, but I'm using it anyway) I've got this inside my MainActivity : TabActivity class
public override void OnBackPressed()
{
base.OnBackPressed();
}
and here's an example of one of my Tab Activity Classes
[Activity]
public class SpeakersActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
//set the content view
SetContentView(Resource.Layout.subs);
//declare webview and tell our code where to find the XAML resource
WebView subWebView = FindViewById<WebView>(Resource.Id.webViewSubs);
//set the webview client
subWebView.SetWebViewClient(new WebViewClient());
//load the subscription url
subWebView.LoadUrl("https://www.bitchute.com/subscriptions/");
//enable javascript in our webview
subWebView.Settings.JavaScriptEnabled = true;
//zoom control on? This should perhaps be disabled for consistency?
//we will leave it on for now
subWebView.Settings.BuiltInZoomControls = true;
subWebView.Settings.SetSupportZoom(true);
//scrollbarsdisabled
// subWebView.ScrollBarStyle = ScrollbarStyles.OutsideOverlay;
subWebView.ScrollbarFadingEnabled = false;
}
}
and I've seen a lot information how to use this
subWebView.GoBack();
to goback in a webview, but the problem is that my WebViews are not within the scope of my hardware back button. The hardware back button is inside mainactivity class and my webviews are inside individual instances of the tab activities.
What's the best way to correct this issue? Thank you!
Thanks so much #SushiHangover !!!
I solved it like this:
[Activity]
public class SpeakersActivity : Activity
{
public override void OnBackPressed()
{
WebView subWebView = FindViewById<WebView>(Resource.Id.webViewSubs);
subWebView.GoBack();
}
}
EDIT: the way you do this with a ViewPager and Fragment is as follows:
//put this code in your MainActivity.cs
public override bool OnKeyDown(Android.Views.Keycode keyCode, KeyEvent e)
{
if (e.KeyCode == Android.Views.Keycode.Back)
{
switch (_viewPager.CurrentItem)
{
case 0:
_fm1.WebViewGoBack();
break;
case 1:
_fm2.WebViewGoBack();
break;
case 2:
_fm3.WebViewGoBack();
break;
case 3:
_fm4.WebViewGoBack();
break;
case 4:
_fm5.WebViewGoBack();
break;
}
}
return false;
}
then in a fragment instantiate WebView assign in OnCreate and create a method for going back inside Fragment :
protected static WebView _wv;
protected static View _view;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
_view = inflater.Inflate(Resource.Layout.TheFragmentLayout1, container, false);
_wv = _view.FindViewById<WebView>(Resource.Id.webView1);
//lots of code
}
public void WebViewGoBack()
{
if (_wv.CanGoBack())
_wv.GoBack();
}
I need to ignore a page while navigating back, I tried the following:
public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
{
if (args.NavigationMode == NavigationMode.Back)
{
args.Cancel = true;
NavigationService.Navigate(typeof(MainPage));
} else {
args.Cancel = false;
}
await Task.CompletedTask;
}
On the page that I am navigating away from, but it seems to only cancel the navigation.
What is the best way to tackle this issue?
In the page that you want to ignore, you can add the following method. This will allow to remove the current page from the navigation history.
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// here NavigationService is supposed to be an instance of Template10 INavigationService
var backStack = NavigationService.FrameFacade.BackStack;
if (backStack.Count > 0 && backStack.Last().SourcePageType == this.GetType())
{
backStack.Remove(backStack.Last());
}
base.OnNavigatedFrom(e);
}
I want to display a toast Message. If I'd do this in onCreate() it'd work fine. But I want to do it like this and I get an error:
Java.Lang.NullPointerException: Attempt to invoke virtual method
'android.content.res.Resources android.content.Context.getResources()'
on a null object reference
What should I do?
public void textToast(string textToDisplay) {
Toast.MakeText(this,
textToDisplay, ToastLength.Long).Show();
}
class SampleTabFragment : Fragment
{
Button add;
MainActivity main = new MainActivity();
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
var view = inflater.Inflate(Resource.Layout.Tab, container, false);
add = view.FindViewById<Button>(Resource.Id.add);
add.Click += Click;
return view;
}
void Click(object sender, EventArgs eventArgs)
{
main.textToast( "I like Toast!");
}
}
The Java.Lang.NullPointerException is triggered because you are manually creating and using an instance of MainActivity.
Instead of using a custom instance of MainActivity to display your toast message in Click, simplify your code to use the fragments existing activity reference:
public void textToast(string textToDisplay) {
Toast.MakeText(this,
textToDisplay, ToastLength.Long).Show();
}
class SampleTabFragment : Fragment
{
Button add;
// Remove manual creation code
// MainActivity main = new MainActivity();
// ...
void Click(object sender, EventArgs eventArgs)
{
(Activity as MainActivity).textToast( "I like Toast!");
}
}
This code assumes that the owning activity is always an instance of MainActivity.
See:
Fragment getActivity()
How to use the method of an Activity in a DialogFragment?
If I understand correctly your question, I think a good solution may be this one:
public void makeToast(Context ctx, string str)
{
Toast.MakeText(ctx, str, ToastLength.Long).Show();
}
And when you use it in every fragment you have, you can call it just writing:
makeToast(this.Activity, "test!");
Works for me, let me know :)
I want to create a simple option menu in Android application with c# and Xamarin Studio. How can I do it?
I haven't found any C# example of this. Can someone simply explain how to create a option menu, please?
Defining the menu
One way to create a menu is using a XML file placed in the Resources/menu/ folder of your Xamarin.Android project.
For example:
Resources/Menu/mymenu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/item1"
android:title="Item 1"/>
<item android:id="#+id/item2"
android:title="Item 2"/>
<item android:id="#+id/item3"
android:title="Item 3"/>
</menu>
To see what other options you can define in a menu xml file, please see the official documentation.
Using the menu
You can inflate a xml menu in multiple locations.
A few examples:
In a Toolbar
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.mytoolbar);
toolbar.InflateMenu(Resource.Menu.mymenu);
Handle clicks
To handle click events on a toolbar menu you have to implement the Toolbar.IOnMenuItemClickListener interface by overriding the following method:
public bool OnMenuItemClick(IMenuItem item)
{
switch (item.ItemId)
{
case Resource.Id.item1:
//Do stuff for item1
return true;
case Resource.Id.item2:
//Do stuff for item2
return true;
case Resource.Id.item3:
//Do stuff for item3
return true;
default:
return false;
}
}
You then have to add the class implementing the interface to the toolbar as a listener:
toolbar.SetOnMenuItemClickListener(your_listener_class);
In the default menu location of an Activity or Fragment (DEPRECATED)
In most cases the default menu location of an activity or fragment is either the hardware menu button or the ActionBar.
Adding a menu here can be accomplished by the overriding the following method:
In a Activity:
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.mymenu, menu);
return true;
}
In a Fragment:
public override void OnCreateOptionsMenu(IMenu menu, MenuInflater inflater)
{
inflater.Inflate(Resource.Menu.mymenu, menu);
}
Make sure you have HasOptionsMenu set to true in the onCreate of the Fragment for this to work.
Handle clicks
You can then handle clicks to the menu by overriding OnOptionsItemSelected
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Resource.Id.item1:
//Do stuff for item1
return true;
case Resource.Id.item2:
//Do stuff for item2
return true;
case Resource.Id.item3:
//Do stuff for item3
return true;
default:
return false;
}
}
After we have handled the selected item we return true to notify the system of this.
Alternative: Creating a menu programatically
A very basic menu is accomplished by overriding the OnCreateOptionsMenu method like this:
public override bool OnCreateOptionsMenu(IMenu menu)
{
menu.Add(0,0,0,"Item 0");
menu.Add(0,1,1,"Item 1");
menu.Add(0,2,2,"Item 2");
return true;
}
You can then handle clicks in the option menu by overriding the OnOptionsItemSelected method.
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case 0:
//Do stuff for item 0
return true;
case 1:
//Do stuff for item 1
return true;
case 2:
//Do stuff for item 2
return true;
default:
return false;
}
}
I have tried many ways, but haven't succeeded.
In this way I can create a new UIBarButtonItem and it works, the problem is that it dosent lock like a backButton/ArrowBackButton:
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
this.NavigationItem.LeftBarButtonItem = new UIBarButtonItem ("Tillbaka", UIBarButtonItemStyle.Plain, delegate(object sender, EventArgs e) {
this.NavigationController.PopViewControllerAnimated (true);
});
}
Have tried this, but haven't worked:
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
this.NavigationItem.SetHidesBackButton(false,true);
}
With MonoTouch.Dialog you have to set a "pushing" flag in order for it to show the back button. You can do this in the constructor, as indicated below:
public class MyViewController : DialogViewController
{
public MyViewController
: base(new RootElement("foo"), true)
{
}
}
Can you give some context to this please? How is this ViewController being added to the NavigationController ?
If you use the PushViewController method (as below) then a back button will be automatically added.
var viewController = new UIViewController();
this.NavigationController.PushViewController(viewController, true);