I'm using NavigationView on a embedded layout, I'm trying to transfert the layout to another layout bu it crash - mapbox-android

I'm trying to use the NavigationView on a embedded layout and trying to "move" the layout to another contentview, but it crash has soon I remove the View from the parent with:
Attempt to invoke virtual method 'void com.mapbox.services.android.navigation.ui.v5.MultiOnClickListener.clearListeners()' on a null object reference]
I have a simple class with:
public class clsNavigationView extends CoordinatorLayout implements OnNavigationReadyCallback, MapboxMap.OnMapLongClickListener,
NavigationListener, ProgressChangeListener, InstructionListListener, SpeechAnnouncementListener,
BannerInstructionsListener, OnTrackingModeChangedListener
...
inflate(getContext(), R.layout.mapbox_activity_embedded_navigation, this);
...
The layout have
<com.mapbox.services.android.navigation.ui.v5.NavigationView
android:id="#+id/navigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navigationDarkTheme="#style/NavigationViewDark"
app:navigationLightTheme="#style/NavigationViewLight"/>
I put the clsNavigationView on a static FrameLayout, I add it to my mainView on another FrameLayout.
When I change view, I remove the view with:
((FrameLayout) objFrameMap.getParent()).removeView(objFrameMap);
Do my new setContentview on my main Activity.
Then I add back my Frame into my new FrameLayout on the new Content
((FrameLayout) findViewById(R.id.layer_mapview)).addView(objFrameMap);
It crash at the removeView, what can I do for fixing that?
What is the best way for "move" a NavigationView without crashing?
** I'm not using fragment.

Related

How can I create a Custom Renderer for a ContentView in Xamarin.Forms MacOS?

We're using Xamarin.Forms with MacOS, and have a custom view MyCustomView : Xamarin.Forms.ContentView, and I'm trying to create a custom view renderer for our view, but it's interfering with the rendered view.
Does anyone know how to create a view renderer in my platform project?
This is the code I've tried so far, looking at similar places:
[assembly: Xamarin.Forms.ExportRenderer(typeof(MyCustomView), typeof(MyCustomViewRenderer))]
namespace Mac.Renderers
{
public class MyCustomViewRenderer : ViewRenderer<Xamarin.Forms.ContentView, AppKit.NSView>
{
public MyCustomViewRenderer()
{
// My implementation
}
}
}
Event when the implementation is left blank, having this custom renderer is affecting the display of the ContentView, so I think this code must not be right - is there a way to do this?
You could fix your issue by changing your class to inherit from VisualElementRenderer<T> instead.
[assembly: Xamarin.Forms.ExportRenderer(typeof(MyCustomView), typeof(MyCustomViewRenderer))]
namespace Mac.Renderers
{
public class MyCustomViewRenderer : VisualElementRenderer<ContentView>
{
public MyCustomViewRenderer()
{
// My implementation
}
}
}
Page has a default Renderer "PageRenderer", do not understand why ContentView does not. It would be nice if there was a ContentViewRenderer.
Hope this helps.-

Crash for second view object's name assign

