android - linearlayout - Establecer un ancho máximo en un ViewGroup
viewgroup android example (6)
¿Cómo configuro el ancho máximo de un grupo de vistas? Estoy usando una actividad Theme.Dialog
, sin embargo, esto no se ve tan bien cuando se cambia el tamaño a pantallas más grandes, también es algo liviano y no quiero que ocupe toda la pantalla.
He intentado esta sugerencia en vano. Además, no hay ninguna propiedad de android:maxWidth
como algunas vistas.
¿Hay una manera de restringir la raíz LinearLayout para que solo (por ejemplo) 640 se sumerja? Estoy dispuesto a cambiar a otro ViewGroup para esto.
¿Alguna sugerencia?
Agregue un Layout externo o una capa Viewgroup a su archivo de diseño actual. La altura y el ancho de este diseño será la altura / anchura máxima. Ahora su diseño interno se puede configurar para envolver contenido y está limitado por el diseño externo. P.ej:
<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>
Ahora android.support.constraint.ConstraintLayout
hace más fácil. Simplemente ajuste su vista (de cualquier tipo) con ConstraintLayout y establezca los siguientes atributos para la vista:
android:layout_width="0dp"
app:layout_constraintWidth_default="spread"
app:layout_constraintWidth_max="640dp"
http://tools.android.com/recent/constraintlayoutbeta5isnowavailable
Aquí hay un mejor código para la respuesta de Dori.
En el método onMeasure
, si llama a super.onMeasure(widthMeasureSpec, heightMeasureSpec);
primero en el método, luego el ancho de todos los objetos en el diseño no se cambiará. Porque se inicializaron antes de establecer el ancho del diseño (padre).
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);
}
}
Y aquí hay un enlace para el uso de xml attr:
http://kevindion.com/2011/01/custom-xml-attributes-for-android-widgets/
Gracias por esta pregunta y respuestas. Su respuesta me ha ayudado mucho, y espero que también ayude a otra persona en el futuro.
Aquí hay una respuesta simple,
El ancho / alto parece que siempre tienen que estar juntos. Esto está funcionando en mi opinión.
<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" />
El elemento primario del botón está configurado para envolver el contenido, por lo que se reduce, pero hasta un máximo de 400 de ancho (4 botones).
Sobre la base de la respuesta original de Chase (+1), haría un par de cambios (que se describen a continuación).
Tendría el ancho máximo establecido a través de un atributo personalizado (xml debajo del código)
super.measure()
llamaríasuper.measure()
y luego hacer laMath.min(*)
. Al usar el código de respuestas original, podemos encontrar problemas cuando el tamaño de entrada establecido enMeasureSpec
seaLayoutParams.WRAP_CONTENT
oLayoutParams.FILL_PARENT
. Como estas constantes válidas tienen valores de -2 y -1 respectivamente, elMath.min(*)
originalMath.min(*)
vuelve inútil, ya que conservará estos valores por encima del tamaño máximo y dice que elWRAP_CONTENT
medido es más grande que nuestro tamaño máximo, esta verificación no Atrapalo. Me imagino que el OP estaba pensando solo en atenuaciones exactas (por lo que funciona muy bien)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()); } } }
y el attr xml
<!-- MaxWidthLinearLayout -->
<declare-styleable name="MaxWidthLinearLayout">
<attr name="maxWidth" format="dimension" />
</declare-styleable>
Una opción que es lo que hice es extender LinearLayout y anular la función onMeasure. Por ejemplo:
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);
}
}
Entonces tu XML usaría la clase personalizada:
<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>
Y la entrada del archivo attr.xml
<declare-styleable name="BoundedView">
<attr name="bounded_width" format="dimension" />
<attr name="bounded_height" format="dimension" />
</declare-styleable>
EDITAR: Este es el código real que estoy usando ahora. Esto todavía no está completo, pero funciona en la mayoría de los casos.