I am starting the NavigationPage in the App.cs class:
MainPage = new NavigationPage(new PageA());
In PageA(), I am are calling "PushAsync":
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void btnCourseList_Clicked(object sender, EventArgs e)
{
Navigation.PushAsync(new PageB());
}
}
If I click back button on PageB(), it goes to PageA() in which it has two tool bars.
Any idea how to fix this?
The reason for it is very simple you are providing two navigation pages in the page lifecycle which is in turn showing two Navbar's
Solution :
In your App.xaml.cs add a static NavigationPage property something like this:
public static NavigationPage NavigationPage { get; set; }
Assign this a Page in your app.xaml constructor something like this :
App.NavigationPage = new NavigationPage(new yourPage) ;
Then Assign this NavigationPage as your MainPage like this:
MainPage=App.NavigationPage;
Now Whenever you plan on going to the next page call the next page like this:
App.NavigationPage.PushAsync(new YourNewPage());
Goodluck!
In case of queries revert.
Related
I try to do list of usb devices, connected by serial odt with smartphone, within xamarin.forms.
To do that I use this project https://github.com/anotherlab/UsbSerialForAndroid
How to do listview in shared project with devices from Project.Droid.MainActivity? I tried to do that with dependency service:
This is my Page1(where I want to have listview):
public partial class Page1 : ContentPage {
public Page1()
{
InitializeComponent();
DependencyService.Get<Interface1>().moj();
}
}
My interface:
namespace SensDxMobileApp.Views.MainWindow {
public interface Interface1 {
void moj();
}
}
And MyActivity(Droid project):
[assembly: Xamarin.Forms.Dependency(typeofProject.Droid.MainActivity))]
namespace Project.Droid {
public class MainActivity: Interface
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
listView = new Android.Widget.ListView;
}
public async void moj()
{
adapter = new UsbSerialPortAdapter(this);
listview.Adapter = adapter;
listView.ItemClick += async (sender, e) =>
{
await OnItemClick(sender, e);
};
await PopulateListAsync();
detachedReceiver = new UsbDeviceDetachedReceiver(this);
RegisterReceiver(detachedReceiver, new IntentFilter(UsbManager.ActionUsbDeviceDetached));
}
}
But I have an error "Object reference not set to an instance of an object.", on " DependencyService.Get().moj()" in Page1();
Did someone do something similar? Thanks
If you going the DependencyService route, then you'll want to create a separate class that implements Interface1 and registering that as a dependency service. I don't think you can register the MainActivity as a DependencyService implementation.
One problem that you are going to hit this is mostly async code and callbacks.
You also shouldn't be newing up an Android ListView as a DependencyService call. That would be better suited as a custom renderer. As a DependencyService implementation, you would want the moj() method to return data that can be consumed by the Xamarin.Forms code. You would need more than just that method. You would need code to initialize the UsbSerialPort class, code to query the list of devices, and then invoke a callback that sends back that list, In theory anyway. I never tested that library with Forms.
I'm trying to set page icon. There is App class of PCL below.
public App()
{
CustomMainPage mainPage = new CustomMainPage();
NavigationPage rootPage = new NavigationPage(mainPage);
this.MainPage = rootPage;
}
What I tried to do?
NavigationPage.SetTitleIcon(mainPage, "icon.png");
The second approach.
NavigationPage.SetTitleIcon(this, "icon.png");
The third approach.
NavigationPage.SetTitleIcon(rootPage, "icon.png");
File icon.png is situated into Resources/drawable.
And finally I decided to implement my custom renderer for the NavigationPage in Xamarin Forms. NavigationPage is setted to MainPage property into App class of PCL.
I created DroidNavigationRenderer class into Android project.
[assembly: ExportRenderer(typeof(NavigationPage), typeof(DroidNavigationPageRenderer))]
namespace App1.Droid.DroidRenderers
{
public class DroidNavigationPageRenderer : NavigationPageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<NavigationPage> e)
{
base.OnElementChanged(e);
var actionBar = ((Activity)Context).ActionBar;
actionBar.SetIcon(Resource.Drawable.icon);
}
}
}
But actionBar is always returns as null.
What I do wrong and how to fix it?
In your ContentPage, you have the Icon property.
You can set it this way
Icon = Device.OnPlatform("Menu", "ic_fa_bars.png", "Assets/Icons/reload.png");
What is your CustomMainPage class? If I have TabbedPage and set one of its child I do it this way:
var navigationPage = new NavigationPage(mainPage);
if (Device.RuntimePlatform == Device.iOS)
{
navigationPage.Icon = "services.png";
}
hope it helps
I declare my main page:
public App () {
MainPage = new NavigationPage(new MainPage());
}
Then on main page open ContantPage after tapping a button:
class MainPage : ContentPage {
public MainPage() {
button.Clicked += to_my_contentpage;
//...
}
private async void to_my_contentpage(object sender, EventArgs e) {
await Navigation.PushModalAsync(new my_contentpage());
//using PushAsync doesn't help
}
}
And try to show button on this page as ToolbarItem:
public class my_contentpage : ContentPage {
public my_contentpage () {
ToolbarItem AddButton = new ToolbarItem("AddButton", "AddIcon.png", () => {
Console.WriteLine("Clicked");
});
this.ToolbarItems.Add(new ToolbarItem());
//...
this.Content = new StackLayout { Children = { header, listView } };
}
}
I feel like doing everithing according to this answer but my ToolbarItem is not included to my page:
How do i add toolbar for android in xamarin,forms as ToolbarItem is not working for .droid?
What am I doing wrong?
PushModalAsync is not going to work in this case, since you need to have a Navigation Bar in order to add ToolBarItems to it.
Since a Modal page explicitly does not show/contain a NavigationBar you are not going to be able to do it this way.
Solutions:
Create a Custom NavigationBar and add any Views you need to it.
Do not use a Modal Page.
Hope this helps.
I am having a weird issue, Xamarin Forms App works fine when I setup Content page as a startup page. If I set TabbedPage as a startup and same ContentPage as a Children of a TabbedPage then it doesn't display/data-bind ContentPage. No errors. What am I missing any idea? Here is my TabbedPage view model.
using MvvmCross.Core.ViewModels;
using System.Windows.Input;
namespace Company.Mobile.ViewModels
{
public class TabbedMainViewModel
: MvxViewModel
{
}
}
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:forms="using:Xamarin.Forms"
xmlns:local="clr-namespace:company.Mobile.Pages;assembly=company.Mobile"
x:Class="company.Mobile.Pages.TabbedMainPage"
Title="Title">
<TabbedPage.Children>
<local:HomePage/>
<local:MainPage/>
<local:ResourcesPage/>
<local:ContactPage/>
</TabbedPage.Children>
</TabbedPage>
After a lot of trial and error and help from the community, here is what worked.
Set BindingContext to the ContentPage code-behind C#, something like below:
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
var svc = Mvx.Resolve<IMobileService>();
BindingContext = new HomeViewModel(svc);
}
}
Get your data in HomeViewModel constructor something like below:
public class HomeViewModel : MvxViewModel
{
private readonly IMobileService service;
public HomeViewModel(IMobileService service)
{
this.service = service;
//Content = service.GetContent; //Get your data
}
}
I would say that you can do that easier by adding this inline property for an each your tabbed page in XAML, e.g. for the home page it should be BindingContext="{Binding HomePageViewModel}"
So I have a View:
public class RadialMenuWidget extends View
from where I want to start a thread like I do from an activity
String urlInput = "http://myserver.com/"+mynewfile;
DownloaderThread downloaderThread = new DownloaderThread(UpdateActivity, urlInput);
downloaderThread.start();
but I get the message "Expression expected" on this line "DownloaderThread(UpdateActivity,... " more specifically on the activity name (UpdateActivity) even though I imported the activity inside the Widget.
What can I do to avoid this while still being able to call the thread.
The idea is, I use the RadialMenuWidget, and inside the RadialMenuWidget class I test to see which menu button was pressed and based on that, I decide what to do next. Calling other intents works just fine, but now I want to start to download a file using a separate thread (that I can call from a regular activity's onButtonClick)
EDIT
So my radialMenu has this structure:
public class RadialMenuWidget extends View {
...
public interface RadialMenuEntry {
...
}
public RadialMenuWidget(Context context) {
...
}
#Override
public boolean onTouchEvent(MotionEvent e) {
...
if (state == MotionEvent.ACTION_UP) {
...
if (menuEntries.get(i).getName() == "Update now") {
String urlInput = "http://myhost.com/"+mynewfile;
DownloaderThread downloaderThread = new DownloaderThread(this.UpdateActivity, urlInput);
downloaderThread.start();
}
}
...
And the DownloadThread class looks like this:
public class DownloaderThread extends Thread {
public DownloaderThread(UpdateActivity inParentActivity, String inUrl)
{
downloadUrl = "";
if(inUrl != null)
{
downloadUrl = inUrl;
}
parentActivity = inParentActivity;
}
#Override
public void run()
{
// does the download
}
...
}
Please help.
Thank you
My solution in the end was to mimic a 2 button radial menu using images. I used the images as backgrounds for a button, placed them in a linear layout, used 9-patch images and got to call the thread onClick like before. So I avoided having to deal with radialMenuWidget in this view.
So question is over now.
I was hoping for a java solution to this problem since I am a newbie and eager to learn anything Android, but this is it, I will manage with my (ugly) solution.