I am new to Xamarin and MVVMCross. So I have created 2 views. Login and Register. I have a button on Login to goto Register view and I am going there by this code in the Login's ViewModel:
// method when user tap register button
public IMvxCommand NavigateRegister
{
get { return new MvxCommand(() => ShowViewModel<RegisterViewModel>()); }
}
It works ok the Register Page opens well. But once I assign Name for a single object on Register view (a textEdit), the app crash when I tap on the Register button.
Below is the error msg:
Xamarin.iOS: Received unhandled ObjectiveC exception:
NSUnknownKeyException [
setValue:forUndefinedKey:]: this class is not key value
coding-compliant for the key regNameEdit.
EDIT:
More details: I already assigned the name (see pic below), but still crash:
And the view also been assigned to its Class "CreateAccount". But I am noticing the class declaration has "partial" darkened out in the "public partial class CreateAccount : MvxViewController" line. That's the only noticeable difference btw this class and the first one.
using MvvmCross.Binding.BindingContext;
using MvvmCross.iOS.Views;
namespace MyApp.iOS.Views
{
public partial class CreateAccount : MvxViewController
{
public CreateAccount() : base("CreateAccount", null)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
Title = "Register";
var set = this.CreateBindingSet<CreateAccount, Core.ViewModels.CreateAccountModel>();
set.Bind(regNameEdit).To(vm => vm.NameStr);
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
}
}
The Bind(regNameEdit) also is an error (not detecting the textedit still)
This usually means that the a control is not defined in the View/ViewController class in your case the regNameEdit.
Make sure you created the back Property for this Edit and that the class assigned to the XIB is the one containing this property.
If you are using Xamarin Studio Designer you create the back property selecting the UIControl in the XIB/StoryBoard and setting a name, then enter.
This will create a property with the name you specified accessible in the ViewController.
public override void ViewDidLoad()
{
base.ViewDidLoad();
this.MyUITextField.Text = string.Empty;
}
UPDATE
When using Storyboard:
Try this: Remove the name from the TextField and also remove the name from the ViewController class, then clean your project and rebuild. Re-add the class to the ViewController but when doing it click over the yellow icon in the bottom, there put the name and hit enter. Continue with the TextField, select it put the name and hit enter.
UPDATE # 2
When using XIBs
When you create the ViewController from the menu, Xamarin Studio will create both the ViewController class and the XIB file and will associate one with the other so here you don't have to do anything else to link them.
For the TextField you will need to do it adding the name as previously indicated.
Try this: Remove the name of the UITextField and save and clean/rebuild the project then add the name and hit enter.
Something you can do to verify if there's any problem, double click on the button in the XIB and this should take you to the ViewController class to create a method.
Hope this helps.

How to create an ActionDrawer with a single action

as pointed out in the google guidelines: https://www.google.com/design/spec-wear/components/action-drawer.html#action-drawer-usage
at 'Single Action', an ActionDrawer should not be expandable.
My question is, how to achieve that behaviour?
I've tried an WearableActionDrawer and WearableDrawerView..
I've also tried the method lockDrawerClosed() but the drawer still opens on click.
Thanks for your help! :)
Edit:
Ok, I found the solution to stop the drawer from opening. I'm using the WearableActionDrawer now and calling lockDrawerClosed(). But now I'm not sure how to change the peek_view properly.
I made a custom view - LinearLayout - which is containing an ImageView. I'm using this view for mWearableActiondrawer.setPeekView(myView). But the problem is, that the view will not be shown properly. It just shows me an empty ActionDrawer at the bottom.
But the clicklistener is working..
Here is my code:
// Bottom Action Drawer
mWearableActionDrawer = (WearableActionDrawer) findViewById(R.id.bottom_action_drawer);
mWearableActionDrawer.lockDrawerClosed();
LayoutInflater layoutInflater =
(LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
LinearLayout view =
(LinearLayout) layoutInflater.inflate(R.layout.action_drawer_peek_view, null);
mWearableActionDrawer.setPeekContent(view);
view.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
Toast.makeText(getApplicationContext(), "Hello", Toast.LENGTH_SHORT).show();
}
});
Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/action_drawer_peek_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/wearable_primary"
android:orientation="vertical"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:src="#drawable/fill_1_copy"
/>
</LinearLayout>
Any thoughts of what I'm doing wrong here? Thanks!
I don't see any error as compared to this sample code. It stated that if you only have a single action for your Action Drawer, you can use a (custom) View to peek on top of the content by calling mWearableActionDrawer.setPeekContent(View). Just make sure you set a click listener to handle user clicking on your View.
You may also try using mWearableDrawerLayout.peekDrawer(Gravity.BOTTOM);. Check again your implementation based on this documentation which shows how to initialize the contents of your drawers.

How to present an iOS Modal View in MvvmCross

