1
votes

My goal is to create an Android UI window that displays three regions: navigation, main, and popup. The navigation and main region will function as a split view. The popup region will be centered in the screen and overlay the other two regions; it will also only be visible part of the time. Ideally, I'd like these regions to host fragments that are dynamically changed to display different layouts and view models based on user interaction. And, all of this should be accomplished without breaking the MvvmCross bindings.

I've got something that works, but it feels a bit hacked together. The current implementation most closely follows resource 1 below. Each region has a dictionary. All of the fragments are registered with a dictionary based on their target region. This is done from the activity. The activity also takes care of inflating each layout and associating it with the correct view model. I’d like to change this so that MvvmCross can do more of the work.

Is it possible to create a custom presenter, in Android, that is a mix between the dynamic fragment layout from resource 2 and the iOS custom presenter shown in resource 3? Just to clarify, I want to specifically define where each region will be displayed using a layout. Then I want to dynamically fill the content, of each region, with different layouts and their associated view models, at runtime.


Resource 1: MvvmCross v3 Fragment Sample

https://github.com/slodge/MvvmCross-Tutorials/tree/master/Fragments

See: “FragmentSample.UI.Droid/Views/TitlesView.cs” and “FragmentSample.UI.Droid/Setup.cs”

Resource 2: N=26 - Androids… down at Fragment Rock

http://www.youtube.com/watch?feature=player_embedded&v=uQT3_WXQQr0

Dynamic Fragment Layout created explained at 26:25 – 32:10

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
  <FrameLayout
    android:id="@+id/subframe1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    />
  <FrameLayout
    android:id="@+id/dubframe1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    />
</LinearLayout>

(In addition to being an extremely helpful video, of all the N+1 videos I've had a chance to watch, this one has the best intro!)

Resource 3: N=24 - Split View

http://www.youtube.com/watch?feature=player_embedded&v=PpeysFIINcY

iOS SplitPresenter created at 11:25 – 15:05

public class SplitViewController : UISplitViewController
    {
        public SplitViewController()
        {
            this.ViewControllers = new UIViewController[]
                {
                    new UIViewController(), 
                    new UIViewController(), 
                };
        }

        public void SetLeft(UIViewController left)
        {
            this.ViewControllers = new UIViewController[]
                {
                    left,
                    this.ViewControllers[1]
                };
        }

        public void SetRight(UIViewController right)
        {
            this.ViewControllers = new UIViewController[]
                {
                    this.ViewControllers[0],
                    right,
                };
        }
    }
1
Stuart, the blog post was helpful in figuring this out. I referenced it a few times while creating the example project. Thanks. - Josh

1 Answers

1
votes

I created a small example project on GitHub that demonstrates how to create multiple regions.

Picture of example project on GitHub

This shows the three regions: Navigation, Main and Popup. The location, size and shape of each region is defined in one layout file. The content is defined, with separate layout files and view models, for each region and is dynamically changed at runtime. MvvmCross bindings still work with each individual view model.


EDIT

I added a more robust solution example on github. This allows the ViewModel to be opened in the standard way. The MultiRegionPresenter handles matching up the view with the correct region by looking at a tag in the view. Views are now tagged with their intended region like this: [Region(Resource.Id.MainRegion)].

The new example project is located here: MultiRegionPresenter Example