Festlegen einer maximalen Breite für eine ViewGroup
Lesezeit: 7 Minuten
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?
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:
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
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);
}
}
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).
Ich würde die maximale Breite über ein benutzerdefiniertes Attribut festlegen lassen (xml unter dem Code)
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());
}
}
}
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:
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).
.
3673900cookie-checkFestlegen einer maximalen Breite für eine ViewGroupyes