How can I present a modal view on iOS using MvvmCross?
Using Xamarin Studio on iOS and the MvvmCross NuGet version 4.2.2, none of the MvxModalSupportTouchViewPresenter, MvxModalNavSupportTouchViewPresenter or IMvxModalTouchView are even available.
Does the ViewModel even need to know about the fact that a particular view is presented as a modal view on iOS?
MvvmCross is a strong Page navigation framework. Default navigation using ShowViewModel<AViewModel> will use the stack metaphor: one on top of another on Android, slide atop each other on iOS, and use < on either platform to go back.
You can tell the ViewPresenter that a given view is modal by giving it a hint, in the form of an interface marker, by adopting IMvxModalIosView.
At the View Level
Adopt the IMvxModalIosView protocol:
public partial class AView : MvxViewController, IMvxModalIosView
At the AppDelegate Level
Replace var setup = new Setup(this, Window) by:
var presenter = new MvxModalSupportIosViewPresenter(this, Window);
var setup = new Setup(this, presenter);
setup.Initialize();
At the ViewModel Level
No change required. The ViewModel is actually not made aware of the modal presentation. Invoke:
ShowViewModel<AViewModel> // May be modal on certain platforms
To close a Page and go back to the previous one, regardless of your presentation style, use Close(this) on that very ViewModel. This will close a modal dialog, or pop a pushed view. A complete, bindable ICommand may look like this:
public ICommand BackCommand {
get { return new MvxCommand(() => Close(this)); }
}
Notes: In MvvmCross 4.2.2, Touch has been renamed iOS, so IMvxModalTouchView is now IMvxModalIosView. The new using are:
using MvvmCross.iOS.Platform;
using MvvmCross.iOS.Views.Presenters;
Using MvvmCross 5.5.2 all I had to get a modal was to add the following MvxModalPresentation attribute to my iOS view:
[Register("ExampleModalView")]
[MvxModalPresentation(
ModalPresentationStyle = UIModalPresentationStyle.PageSheet,
ModalTransitionStyle = UIModalTransitionStyle.CoverVertical
)]
public class ExampleModalView : MvxViewController
{
public ExampleModalView() {
}
...
}
Launching the modal is simple with the IMvxNavigationService service
await _navigationService.Navigate<ExampleModalViewModel>();
ExampleModalViewModel just needs to be a plain MvvmCross view model inheriting from MvxViewModel.
A useful reference for this is ModalView.cs in the iOS playground project: https://github.com/MvvmCross/MvvmCross/blob/develop/TestProjects/Playground/Playground.iOS/Views/ModalView.cs#L12

Bind a custom control created as UIView in Interface Builder via monotouch

Using monotouch and monodevelop, I'd like to create a custom control.
I followed this steps:
add a new file as "iPhone View" (calling it TestView)
edit TestView.xib in Interface Builder, es. changing it's background and size
edit MainWindow.xib in Interface Builder, adding a UIView and setting it's class identity as "TestView".
At this point, I'd like to launch the application and see in the UIView of MainWindow the content of an instance of TestView.
In order to get this "binding" I tried several steps (I know it can be done via code creating the outlets, etc.., but I'd like to understand if it can be done via Interface builder).
In one of the methods tried, I set via Interface Builder the value "TestView" as class identifier in the View of TestView.xib: in this way MonoTouch created the code in TestView.xib.designer.cs.
[MonoTouch.Foundation.Register("TestView7")]
public partial class TestView7 {
}
Then, in TestView.xib.cs, I added:
public partial class TestView : UIView
{
public TestView (IntPtr p) : base(p)
{
}
}
When I launch the app, I cannot see in the view of MainWindow the content of TestView, but if in TestView constructor I add something such as
BackgroundColor = UIColor.Yellow;
then, I can see TestView in MainWindow... or better I can see only the yellow rectangle, not the real content!
So, the problem is that TestView is binded to the UIView in MainWindow, but it's content comes only from the code and not from the content defined via Interface Builder in TestView.xib.
Is there a way to load the content from the TestView.xib?
Take a look at http://ios.xamarin.com/Documentation/API_Design#Interface_Builder_Outlets_and_C.23
I believe what you need to do is add a constructor that handles the nib file (The following is from the above link):
When using MonoTouch your application will need to create a class that derives from UIViewController and implement it like this:
public class MyViewController : UIViewController {
public MyViewController (string nibName, NSBundle bundle) : base (nibName, bundle)
{
// You can have as many arguments as you want, but you need to call
// the base constructor with the provided nibName and bundle.
}
}
Then to load your ViewController from a NIB file, you do this:
var controller = new MyViewController ("HelloWorld", NSBundle.MainBundle, this);
This loads the user interface from the NIB.
The answer by Allison A in SO question monotouch - reusable iOS custom view, explains how to load existing composite views created in Interface Builder into a custom view.

Resources