问题
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.
<?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);
}
}
回答1:
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.
回答2:
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 <mariotaku.lee@gmail.com>
*
* 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.
回答3:
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
.
回答4:
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);
}
});
}
}
}
回答5:
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)
来源:https://stackoverflow.com/questions/12208037/android-child-view-height-not-match-parent-in-listview-item