Подтвердить что ты не робот

Установка максимальной ширины в ViewGroup

Как установить максимальную ширину в ViewGroup? Я использую активность Theme.Dialog, однако это не выглядит так хорошо, когда вы изменяете размер экрана на большие экраны, он также выглядит легким, и я не хочу, чтобы он занимал весь экран.

Я попробовал это предложение безрезультатно. Кроме того, нет свойства android:maxWidth, как некоторые представления.

Есть ли способ ограничить root LinearLayout так, чтобы он был (например) 640 dip? Я готов перейти на другую ViewGroup для этого.

Любые предложения?

4b9b3361

Ответ 1

Один из вариантов, который я сделал, - расширить LinearLayout и переопределить функцию onMeasure. Например:

public class BoundedLinearLayout extends LinearLayout {

    private final int mBoundedWidth;

    private final int mBoundedHeight;

    public BoundedLinearLayout(Context context) {
        super(context);
        mBoundedWidth = 0;
        mBoundedHeight = 0;
    }

    public BoundedLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BoundedView);
        mBoundedWidth = a.getDimensionPixelSize(R.styleable.BoundedView_bounded_width, 0);
        mBoundedHeight = a.getDimensionPixelSize(R.styleable.BoundedView_bounded_height, 0);
        a.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Adjust width as necessary
        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
        if(mBoundedWidth > 0 && mBoundedWidth < measuredWidth) {
            int measureMode = MeasureSpec.getMode(widthMeasureSpec);
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(mBoundedWidth, measureMode);
        }
        // Adjust height as necessary
        int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
        if(mBoundedHeight > 0 && mBoundedHeight < measuredHeight) {
            int measureMode = MeasureSpec.getMode(heightMeasureSpec);
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(mBoundedHeight, measureMode);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

Затем вы используете XML-пользовательский класс:

<com.yourpackage.BoundedLinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:bounded_width="900dp">

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
    />
</com.youpackage.BoundedLinearLayout>

И запись файла attr.xml

<declare-styleable name="BoundedView">
    <attr name="bounded_width" format="dimension" />
    <attr name="bounded_height" format="dimension" />
</declare-styleable>

EDIT: Это фактический код, который я использую сейчас. Это все еще не завершено, но работает в большинстве случаев.

Ответ 2

Основываясь на исходном ответе Chase (+1), я сделал бы пару изменений (обрисованных ниже).

  • Я бы установил максимальную ширину с помощью настраиваемого атрибута (xml под кодом)

  • Сначала я бы назвал super.measure(), а затем сравним Math.min(*). Используя исходный код ответов, мы можем столкнуться с проблемами, когда входящий размер, установленный в MeasureSpec, равен либо LayoutParams.WRAP_CONTENT, либо LayoutParams.FILL_PARENT. Поскольку эти допустимые константы имеют значения -2 и -1, оригинал Math.min(*) становится бесполезным, так как он сохраняет эти значения над максимальным размером и говорит, что измеренные WRAP_CONTENT больше нашего максимального размера, эта проверка не поймает его. Я полагаю, что ОП думал о точном тусклом (для которого он отлично работает)

    public class MaxWidthLinearLayout extends LinearLayout {
    
    private int mMaxWidth = Integer.MAX_VALUE;
    
    public MaxWidthLinearLayout(Context context) {
    
        super(context);
    }
    
    public MaxWidthLinearLayout(Context context, AttributeSet attrs) {
    
        super(context, attrs);
    
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MaxWidthLinearLayout);
        mMaxWidth = a.getDimensionPixelSize(R.styleable.MaxWidthLinearLayout_maxWidth, Integer.MAX_VALUE);
    }
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //get measured height
        if(getMeasuredWidth() > mMaxWidth){
            setMeasuredDimension(mMaxWidth, getMeasuredHeight());
        }
    }
    }
    

и xml attr

    <!-- MaxWidthLinearLayout -->
    <declare-styleable name="MaxWidthLinearLayout">
        <attr name="maxWidth" format="dimension" />
    </declare-styleable>

Ответ 3

Вот лучший код для ответа Дори.

В методе onMeasure, если вы сначала вызываете super.onMeasure(widthMeasureSpec, heightMeasureSpec); в методе, тогда ширина всех объектов в макете не будет изменена. Поскольку они инициализируются до того, как вы установите ширину макета (родительского).

public class MaxWidthLinearLayout extends LinearLayout {
    private final int mMaxWidth;

    public MaxWidthLinearLayout(Context context) {
        super(context);
        mMaxWidth = 0;
    }

    public MaxWidthLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MaxWidthLinearLayout);
        mMaxWidth = a.getDimensionPixelSize(R.styleable.MaxWidthLinearLayout_maxWidth, Integer.MAX_VALUE);
        a.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
        if (mMaxWidth > 0 && mMaxWidth < measuredWidth) {
            int measureMode = MeasureSpec.getMode(widthMeasureSpec);
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxWidth, measureMode);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

И вот ссылка на использование xml attr:
  http://kevindion.com/2011/01/custom-xml-attributes-for-android-widgets/

Спасибо за этот вопрос и ответы. Ваш ответ мне очень помог, и я надеюсь, что это поможет кому-то еще и в будущем.

Ответ 4

Теперь android.support.constraint.ConstraintLayout упрощается. Просто оберните свой вид (любого типа) с помощью ConstraintLayout и установите следующие атрибуты в представление:

android:layout_width="0dp"
app:layout_constraintWidth_default="spread"
app:layout_constraintWidth_max="640dp"

http://tools.android.com/recent/constraintlayoutbeta5isnowavailable

Ответ 5

Добавьте слой Outer Layout или Viewgroup в текущий файл Layout. Высота и ширина этого макета будут максимальной высотой/шириной. Теперь ваш внутренний макет может быть настроен на обертку содержимого и ограничен внешней компоновкой. Например:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- OuterLayout to set Max Height and Width  -- Add this ViewGroup to your layout  File  -->
    <LinearLayout
        android:id="@+id/outerLayout"
        android:layout_width="650dp"
        android:layout_height="650dp"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

Ответ 6

Вот простой ответ,

Ширина/Высота всегда должны быть установлены вместе. Это работает на мой взгляд.

    <Button
        android:text="Center"
        android:layout_width="100dp"
        android:layout_height="fill_parent"
        android:id="@+id/selectionCenterButton"
        android:minWidth="50dp"
        android:minHeight="50dp"
        android:maxWidth="100dp"
        android:maxHeight="50dp"
        android:layout_weight="1" />

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