Festlegen einer maximalen Breite für eine ViewGroup

Lesezeit: 7 Minuten

Festlegen einer maximalen Breite fur eine ViewGroup
zsniperx

Wie lege ich die maximale Breite einer ViewGroup fest? ich benutze a Theme.Dialog Aktivität, dies sieht jedoch nicht so gut aus, wenn die Größe auf größere Bildschirme geändert wird, es ist auch irgendwie leicht und ich möchte nicht, dass es den gesamten Bildschirm einnimmt.

Ich habe diesen Vorschlag vergeblich versucht. Außerdem gibt es keine android:maxWidth Eigentum wie einige Ansichten.

Gibt es eine Möglichkeit, das Root-LinearLayout so einzuschränken, dass es nur (zum Beispiel) 640 Dip ist? Ich bin bereit, dafür zu einer anderen ViewGroup zu wechseln.

Irgendwelche Vorschläge?

Festlegen einer maximalen Breite fur eine ViewGroup
Verfolgungsjagd

Eine Option, die ich gemacht habe, besteht darin, LinearLayout zu erweitern und die onMeasure-Funktion zu überschreiben. Beispielsweise:

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

Dann würde Ihr XML die benutzerdefinierte Klasse verwenden:

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

Und der Dateieintrag attr.xml

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

EDIT: Dies ist der eigentliche Code, den ich jetzt verwende. Dies ist noch nicht vollständig, funktioniert aber in den meisten Fällen.

  • Es ist unglaublich, dass Google kein a maxWidth out of the box, stattdessen müssen wir eine Unterklasse erstellen 🙁

    – Irgendwer irgendwo

    6. September ’13 um 22:17

  • Du hast absolut recht. Sie Crowdsourcing der Plattform effektiv :]

    – Verfolgungsjagd

    10. September ’13 um 1:44


  • Ich habe eine Fehlermeldung erhalten, wenn ich app_name:bounded_width=”900dp” hinzufüge

    – AHméd Net

    6. Dezember ’14 um 14:12


  • @AHmédNet hinzufügen xmlns:app_name="http://schemas.android.com/apk/res-auto" zum obersten Element in Ihrem Layout, um das zu beheben

    – David Passmore

    14. Februar ’15 um 11:13

1641914853 373 Festlegen einer maximalen Breite fur eine ViewGroup
Jonypoins

Hier ist ein besserer Code für die Antwort von Dori.

In Methode onMeasure, wenn du anrufst super.onMeasure(widthMeasureSpec, heightMeasureSpec); zuerst in der Methode, dann wird die Breite aller Objekte im Layout nicht geändert. Weil sie initialisiert wurden, bevor Sie die Breite des Layouts (übergeordneten) festlegen.

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

Und hier ist ein Link zur Verwendung von xml attr:
http://kevindion.com/2011/01/custom-xml-attributes-for-android-widgets/

Danke für diese Frage und Antworten. Ihre Antwort hat mir sehr geholfen und ich hoffe, dass sie in Zukunft auch jemand anderem hilft.

  • diese Antwort ist besser. (auch warum Dori einen trivialen Fehler übersehen hat?)

    – Zyoo

    6. Januar ’14 um 7:50

  • Der Inhalt verwendet immer noch die ursprüngliche Breite, wenn in den Layoutparametern von MaxWidthLinearLayout wird eine genaue größe angegeben… musst du angeben MATH_PARENT und legen Sie die genaue Größenverwaltung in die onMeasure(..). dumm aber funktioniert.

    – Gianluca P.

    21. Mai ’14 um 15:46

