Высота дочернего вида Android не соответствует родительскому элементу в элементе ListView

Как описано, мой элемент списка – это FrameLayout , внутри него есть два вида.

ColorView – это пользовательское представление, которое я сделал для отображения цвета в целом.

(Высота FrameLayout – «wrap_content»)

Кажется, это хорошо работает на моем устройстве ICS, но не работает на моем эмуляторе Android 2.2 и Android 1.6 G1.

ICS

Пончик

 <?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> 

Есть ли у него какое-либо решение или другой способ решить эту проблему?

РЕДАКТИРОВАТЬ

Код для 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); } } 

Solutions Collecting From Web of "Высота дочернего вида Android не соответствует родительскому элементу в элементе ListView"

Нам просто пришлось иметь дело с подобной проблемой. Мы заметили, что использование match_height в представлении, являющемся частью элемента ListView, не будет работать должным образом. Следующий код должен работать:

 <?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> 

Фокус в основном заключается в выравнивании цветного представления в верхней и нижней части содержимого. Какова бы ни была высота контента, он будет принят цветным представлением.

На стороне примечания, как указано в документации Android , вы не должны использовать FrameLayout, чтобы содержать более одного ребенка.

РЕДАКТИРОВАТЬ

Мой коллега заметил, что если мы используем LinearLayout в качестве корневого элемента элемента listview, match_parent работает так, как ожидалось:

 <?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> 

Я тестировал это на устройстве с Android 2.2, и он работал правильно.

Так грустно, никто не знает, как с этим бороться.

Но, наконец, я использовал обходное решение для решения этой проблемы.

Новый макет 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> 

Код для 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); } } 

Это работает очень хорошо для меня.

Скриншот на G1

ColorView ли использование ColorView ? Я спрашиваю об этом, потому что, если вы не используете его ни для чего другого, это просто отходы, чтобы использовать его. У вас есть родительский FrameLayout и вы должны установить drawable, используемый в ColorView в качестве фона для родительского FrameLayout .

Создание настраиваемого макета расширяет FrameLayout или другие макеты, а затем переопределяет метод onLayout.

 @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); } }); } } } 

Обновление для ответа @softlete:

 <?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> 

«Минимальная высота» задается полями (верхняя + нижняя) для @+id/imageContainer плюс + высота @+id/image (можно использовать любой вид / макет, который вы хотите)