Setting a maximum width on a ViewGroup
One option which is what I did is to extend LinearLayout and override the onMeasure function. For example:
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);
}
}
Then you XML would use the custom class:
<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>
And the attr.xml file entry
<declare-styleable name="BoundedView">
<attr name="bounded_width" format="dimension" />
<attr name="bounded_height" format="dimension" />
</declare-styleable>
EDIT: This is the actual code I am using now. This is still not complete but works in most cases.
how to set max Width for a Layout
The appropriate way to handle your situation is to create a separate layout file to optimize your form view for tablets while using the existing file for phones. You do this by creating separate res/layout directories with qualifiers for screen size and/or resolution attached to them.
You can read more about the available resource qualifiers here. There are a number of choices here and I will leave it to you to pick the best for your application, but here is a simple example:
Let's assume your current layout file is form.xml.
Place your existing layout file in res/layout/form.xml. This will make it the default layout.
Create another file and place it in res/layout-large/form.xml. This layout file will be used on devices with a physical screen size > ~5" (all standard tablets). To handle your issue, I have modified your default layout to display the form centered horizontally and only take up 60% of the screen width:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/adlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:gravity="center_horizontal"
android:weightSum="1" >
<TableLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:stretchColumns="1" >
<TableRow android:id="@+id/tableRow1">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dip"
android:text="Barcode Format" >
</TextView>
<EditText
android:id="@+id/edit_barcode_format"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="6dip" >
</EditText>
</TableRow>
<TableRow android:id="@+id/tableRow1">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dip"
android:text="Barcode Type" >
</TextView>
<EditText
android:id="@+id/edit_barcode_type"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="6dip" >
</EditText>
</TableRow>
</TableLayout>
</LinearLayout>
The change utilizes the layout_weight
and weightSum
properties of LinearLayout
, which tell the table to only fill 60% (layout_weight=0.6
) of its parent. This is more efficient than try to set a maximum width, especially when devices have variable resolutions and aspect ratios.
FYI, I also tried to remove as many of the unnecessary attributes that you had in your XML that were doing nothing but creating clutter (such as multiple xmlns:android
declarations). One of those changes was removing extra layout_
parameters from the TableLayout
children, because TableLayout
ignores all these parameters anyway and forces its children to use certain constraints. From the Docs:
The children of a TableLayout cannot specify the layout_width attribute. Width is always MATCH_PARENT. However, the layout_height attribute can be defined by a child; default value is WRAP_CONTENT. If the child is a TableRow, then the height is always WRAP_CONTENT.
You can read more about TableLayout
in the SDK docs.
HTH
Setting a max width for LinearLayout
This does it - what I needed beyond what was suggested in prior answer is to add another layout (@+id/TheLayout
) as a wrapper between the content and the top layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="100dip"
android:paddingRight="100dip">
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/TheLayout"
android:layout_gravity="right">
<TextView android:id="@+id/TextView01"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="1"
android:text="this is my text."
android:layout_gravity="center_vertical">
</TextView>
<ImageView android:id="@+id/ImageView01"
android:layout_height="wrap_content"
android:background="@drawable/icon"
android:layout_width="fill_parent">
</ImageView>
</LinearLayout>
</LinearLayout>
How to use android:maxWidth?
I want to set a maximum width of an edit box.
In your example:
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ems="10" />
The layout_width
and ems
attributes are trying to set the same value. Android seems to choose the larger fill_parent
value and ignores the other. And when you use this:
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:maxWidth="50dp"
android:minWidth="50dp" />
Here ems
and maxWidth
are trying to set the same value, again the greater value is used. So depending on what you actually want you can use:
<EditText
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10" />
or replace android:ems="10"
with android:maxWidth="50dp"
if you prefer to work with dp.
Lastly your LinearLayout only has one child, the EditText. Typically when this happens you can remove the LinearLayout tags and use the EditText by itself.
Combine layout_weight and maxWidth for views
I don't have Eclipse here to test it, but I would use a RelativeLayout instead, something like:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<View
android:id="@+id/centerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
/>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/centerView"
android:enabled="false"
android:textStyle="bold"
android:text="@string/button1"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/centerView"
android:text="@string/button2"
/>
</RelativeLayout>
As I said, I can't test it right now, but you can work around this idea.
On a side note, unless your layout is very simple, I usually create separate layouts for landscape. It's a little more work, but you can optimize the views much better that way. Specially, if you plan to support larger screens.
how to set max Width for a Layout
The appropriate way to handle your situation is to create a separate layout file to optimize your form view for tablets while using the existing file for phones. You do this by creating separate res/layout directories with qualifiers for screen size and/or resolution attached to them.
You can read more about the available resource qualifiers here. There are a number of choices here and I will leave it to you to pick the best for your application, but here is a simple example:
Let's assume your current layout file is form.xml.
Place your existing layout file in res/layout/form.xml. This will make it the default layout.
Create another file and place it in res/layout-large/form.xml. This layout file will be used on devices with a physical screen size > ~5" (all standard tablets). To handle your issue, I have modified your default layout to display the form centered horizontally and only take up 60% of the screen width:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/adlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:gravity="center_horizontal"
android:weightSum="1" >
<TableLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:stretchColumns="1" >
<TableRow android:id="@+id/tableRow1">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dip"
android:text="Barcode Format" >
</TextView>
<EditText
android:id="@+id/edit_barcode_format"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="6dip" >
</EditText>
</TableRow>
<TableRow android:id="@+id/tableRow1">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dip"
android:text="Barcode Type" >
</TextView>
<EditText
android:id="@+id/edit_barcode_type"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="6dip" >
</EditText>
</TableRow>
</TableLayout>
</LinearLayout>
The change utilizes the layout_weight
and weightSum
properties of LinearLayout
, which tell the table to only fill 60% (layout_weight=0.6
) of its parent. This is more efficient than try to set a maximum width, especially when devices have variable resolutions and aspect ratios.
FYI, I also tried to remove as many of the unnecessary attributes that you had in your XML that were doing nothing but creating clutter (such as multiple xmlns:android
declarations). One of those changes was removing extra layout_
parameters from the TableLayout
children, because TableLayout
ignores all these parameters anyway and forces its children to use certain constraints. From the Docs:
The children of a TableLayout cannot specify the layout_width attribute. Width is always MATCH_PARENT. However, the layout_height attribute can be defined by a child; default value is WRAP_CONTENT. If the child is a TableRow, then the height is always WRAP_CONTENT.
You can read more about TableLayout
in the SDK docs.
HTH
Related Topics
How to Fix "Fail to Connect to Camera Service" Exception in Android Emulator
Status Bar Turns White and Does Not Show Content Behind It
How Do Cursorloader Automatically Updates the View Even If the App Is Inactive
Is Arm64-V8A Compatible with Armeabi-V7A
Rendering Problems in Android Studio V 1.1/1.2
Write File to Location Other Than Sdcard Using Android Ndk
Intent Putextra Arraylist<Namevaluepair>
Android Get a Cursor Only with Contacts That Have an Email Listed >Android 2.0
Android:Change Button Text and Background Color
What Happens If a Android Service Is Started Multiple Times
Setting Audio File as Ringtone
Install App via Usb: the Device Is Temporarily Restricted
How to Load HTML String in a Webview
Android Audiotrack Playing .Wav File, Getting Only White Noise