简体   繁体   中英

Constraint Layout Getting a default top margin for imageview

I am trying to create a layout using constraint layout, with an ImageView on top, a button in the ImageView, a TextView below it and then another TextView below it. Following is the xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    app:cardElevation="4dp">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white">
        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/news_image1"
                android:layout_width="0dp"
                android:layout_height="0dp"
                app:layout_constraintDimensionRatio="16:9"
                android:scaleType="centerCrop"
                android:adjustViewBounds="true"
                app:layout_constraintTop_toTopOf="parent"
                android:layout_marginTop="0dp"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintBottom_toTopOf="@+id/news_title1"/>
            <ImageButton
                android:id="@+id/news_share_button_1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/transparent"
                android:src="@drawable/share_button_big"
                app:layout_constraintBottom_toBottomOf="@+id/news_image1"
                app:layout_constraintRight_toRightOf="@+id/news_image1"
                android:layout_marginRight="15dp"
                android:layout_marginEnd="15dp"/>
            <TextView
                android:id="@+id/news_title1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:gravity="center_vertical|start"
                android:layout_alignParentBottom="true"
                android:lines="3"
                android:ellipsize="end"
                app:layout_constraintTop_toBottomOf="@+id/news_image1"
                app:layout_constraintBottom_toTopOf="@+id/news_read_more1"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                android:textColor="@color/colorPrimaryText"
                android:layout_margin="@dimen/news_cell0_textview_margin"
                android:textSize="12sp"
                android:typeface="monospace" />
            <TextView
                android:id="@+id/news_read_more1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:gravity="center_vertical|start"
                android:layout_alignParentBottom="true"
                android:lines="1"
                android:ellipsize="end"
                app:layout_constraintTop_toBottomOf="@+id/news_title1"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                android:textColor="@color/read_more_text_color"
                android:text="@string/news_read_more"
                android:layout_margin="@dimen/news_cell0_textview_margin"
                android:textSize="10sp" />
        </android.support.constraint.ConstraintLayout>
    </RelativeLayout>
</android.support.v7.widget.CardView>

Everything is correct except for a small margin on top of the first ImageView. Whatever I do I cannot get rid of that margin. See the image below.

在此处输入图片说明

Please note the margin between the top of the ImageView and the card, that is what is troubling me.

Your news_image , news_title1 , and news_read_more1 views form a chain. Apparently, though I cannot find documentation on this, all views in a vertical chain will share vertical margins. In other words, applying a layout_marginTop or layout_marginBottom attribute to one of those three views will wind up applying it to all three of them .

You will have to re-allocate your margins, keeping this in mind.

Edit

Looks like the behavior is a little more sophisticated than I thought. First of all, it looks like it only applies to views with the spread "chain style" (which is the default). Second, it looks like top margin is applied to the view it is specified on as well as all views above that one in the chain, while bottom margin is applied to the view it is specified on as well as all views below that one in the chain. Finally, it appears that margins are cumulative (so if you had 10dp top margin on your bottom view and 20dp top margin on your middle view, the final result would be 30dp on your top view, 30dp on your middle view, and 10dp on your bottom view).

As for how to solve this problem in your specific case? You should be able to use left/right margins without issue. And then probably you should use bottom margin on your top view to space the three views out.

Edit #2

Muthukrishnan's answer made me realize that you could solve this problem by simply removing the chain from your views. If you delete the app:layout_constraintBottom_toTopOf="@+id/news_title1" constraint from your ImageView, that will break the chain and now the vertical margins aren't shared.

Thanks to the great starter by Ben P, I managed to figure out a solution. There are three(plus one weighed) chaining styles available in ConstraintLayout. According to this great tutorial the chaining styles are explained as:

  1. Spread : The views are evenly distributed. Eg app:layout_constraintHorizontal_chainStyle=”spread” app:layout_constraintVertical_chainStyle=”spread”
  2. Spread inside : The first and last view are affixed to the constraints on each end of the chain and the rest are evenly distributed. Eg app:layout_constraintHorizontal_chainStyle=”spread_inside” app:layout_constraintVertical_chainStyle=”spread_inside”
  3. Packed : The views are packed together (after margins are accounted for). You can then adjust the whole chain's bias (left/right or up/down) by changing the chain's head view bias. Eg app:layout_constraintHorizontal_chainStyle=”packed” app:layout_constraintVertical_chainStyle=”packed”
  4. Weighted : When the chain is set to either spread or spread inside, you can fill the remaining space by setting one or more views to “match constraints” (0dp). By default, the space is evenly distributed between each view that's set to "match constraints," but you can assign a weight of importance to each view using thelayout_constraintHorizontal_weight and layout_constraintVertical_weight attributes . If you're familiar with layout_weight in a linear layout, this works the same way. So the view with the highest weight value gets the most amount of space; views that have the same weight get the same amount of space.

