如何使视图的宽度取决于recyclerview中的其他视图?

时间:2017-07-21 09:46:09

标签: android android-recyclerview android-view

我想测量一个cardview的宽度并与其外面的cardview相匹配,以便清楚地了解我会附上一个图像以及问题:

enter image description here

在这里,内部cardview应该与外部cardview的宽度相同,内部cardview是回复聊天气泡,外部是聊天消息气泡。

我尝试过扩展cardview:

public class ExtendCardView extends CardView {

Integer newWidth;

public ExtendCardView(Context context) {
    super(context);
}

public ExtendCardView(Context context, AttributeSet attrs) {
    super(context, attrs);
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    newWidth= MeasureSpec.getSize(widthMeasureSpec);
      super.onMeasure(newWidth, heightMeasureSpec);

}

public Integer getNewWidth() {
    return newWidth;
}

public void setNewWidth(Integer newWidth) {
    this.newWidth = newWidth;
}}

在适配器的onBindView上我添加了一个视图树观察器来改变宽度:

((CardView) holder).inner_card_view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @SuppressLint("NewApi")
        @SuppressWarnings("deprecation")
        @Override
        public void onGlobalLayout() {
            //((CardView) holder).inner_card_view.measure(View.MeasureSpec.EXACTLY, View.MeasureSpec.EXACTLY);

            ((CardView) holder).inner_card_view.setNewWidth(((CardView) holder).outer_card_view.getNewWidth());
            //now we can retrieve the width and height
            //...
            //do whatever you want with them
            //...
            //this is an important step not to keep receiving callbacks:
            //we should remove this listener
            //I use the function to remove it based on the api level!

            if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
                ((CardView) holder).inner_card_view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            else
                ((CardView) holder).inner_card_view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
    });

实现这样的目标的完美方式是什么,这是我对cardview的布局文件:

      <com.example.ui.view.ExtendCardView
    android:id="@+id/outer_card"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentEnd="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:layout_marginEnd="8dp"
    android:layout_marginLeft="50dp"
    android:layout_marginRight="8dp"
    android:layout_marginStart="50dp"
    app:cardCornerRadius="8dp">


        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="2dp">

            <TextView
                android:id="@+id/tv_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:textAppearance="@style/TextAppearance.AppCompat.Small"
                android:textColor="@color/black" />

            <com.example.ui.view.ExtendCardView
                android:id="@+id/inner_card"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/tv_name"
                android:layout_margin="1dp"
                android:minWidth="80dp"
                app:cardBackgroundColor="@color/red"
                app:cardCornerRadius="8dp"
                app:cardElevation="0dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">

                    <RelativeLayout
                        android:id="@+id/rel_layout"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_margin="5dp"
                        android:layout_marginEnd="15dp"
                        android:layout_marginRight="15dp">

                        <TextView
                            android:id="@+id/tv_user_name"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_alignParentLeft="true"
                            android:layout_alignParentStart="true"
                            android:textStyle="bold" />

                        <LinearLayout
                            android:id="@+id/lin_layout"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_below="@id/tv_user_name"
                            android:layout_marginBottom="8dp"
                            android:orientation="horizontal">

                            <ImageView
                                android:id="@+id/iv_type"
                                android:layout_width="18dp"
                                android:layout_height="18dp"
                                android:layout_marginEnd="4dp"
                                android:layout_marginRight="4dp"
                                android:tint="@color/dark_grey"
                                android:visibility="gone" />

                            <TextView
                                android:id="@+id/tv_message"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:autoLink="web"
                                android:maxLines="3" />
                        </LinearLayout>


                    </RelativeLayout>

                    <ImageView
                        android:id="@+id/iv_media"
                        android:layout_width="40dp"
                        android:layout_height="40dp"
                        android:layout_gravity="center_vertical"
                        android:layout_marginEnd="8dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="8dp"
                        android:layout_marginStart="15dp"
                        android:visibility="gone" />
                </LinearLayout>

            </com.nodd.nodd.ui.view.ExtendCardView>

            <TextView
                android:id="@+id/tv_reply_message"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:layout_below="@+id/inner_card"
                android:layout_marginBottom="5dp"
                android:layout_marginEnd="4dp"
                android:layout_marginLeft="4dp"
                android:layout_marginRight="4dp"
                android:layout_marginStart="4dp"
                android:autoLink="web"
                android:linksClickable="true"
                android:textColor="@color/white"
                android:textColorLink="@color/linkedin_blue" />

            <ImageView
                android:id="@+id/tv_reply_image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:layout_below="@+id/inner_card"
                android:visibility="gone"
                android:layout_marginBottom="5dp"
                android:layout_marginEnd="4dp"
                android:layout_marginLeft="4dp"
                android:layout_marginRight="4dp"
                android:layout_marginStart="4dp"
                android:layout_marginTop="5dp" />
        </RelativeLayout>

    </RelativeLayout>
</com.example.ui.view.ExtendCardView>

3 个答案:

答案 0 :(得分:1)

看看ConstraintLayout

  

ConstraintLayout 允许您使用平面视图层次结构创建大型复杂布局(无嵌套视图组)。它与RelativeLayout类似,因为所有视图都是根据兄弟视图和父布局之间的关系布局的,但它比RelativeLayout更灵活,更易于使用Android Studio的布局编辑器。

您可以将内卡放在 ConstraintLayout 中,并通过外卡调整其尺寸,而无需测量和设置尺寸。

由于 ConstraintLayout 中不允许match_parent,因此请将layout_height和/或layout_width设置为0dp(调整layout_margin属性在内卡和外卡之间增加空间。)

在你的情况下,你会得到类似的东西:

<com.example.ui.view.ExtendCardView
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"

    android:id="@+id/inner_card"
    android:layout_margin="1dp"
    android:minWidth="80dp"
    app:cardBackgroundColor="@color/red"
    app:cardCornerRadius="8dp"
    app:cardElevation="0dp">

    <!-- ExtendCardView content -->

</com.nodd.nodd.ui.view.ExtendCardView>

希望它有所帮助!

答案 1 :(得分:0)

CardView具有默认填充,因此创建一个从CardView扩展的CustomCardView类,并通过删除填充来自定义它或使用其他布局为您的卡根(RelativeLayout,LinearLayout,...)

答案 2 :(得分:0)

我不知道这是否完美但它应该可以解决你的问题。有两个地方可以防止内卡与外卡的宽度相同。您在内卡中设置的1dp保证金&amp;您在RelativeLayout中设置的2dp填充是内卡的父级。通过将这两个设置为0,您应该能够使内卡与外部卡宽度相同。您需要为RelativeLayout提供ID。我用了card_layout。然后将这个逻辑放在你知道是否应该有边距的地方。

    int margin;
    int padding;

    if(needsMargins) {
        margin = 1;
        padding = 2;
    } else {
        margin = 0;
        padding = 0;
    }

    CardView cardView = (CardView)findViewById(R.id.inner_card);
    ViewGroup.MarginLayoutParams params =
            (ViewGroup.MarginLayoutParams)cardView.getLayoutParams();
    params.setMargins(margin, margin, margin, margin);
    cardView.requestLayout();

    RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.card_layout);
    relativeLayout.setPadding(padding, padding, padding, padding);