Aufbauend auf der ursprünglichen Antwort von Chase (+1) würde ich einige Änderungen vornehmen (siehe unten).

  1. Ich würde die maximale Breite über ein benutzerdefiniertes Attribut festlegen lassen (xml unter dem Code)

  2. ich würde anrufen super.measure() zuerst und dann mach das Math.min(*) Vergleich. Bei Verwendung des ursprünglichen Antwortcodes können Probleme auftreten, wenn die eingehende Größe im MeasureSpec entweder LayoutParams.WRAP_CONTENT oder LayoutParams.FILL_PARENT. Da diese gültigen Konstanten Werte von haben -2 und -1 bzw. das Original Math.min(*) wird nutzlos, da diese Täler über die maximale Größe hinweg erhalten bleiben und die gemessenen Werte angegeben werden WRAP_CONTENT größer als unsere maximale Größe ist, würde dieser Scheck ihn nicht fangen. Ich stelle mir vor, das OP dachte nur an genaue Dims (für die es großartig funktioniert)

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

und die xml-attr

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

  • Vielen Dank für Ihre Antwort. Ich brauche das nicht mehr, aber ich bin sicher, andere Leute könnten es auch brauchen. Wenn ich das Gefühl habe, dass ich meinen Code überarbeiten muss, werde ich dies auf jeden Fall überprüfen!

    – zsniperx

    24. Dezember ’11 um 0:17

  • wenn es für andere / mich in einem Jahr war, in dem ich vergesse, was ich getan habe 🙂

    – Dori

    20. Januar ’12 um 10:44

  • Dieser Code funktioniert nicht wie erwartet. Während die Breite angepasst wird, arbeiten die enthaltenden Elemente weiterhin mit der ursprünglichen Breite. Somit wird der Inhalt nur abgeschnitten. Jonypoins Antwort funktioniert.

    – Gunnar Bernstein

    8. Apr. ’14 um 7:11

Jetzt android.support.constraint.ConstraintLayout macht es leichter. Umschließen Sie einfach Ihre Ansicht (jeglicher Art) mit ConstraintLayout und legen Sie die folgenden Attribute für die Ansicht fest:

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

http://tools.android.com/recent/constraintlayoutbeta5ist jetzt verfügbar

1641914853 524 Festlegen einer maximalen Breite fur eine ViewGroup
Stephen Talley

Hier ist eine reine Kotlin-Lösung mit dem zusätzlichen Vorteil, dass Sie sie verwenden können android:maxWidth.

BoundedFrameLayout.kt

package example.com

import android.content.Context
import android.util.AttributeSet
import android.widget.FrameLayout
import androidx.core.content.withStyledAttributes
import com.sas.android.common.R

class BoundedFrameLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
    private var maxWidth = -1

    init {
        if (attrs != null) {
            context.withStyledAttributes(attrs, R.styleable.BoundedView) {
                maxWidth = getDimensionPixelSize(
                    R.styleable.BoundedView_android_maxWidth, maxWidth
                )
            }
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        var widthSpec = widthMeasureSpec
        if (maxWidth >= 0) {
            val widthSize = MeasureSpec.getSize(widthMeasureSpec)
            if (widthSize > maxWidth) {
                val widthMode = MeasureSpec.getMode(widthMeasureSpec)
                widthSpec = MeasureSpec.makeMeasureSpec(maxWidth, widthMode)
            }
        }
        super.onMeasure(widthSpec, heightMeasureSpec)
    }
}

attrs.xml

<resources>
    <declare-styleable name="BoundedView">
        <attr name="android:maxWidth" />
    </declare-styleable>
</resources>

Dann in Ihrem Layout-XML:

…
<com.example.BoundedFrameLayout
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:maxWidth="350dp"
/>
…

Die maximale Höhe kann wie die Breite behandelt werden; es wird hier der Kürze halber weggelassen.

Dieses Muster kann für jede ViewGroup-Unterklasse (zB LinearLayout) übernommen werden.

1641914853 615 Festlegen einer maximalen Breite fur eine ViewGroup
Manokar

Hier ist eine einfache Antwort,

Breite/Höhe scheinen immer zusammen eingestellt werden zu müssen. Das funktioniert aus meiner Sicht.

    <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" />

Das übergeordnete Element der Schaltfläche ist so eingestellt, dass es Inhalt umbricht, skaliert also nach unten, aber bis zu einer maximalen Breite von 400 (4 Schaltflächen).

.

367390cookie-checkFestlegen einer maximalen Breite für eine ViewGroup

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy