Android RelativeLayout выравнивает центр одного представления в правом верхнем углу другого представления

У меня есть опыт работы с RelativeLayout, но я никогда не сталкивался со способом решения проблемы, с которой я столкнулся (кроме значений полей жесткого кодирования, которых я хочу избежать).

Я хочу попытаться создать что-то вроде следующего изображения в RelativeLayout:

введите здесь описание изображения

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

Я пробовал с android:alignTop="boxView" и android:alignRight="boxView", но это полностью поместило мой оранжевый круг в мою коробку. Я хочу, чтобы круг был в центре над правым верхним углом поля.

Кто-нибудь знает, как я могу получить этот результат с помощью RelativeLayout? желательно без жесткого кодирования полей от края экрана для просмотра оранжевых точек.


person FoamyGuy    schedule 01.05.2012    source источник
comment
Почему вы не хотите использовать маржу для этого. Маржа кажется идеальным способом добиться этого.   -  person Bobbake4    schedule 01.05.2012
comment
Я только не хочу давать ему запас на то, как далеко от края экрана. Если бы я мог выровнять его по коробке, а затем сместить вверх и вниз на половину его диаметра с запасом, это было бы на самом деле идеально. Но я могу понять, как это сделать, только сообщив ему, как далеко от края экрана, а не как далеко от точки, по которой я хочу выровнять.   -  person FoamyGuy    schedule 01.05.2012


Ответы (3)


Этот код создает то, что вы ищете, но использует поля. Теперь вы можете установить поле в коде, если это динамическая структура, которую вы создаете. Как видите, я использовал отрицательные поля, чтобы переместить верхнюю правую фигуру за пределы синего прямоугольника. Они должны быть на половину высоты круга, который вы пытаетесь переместить. Вы можете сделать все это в коде, чтобы центрировать круг в правом верхнем углу.

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

        <LinearLayout
            android:id="@+id/linearLayout1"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:background="#0000FF"
            android:orientation="vertical" >
        </LinearLayout>

        <LinearLayout
            android:layout_width="26dp"
            android:layout_height="26dp"
            android:layout_alignRight="@+id/linearLayout1"
            android:layout_alignTop="@+id/linearLayout1"
            android:layout_marginRight="-13dp"
            android:layout_marginTop="-13dp"
            android:background="#FF00FF"
            android:orientation="vertical" >
        </LinearLayout>

    </RelativeLayout>
person Bobbake4    schedule 01.05.2012
comment
Обратите внимание, что это на самом деле не работает, если размер второго представления определяется изображением, поскольку у рисунков нет постоянного размера в DP (их размер в пикселях переходит от одного сегмента DPI к другому вместо непрерывного масштабирования). Так что вы не можете просто сделать 26dp / 2 = 13dp. Одним из обходных путей является выбор размера, который определенно больше, чем изображение, и добавление макета-оболочки вокруг представления с этим определенным размером (с исходным представлением, центрированным в нем), после чего вы можете вычислить его половину. - person Karu; 11.05.2015
comment
Отрицательные поля официально не поддерживаются и не работают должным образом на некоторых устройствах. issuetracker.google.com/issues/37103660 - person Shroud; 22.03.2018

Вы можете использовать круговое позиционирование ConstraintLayout, просто выровняйте свой вид на угол 45 градусов и отрегулируйте радиус:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:background="@color/colorAccent"
        android:id="@+id/view"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:background="@color/colorPrimary"
        android:id="@+id/alignedView"
        android:layout_width="30dp"
        android:layout_height="30dp"
        app:layout_constraintCircle="@id/view"
        app:layout_constraintCircleAngle="45"
        app:layout_constraintCircleRadius="60dp" />

</androidx.constraintlayout.widget.ConstraintLayout>
person Danil.B    schedule 19.09.2019

Лучший и правильный способ сделать:

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/_10sdp">

    <View
        android:id="@+id/viewBox"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:background="@color/black"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent" />

    <View
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:src="@drawable/ic_close"
        app:layout_constraintBottom_toTopOf="@+id/viewBox"
        app:layout_constraintLeft_toRightOf="@+id/viewBox"
        app:layout_constraintRight_toRightOf="@+id/viewBox"
        app:layout_constraintTop_toTopOf="@+id/viewBox" />

</androidx.constraintlayout.widget.ConstraintLayout>
person Omer    schedule 11.03.2021