Android child view height not match parent in ListView item
Asked Answered
N

5

11

As described, my List item is a FrameLayout, there are two views inside.

ColorView is a custom view I made for show color in whole view.

(FrameLayout's height is "wrap_content")

It seems work well on my ICS device, but doesn't work on my Android 2.2 emulator and Android 1.6 G1.

ICS

Donut

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <org.mariotaku.twidere.view.ColorView
        android:id="@+id/status_background"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:background="@drawable/ic_label_user"/>

    <RelativeLayout
        android:id="@+id/status_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="6dp"
        android:paddingRight="6dp"
        android:paddingTop="6dp">

        <org.mariotaku.twidere.view.RoundCorneredImageView
            android:id="@+id/profile_image"
            android:layout_width="@dimen/profile_image_size"
            android:layout_height="@dimen/profile_image_size"
            android:layout_marginLeft="6dp"
            android:scaleType="fitCenter"/>

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_alignWithParentIfMissing="true"
            android:layout_marginLeft="6dp"
            android:layout_toLeftOf="@+id/time"
            android:layout_toRightOf="@+id/profile_image"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="?android:attr/textColorPrimary"
            android:textStyle="bold"/>

        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/name"
            android:layout_alignParentRight="true"
            android:layout_alignWithParentIfMissing="true"
            android:layout_below="@+id/name"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="?android:attr/textColorSecondary"/>

        <TextView
            android:id="@+id/time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/name"
            android:layout_alignParentRight="true"
            android:layout_alignWithParentIfMissing="true"
            android:drawablePadding="3dp"
            android:gravity="center_vertical|right"
            android:textColor="?android:attr/textColorSecondary"/>

        <ImageView
            android:id="@+id/image_preview"
            android:layout_width="@dimen/preview_image_size"
            android:layout_height="@dimen/preview_image_size"
            android:layout_alignWithParentIfMissing="true"
            android:layout_below="@+id/text"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="3dp"
            android:layout_toRightOf="@+id/profile_image"
            android:background="@drawable/image_preview_background"
            android:drawablePadding="3dp"
            android:scaleType="fitCenter"
            android:visibility="gone"/>

        <TextView
            android:id="@+id/reply_retweet_status"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignWithParentIfMissing="true"
            android:layout_below="@+id/image_preview"
            android:layout_toRightOf="@+id/profile_image"
            android:drawablePadding="3dp"
            android:paddingLeft="6dp"
            android:paddingTop="3dp"
            android:textColor="?android:attr/textColorSecondary"/>
    </RelativeLayout>

    <TextView
        android:id="@+id/list_gap_text"
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:layout_gravity="center"
        android:gravity="center"
        android:text="@string/tap_to_load_more"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textStyle="bold"
        android:visibility="gone"/>

</FrameLayout>

does it have any workaround or other way to solve this?

EDIT

code for ColorView

package org.mariotaku.twidere.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;

public class ColorView extends View {

    private int mColor = Color.TRANSPARENT;

    public ColorView(Context context) {
        this(context, null);
    }

    public ColorView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ColorView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setColor(int color) {
        mColor = color;
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(mColor);
    }

}
Norven answered 31/8, 2012 at 2:7 Comment(4)
Upvote to help you get attention.Sounder
Can you add the code for ColorView?Watertight
And which one of the layout views is the strip on the left?Watertight
it's background of ColorView, a 9patch drawable. !IMGNorven
N
3

so sad, nobody knows how to deal with this.

but finally I used a workaround to solve this problem.

new layout XML:

<?xml version="1.0" encoding="utf-8"?>
<org.mariotaku.twidere.view.ColorLabelRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="6dp">

    <org.mariotaku.twidere.view.RoundCorneredImageView
        android:id="@+id/profile_image"
        android:layout_width="@dimen/profile_image_size"
        android:layout_height="@dimen/profile_image_size"
        android:scaleType="fitCenter"/>

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignWithParentIfMissing="true"
        android:layout_marginLeft="3dp"
        android:layout_toLeftOf="@+id/time"
        android:layout_toRightOf="@+id/profile_image"
        android:singleLine="true"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="?android:attr/textColorPrimary"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/name"
        android:layout_alignParentRight="true"
        android:layout_alignWithParentIfMissing="true"
        android:layout_below="@+id/name"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="?android:attr/textColorSecondary"/>

    <TextView
        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/name"
        android:layout_alignParentRight="true"
        android:layout_alignWithParentIfMissing="true"
        android:drawablePadding="3dp"
        android:gravity="center_vertical|right"
        android:textColor="?android:attr/textColorSecondary"/>

    <ImageView
        android:id="@+id/image_preview"
        android:layout_width="@dimen/preview_image_size"
        android:layout_height="@dimen/preview_image_size"
        android:layout_alignWithParentIfMissing="true"
        android:layout_below="@+id/text"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="3dp"
        android:layout_toRightOf="@+id/profile_image"
        android:background="@drawable/image_preview_background"
        android:drawablePadding="3dp"
        android:scaleType="fitCenter"
        android:visibility="gone"/>

    <TextView
        android:id="@+id/reply_retweet_status"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignWithParentIfMissing="true"
        android:layout_below="@+id/image_preview"
        android:layout_toRightOf="@+id/profile_image"
        android:drawablePadding="3dp"
        android:paddingLeft="6dp"
        android:paddingTop="3dp"
        android:textColor="?android:attr/textColorSecondary"/>

    <TextView
        android:id="@+id/list_gap_text"
        android:layout_width="wrap_content"
        android:layout_height="42dp"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="@string/tap_to_load_more"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textStyle="bold"
        android:visibility="gone"/>

</org.mariotaku.twidere.view.ColorLabelRelativeLayout>

code for ColorLabelRelativeLayout:

/*
 *              Twidere - Twitter client for Android
 * 
 * Copyright (C) 2012 Mariotaku Lee <[email protected]>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.mariotaku.twidere.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.RelativeLayout;

public class ColorLabelRelativeLayout extends RelativeLayout {

    private final Paint mPaintLeft = new Paint(), mPaintRight = new Paint(), mPaintBackground = new Paint();
    private final Rect mRectLeft = new Rect(), mRectRight = new Rect(), mRectBackground = new Rect();
    private final float mDensity;       

    public ColorLabelRelativeLayout(Context context) {
        this(context, null);
    }

    public ColorLabelRelativeLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ColorLabelRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setWillNotDraw(false);
        mDensity = context.getResources().getDisplayMetrics().density;
        mPaintLeft.setColor(Color.TRANSPARENT);
        mPaintRight.setColor(Color.TRANSPARENT);
        mPaintBackground.setColor(Color.TRANSPARENT);
    }

    public void drawLabel(int left, int right, int background) {
        mPaintBackground.setColor(background);
        mPaintLeft.setColor(left);
        mPaintRight.setColor(right);
        invalidate();
    }

    public void drawLeft(int color) {
        drawLabel(color, mPaintRight.getColor(), mPaintBackground.getColor());
    }

    public void drawRight(int color) {
        drawLabel(mPaintLeft.getColor(), color, mPaintBackground.getColor());
    }

    public void drawBackground(int color) {
        drawLabel(mPaintLeft.getColor(), mPaintRight.getColor(), color);
    }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawRect(mRectBackground, mPaintBackground);
        canvas.drawRect(mRectLeft, mPaintLeft);
        canvas.drawRect(mRectRight, mPaintRight);
        super.onDraw(canvas);
    }

    @Override
    public void onSizeChanged(int w, int h, int oldw, int oldh) {
        mRectBackground.set(0, 0, w, h);
        mRectLeft.set(0, 0, (int)(4 * mDensity), h);
        mRectRight.set(w - (int)(4 * mDensity), 0, w, h);
        super.onSizeChanged(w, h, oldw, oldh);
    }
}

it works really well for me.

screenshot on G1

Norven answered 2/9, 2012 at 11:36 Comment(0)
F
16

We just had to deal with a similar problem. We noticed that using match_height on a view that is part of a ListView item will not work as expected. The following code should work:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@+id/color_bar" >

        <!-- Put the content views of your item here. You do not have to use frame layout, it can be any kind of view. -->

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="8dp"
            android:text="@string/app_name" />
    </FrameLayout>

    <View
        android:id="@id/color_bar"
        android:layout_width="10dp"
        android:layout_height="match_parent"
        android:layout_alignBottom="@id/content"
        android:layout_alignParentRight="true"
        android:layout_alignTop="@id/content"
        android:background="@android:color/darker_gray" />

</RelativeLayout>

The trick is basically to align the coloured view to the top and bottom of the content view. Whatever the height of the content is, it will be adopted by the coloured view.

On a side note, as stated in the Android's documentation, you should not use a FrameLayout to contain more than one child.

EDIT

My colleague made me notice that if we use a LinearLayout as the root element of the listview item, match_parent works as expected:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/content"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:padding="8dp"
        android:text="@string/app_name" />

    <View
        android:id="@+id/color_bar"
        android:layout_width="10dp"
        android:layout_height="match_parent"
        android:background="@android:color/darker_gray" />

</LinearLayout>

I tested this on a device with Android 2.2 and it worked correctly.

Freyah answered 15/10, 2013 at 3:17 Comment(0)
N
3

so sad, nobody knows how to deal with this.

but finally I used a workaround to solve this problem.

new layout XML:

<?xml version="1.0" encoding="utf-8"?>
<org.mariotaku.twidere.view.ColorLabelRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="6dp">

    <org.mariotaku.twidere.view.RoundCorneredImageView
        android:id="@+id/profile_image"
        android:layout_width="@dimen/profile_image_size"
        android:layout_height="@dimen/profile_image_size"
        android:scaleType="fitCenter"/>

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignWithParentIfMissing="true"
        android:layout_marginLeft="3dp"
        android:layout_toLeftOf="@+id/time"
        android:layout_toRightOf="@+id/profile_image"
        android:singleLine="true"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="?android:attr/textColorPrimary"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/name"
        android:layout_alignParentRight="true"
        android:layout_alignWithParentIfMissing="true"
        android:layout_below="@+id/name"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="?android:attr/textColorSecondary"/>

    <TextView
        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/name"
        android:layout_alignParentRight="true"
        android:layout_alignWithParentIfMissing="true"
        android:drawablePadding="3dp"
        android:gravity="center_vertical|right"
        android:textColor="?android:attr/textColorSecondary"/>

    <ImageView
        android:id="@+id/image_preview"
        android:layout_width="@dimen/preview_image_size"
        android:layout_height="@dimen/preview_image_size"
        android:layout_alignWithParentIfMissing="true"
        android:layout_below="@+id/text"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="3dp"
        android:layout_toRightOf="@+id/profile_image"
        android:background="@drawable/image_preview_background"
        android:drawablePadding="3dp"
        android:scaleType="fitCenter"
        android:visibility="gone"/>

    <TextView
        android:id="@+id/reply_retweet_status"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignWithParentIfMissing="true"
        android:layout_below="@+id/image_preview"
        android:layout_toRightOf="@+id/profile_image"
        android:drawablePadding="3dp"
        android:paddingLeft="6dp"
        android:paddingTop="3dp"
        android:textColor="?android:attr/textColorSecondary"/>

    <TextView
        android:id="@+id/list_gap_text"
        android:layout_width="wrap_content"
        android:layout_height="42dp"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="@string/tap_to_load_more"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textStyle="bold"
        android:visibility="gone"/>

</org.mariotaku.twidere.view.ColorLabelRelativeLayout>

code for ColorLabelRelativeLayout:

/*
 *              Twidere - Twitter client for Android
 * 
 * Copyright (C) 2012 Mariotaku Lee <[email protected]>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.mariotaku.twidere.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.RelativeLayout;

public class ColorLabelRelativeLayout extends RelativeLayout {

    private final Paint mPaintLeft = new Paint(), mPaintRight = new Paint(), mPaintBackground = new Paint();
    private final Rect mRectLeft = new Rect(), mRectRight = new Rect(), mRectBackground = new Rect();
    private final float mDensity;       

    public ColorLabelRelativeLayout(Context context) {
        this(context, null);
    }

    public ColorLabelRelativeLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ColorLabelRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setWillNotDraw(false);
        mDensity = context.getResources().getDisplayMetrics().density;
        mPaintLeft.setColor(Color.TRANSPARENT);
        mPaintRight.setColor(Color.TRANSPARENT);
        mPaintBackground.setColor(Color.TRANSPARENT);
    }

    public void drawLabel(int left, int right, int background) {
        mPaintBackground.setColor(background);
        mPaintLeft.setColor(left);
        mPaintRight.setColor(right);
        invalidate();
    }

    public void drawLeft(int color) {
        drawLabel(color, mPaintRight.getColor(), mPaintBackground.getColor());
    }

    public void drawRight(int color) {
        drawLabel(mPaintLeft.getColor(), color, mPaintBackground.getColor());
    }

    public void drawBackground(int color) {
        drawLabel(mPaintLeft.getColor(), mPaintRight.getColor(), color);
    }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawRect(mRectBackground, mPaintBackground);
        canvas.drawRect(mRectLeft, mPaintLeft);
        canvas.drawRect(mRectRight, mPaintRight);
        super.onDraw(canvas);
    }

    @Override
    public void onSizeChanged(int w, int h, int oldw, int oldh) {
        mRectBackground.set(0, 0, w, h);
        mRectLeft.set(0, 0, (int)(4 * mDensity), h);
        mRectRight.set(w - (int)(4 * mDensity), 0, w, h);
        super.onSizeChanged(w, h, oldw, oldh);
    }
}

it works really well for me.

screenshot on G1

Norven answered 2/9, 2012 at 11:36 Comment(0)
W
1

Is a requirement to use the ColorView? I ask this because if you don't use it for anything else it's just a waste to use it. You have the parent FrameLayout and you should set the drawable used on the ColorView as the background for the parent FrameLayout.

Watertight answered 1/9, 2012 at 10:15 Comment(4)
root view is used for another background in multi select mode, ColorView is not only used for background but also for that color label.Norven
@Norven Multi select mode meaning what(contextual action bar)? Isn't easier to simply change the background on the Framelayout depending on the current situation?Watertight
for backward compatibility I used some workarounds i.imgur.com/F4X9t.png this works on Android 1.6, by changing FrameLayout background. you can see full source code here. github.com/mariotaku/twidereNorven
@Norven The codebase is to big for me to look and find the problem. You should revise the code for the list row, I have a feeling that you complicated the logic. Also 1.6 represents about 0.5% of the android phones out there, you could drop 1.6 and switch to Eclair(if this forcing you to use various "hacks").Watertight
T
0

Create a custom Layout extends FrameLayout, or other layouts whatever, then override the onLayout method.

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);

    Log.d("onLayout", getWidth() + "x" + getHeight());

    final View statusView = findViewById(R.id.status_background);
    if (statusView.getVisibility() == VISIBLE) {
        final LayoutParams p = (LayoutParams) statusView.getLayoutParams();
        if (p.width != getWidth() || p.height != getHeight()) {
            p.width = getWidth();
            p.height = getHeight();
            statusView.post(new Runnable() {
                @Override
                public void run() {
                    statusView.setLayoutParams(p);
                }
            });
        }
    }
}
Terri answered 28/4, 2014 at 6:59 Comment(0)
C
0

An update to @softlete answer:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/transparent">

    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp">

    <RelativeLayout
        android:id="@+id/messageContent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:layout_marginRight="20dp"
        android:layout_marginLeft="20dp"
        android:padding="5dp"
        android:background="@drawable/message_bg">

        <TextView
            android:id="@+id/message"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginRight="20dp"
            android:text="un mensaje supremamente largo debe ir aqui para probar el layout"
            android:textColor="@android:color/black"
            android:textSize="16dp"/>

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/imageContainer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:paddingTop="10dp"
        android:paddingBottom="10dp">

        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/image"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:src="@drawable/com_facebook_profile_default_icon" />

    </RelativeLayout>

    </RelativeLayout>

</LinearLayout>

The "Minimum height" is given by the margins(top+bottom) of @+id/imageContainer plus +height of @+id/image(can use any view/layout that you want)

Comitative answered 30/1, 2015 at 5:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.