Sweeper
Sweeper

Reputation: 271060

LinearLayout leaving out too much white space. Why?

I am writing an Android app that helps little kids learn maths. It gives the user some questions and the user would answer them. If he/she answers all of them correctly, a prize would be given. Now I need to tell the user about this in the ResultsActivity. Here is how it looks like:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                android:orientation="horizontal"
                tools:context="com.smartkidslovemaths.ResultsActivity">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:id="@+id/left_side"
        android:orientation="vertical"
        android:gravity="center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/score_label"
            android:textSize="@dimen/score_label_size"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="100"
            android:id="@+id/score_value"
            android:textSize="@dimen/score_size"/>
    </LinearLayout>

    <View
        android:layout_width="1dp"
        android:layout_height="match_parent"
        android:background="#FF0000FF" />

    <ScrollView
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/right_side"
            android:layout_margin="@dimen/question_display_margin"
            android:orientation="vertical">

        </LinearLayout>
    </ScrollView>

</LinearLayout>

As you can see, the left side of the screen is used to display the score. The right side (The LinearLayout with the id right_side) is empty because it would have different things in it depending on whether the user answers all the questions correctly. If he/she doesn't, it would display which question(s) did he/she did wrongly. That means I need to add views dynamically to the LinearLayout. After a few tries, I am able to display the prize that the user gets and some text telling him/her. However, there are lots of empty between the text and the ImageView! Here is a screen shot:

enter image description here

Hope you don't mind that this is Chinese. As you can see, there are lots of space between the tip of the star and the text. (I even need to scroll down a little to see the star!) Now here is my code to add the views:

private void displayPrize () { //This is called in the onCreate() method
    Resources res = getResources ();
    int marginAll = (int)res.getDimension (R.dimen.prize_display_margin);
    FrameLayout.LayoutParams parentParams = new FrameLayout.LayoutParams (FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
    parentParams.setMargins (marginAll, marginAll, marginAll, marginAll);
    ((LinearLayout)findViewById (R.id.right_side)).setLayoutParams (parentParams);

    TextView text = new TextView (this);
    final LinearLayout.LayoutParams textParams =
            new LinearLayout.LayoutParams (
                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT
            );

    final LinearLayout.LayoutParams imageParams =
            new LinearLayout.LayoutParams (
                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT
            );
    text.setLayoutParams (textParams);
    QuestionOptions options = QuestionsActivity.Options.getOptions ();

    switch (options.getDigitCount ()) {
        case 1:
        default:
            text.setText (res.getText (R.string.earn_star_text));
            break;
        case 2:
            text.setText (res.getText (R.string.earn_badge_text));
            break;
        case 3:
            text.setText (res.getText (R.string.earn_trophy_text));
            break;
    }

    text.setTextSize (res.getDimension (R.dimen.answer_text_size) / 1.5F);

    ((LinearLayout)findViewById (R.id.right_side)).addView (text);

    ImageView image = new ImageView (this);
    image.setLayoutParams (imageParams);
    int resID = QuestionOptionMaps.getOptionsDrawableMap ().get (options);
    image.setImageResource (resID);
    ((LinearLayout)findViewById (R.id.right_side)).addView (image);
}

I tired a lot of times by changing those wrap_content and match_parent stuff. And every time it didn't work. I even tried to add weights to the views! And I'm sure that the image is a perfect square so the white space isn't caused by the image.

Just for clarity, here is the dimens.xml and strings.xml

<resources>
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="question_margin">25dp</dimen>

    <dimen name="customize_menu_title">15pt</dimen>
    <dimen name="customize_menu_radio">13pt</dimen>
    <dimen name="question_text_size">20pt</dimen>
    <dimen name="answer_text_size">12pt</dimen>

    <dimen name="radio_button_spacing">20dp</dimen>
    <dimen name="item_spacing">20dp</dimen>

    <dimen name="score_label_size">20pt</dimen>
    <dimen name="score_size">40pt</dimen>
    <dimen name="question_display_margin">4dp</dimen>
    <dimen name="prize_display_margin">32dp</dimen>
</resources>

<resources>
    <string name="app_name">Smart Kids Love Maths</string>

    <string name="button_trophies">My Prizes</string>
    <string name="button_start">Start!</string>

    <string name="digit_text">Number of digits</string>
    <string name="operator_text">Operation</string>
    <string name="timer_enabled_text">Timer Enabled</string>
    <string name="title_activity_questions">Smart Kids Love Maths</string>

    <string name="title_activity_results">Results</string>
    <string name="score_label">Your Score:</string>

    <string name="correct_text">Correct!</string>
    <string name="wrong_text">Wrong!</string>
    <string name="correct_answer_text">Correct Answer: </string>
    <string name="earn_trophy_text">You earned a new trophy!</string>
    <string name="earn_badge_text">You earned a new badge!</string>
    <string name="earn_star_text">You earned a new star!</string>
</resources>

Can you tell me why this is happening and how can I fix this?

Upvotes: 3

Views: 755

Answers (1)

wrkwrk
wrkwrk

Reputation: 2351

If the imageView is larger than its parent, use imageView.setAdjustViewBounds(true) to keep its size ratio.

You can see the differences between the attached images.

    LinearLayout linear = (LinearLayout) findViewById(R.id.left);
    TextView textView = new TextView(this);
    textView.setText("Test Right 1");
    textView.setTextSize(32);
    LinearLayout.LayoutParams tParams = new LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    linear.addView(textView, tParams);

    ImageView imageView = new ImageView(this);
    imageView.setImageResource(R.mipmap.img);
    imageView.setAdjustViewBounds(true); // This is the trick
    LinearLayout.LayoutParams iParams = new LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    linear.addView(imageView, iParams);

before set

after

Upvotes: 2

Related Questions