Search code examples
androidandroid-layoutviewflipper

FILL_PARENT inside a ViewFlipper inside a Dialog with no title


I'm trying to create a ViewFlipper where each child View has some minimum size (based on their contents) but each should fill the outer ViewFlipper. So I thought if I make the size of each child FILL_PARENT, it'll do exactly what I'd like.

However, it seems what happens is the size of each child is calculated individually, then the maximum is taken and that's what the size of the ViewFlipper is, but the layout of the children is not re-calculated to match this new size. The weird thing is, this seems to happen only if FEATURE_NO_TITLE is set.

Below is a demonstration of the problem. Child 0 is sized FILL_PARENT x FILL_PARENT, and child 1 is 100x100, so the size of the ViewFlipper is correctly determined to be 100x100. However, child 0 is not resized to be 100x100; in fact, it has size 0x0 (as you can tell when running the app and seeing the red rectangle with no trace of green on it). However, if you remove the line

this.requestWindowFeature(Window.FEATURE_NO_TITLE);

then it works as expected... What's going on here?

The code:

package com.example.flipper;

import android.app.Activity;
import android.os.Bundle;
import android.view.*;
import android.widget.*;

public class MainActivity extends Activity
{
    ViewFlipper flipper;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        this.requestWindowFeature(Window.FEATURE_NO_TITLE);

        this.flipper = new ViewFlipper(this);
        flipper.setBackgroundColor(0xffff0000);

        {
            LinearLayout ll = new LinearLayout(this);
            ll.setBackgroundColor(0xff00ff00);
            flipper.addView (ll, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
        }

        {
            LinearLayout ll = new LinearLayout(this);
            ll.setBackgroundColor(0xff0000ff);
            flipper.addView (ll, new ViewGroup.LayoutParams(100, 100));
        }

        setContentView(flipper);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e)
    {
        flipper.setDisplayedChild(1);
        return true;
    }
}

the manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.flipper"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:label="@string/app_name" >
        <activity android:name="MainActivity"
                  android:theme="@android:style/Theme.Dialog"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest> 

Solution

  • It seems I was able to solve this with a kludge: I wrapped the ViewFlipper in a LinearLayout and set that as the activity's view:

    LinearLayout llOuter = new LinearLayout(this);
    llOuter.addView(flipper, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
    
    setContentView(llOuter);