spread is the default chaining style. I changed it to spread_inside so that the first and last views are affixed to the constraints on each end of the chain(hence obeying the margins provided). The xml now looks like:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    app:cardElevation="4dp">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white">
        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/news_image1"
                android:layout_width="0dp"
                android:layout_height="0dp"
                app:layout_constraintDimensionRatio="16:9"
                android:scaleType="centerCrop"
                android:adjustViewBounds="true"
                app:layout_constraintTop_toTopOf="parent"
                android:layout_marginTop="0dp"
                app:layout_constraintVertical_chainStyle="spread_inside"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintBottom_toTopOf="@+id/news_title1"/>
            <ImageButton
                android:id="@+id/news_share_button_1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/transparent"
                android:src="@drawable/share_button_big"
                app:layout_constraintBottom_toBottomOf="@+id/news_image1"
                app:layout_constraintRight_toRightOf="@+id/news_image1"
                android:layout_marginRight="15dp"
                android:layout_marginEnd="15dp"/>
            <TextView
                android:id="@+id/news_title1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:gravity="center_vertical|start"
                android:layout_alignParentBottom="true"
                android:lines="3"
                android:ellipsize="end"
                app:layout_constraintVertical_chainStyle="spread_inside"
                app:layout_constraintTop_toBottomOf="@+id/news_image1"
                app:layout_constraintBottom_toTopOf="@+id/news_read_more1"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                android:textColor="@color/colorPrimaryText"
                android:layout_margin="@dimen/news_cell0_textview_margin"
                android:textSize="12sp"
                android:typeface="monospace" />
            <TextView
                android:id="@+id/news_read_more1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:gravity="center_vertical|start"
                android:layout_alignParentBottom="true"
                android:lines="1"
                android:ellipsize="end"
                app:layout_constraintVertical_chainStyle="spread_inside"
                app:layout_constraintTop_toBottomOf="@+id/news_title1"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                android:textColor="@color/read_more_text_color"
                android:text="@string/news_read_more"
                android:layout_margin="@dimen/news_cell0_textview_margin"
                android:textSize="10sp" />
        </android.support.constraint.ConstraintLayout>
    </RelativeLayout>
</android.support.v7.widget.CardView>

Try this, I remove app:layout_constraintTop_toTopOf="parent" in your layout it works

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    app:cardElevation="4dp">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white">
        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <ImageView
                android:id="@+id/news_image1"
                android:layout_width="0dp"
                android:layout_height="0dp"
                app:layout_constraintDimensionRatio="16:9"
                android:scaleType="centerCrop"
                android:adjustViewBounds="true"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"/>
            <ImageButton
                android:id="@+id/news_share_button_1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/transparent"
                android:src="@drawable/ic_menu_share"
                app:layout_constraintBottom_toBottomOf="@+id/news_image1"
                app:layout_constraintRight_toRightOf="@+id/news_image1"
                android:layout_marginRight="15dp"
                android:layout_marginEnd="15dp"/>
            <AliasTextView
                android:id="@+id/news_title1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:gravity="center_vertical|start"
                android:layout_alignParentBottom="true"
                android:lines="3"
                android:ellipsize="end"
                app:layout_constraintTop_toBottomOf="@+id/news_image1"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                android:textColor="@color/colorPrimaryText"
                android:layout_margin="@dimen/news_cell0_textview_margin"
                android:textSize="12sp"
                android:typeface="monospace" />
            <TextView
                android:id="@+id/news_read_more1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:gravity="center_vertical|start"
                android:layout_alignParentBottom="true"
                android:lines="1"
                android:ellipsize="end"
                app:layout_constraintTop_toBottomOf="@+id/news_title1"
                app:layout_constraintLeft_toLeftOf="parent"
                android:textColor="@color/read_more_text_color"
                android:text="@string/news_read_more"
                android:layout_margin="@dimen/news_cell0_textview_margin"
                android:textSize="10sp" />
        </android.support.constraint.ConstraintLayout>
    </RelativeLayout>
</android.support.v7.widget.CardView>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM