Search code examples
androidmvvmcross

MvxFrameLayout derived class doesn't draw child


I created a test MvxFrameLayout derived class, which I want to draw a child at 0,0 with size 24x24:

    public class MyCustomLayout : MvxFrameLayout
    {
        public MyCustomLayout(Context context, IAttributeSet attrs) : base(context, attrs)
        {
        }

        public MyCustomLayout(Context context, IAttributeSet attrs, IMvxAdapterWithChangedEvent adapter) : base(context, attrs)
        {
        }

        protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
        {
            if (!changed)
            {
                return;
            }
            for (int i = 0; i < this.ChildCount; ++i)
            {
                var child = this.GetChildAt(i);
                child.Layout(0, 0, 24, 24);
            }
        }
    }

Which is used in an activity layout (FirstView.axml) like this:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <hotspotappandroid.droid.views.MyCustomLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        local:MvxBind="ItemsSource Hotspots"
        local:MvxItemTemplate="@layout/hotspot" />
</FrameLayout>

The view model which has one item:

public class FirstViewModel : MvxViewModel
{
    public string[] Hotspots { get; private set; }

    public FirstViewModel()
    {
        this.Hotspots = new string[] { "A" };
    }
}

The hotspot.xml is an ImageView with an image (circle.png) of 24x24:

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:src="@drawable/circle" />

The problem is the circle image is not being drawn.

If in hotspot.xml I change android:layout_width="fill_parent" and android:layout_height="fill_parent to wrap_content, the image is drawn, but not correctly. The image is drawn in half. It looks like the image is drawn scaled to double of its size and it's cropped by half (probably due to `child.Layout(0, 0, 24, 24)).

I am not sure what is going on. I see that the child in OnLayout is of type cirrious.mvvmcross.binding.droid.views.MvxListItemView instead of 'ImageView' because that I would have expected. Maybe that has something to do?


Solution

  • The MvxFrameLayout works by inflating a child MvxListItemView for each child. The MvxListItemView itself inherits from FrameLayout and has default layout parameters.

    According to the docs - http://developer.android.com/reference/android/widget/FrameLayout.html - this means each child FrameLayout should be sized:

    The size of the FrameLayout is the size of its largest child (plus padding), visible or not (if the FrameLayout's parent permits)

    Since you are specifying fill_parent for the ImageView inner grandchildren here, then I guess that is what is causing your inner views to be zero-sized.

    In order to give your child frames some size, it might be better to give them ImageView sizes directly in the inner child XML, instead of requesting fill_parent


    If you do want to return an ImageView directly and to use that as the Child - without the intermediate MvxListItemView then in the latest MvvmCross source I believe you can: