Android横屏布局调整:让两个垂直LinearLayout按2/3与1/3分配宽度
Hey there! The main issue here is that RelativeLayout doesn't support the layout_weight attribute — that's a feature exclusive to LinearLayout. So any weight values you set on your RelativeLayout or its children won't do anything at all, which explains why your width distribution isn't working as expected.
Let me walk you through two solid solutions tailored to your needs (equal width in portrait mode, 2/3 vs 1/3 split in landscape):
Solution 1: Use LinearLayout + Orientation-Specific Layouts (Beginner-Friendly)
The most straightforward approach is to create separate layout files for portrait and landscape modes. Android will automatically load the correct one based on the screen orientation.
Portrait Layout (res/layout/activity_return_area.xml)
Replace your RelativeLayout root with a horizontal LinearLayout, then set both child LinearLayouts to use layout_weight="1" (so they split the width evenly):
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:background="@color/colorBackgroundGray" tools:context="com.myCompany.myProduct.activities.ReturnAreaActivity"> <!-- First vertical LinearLayout (50% width in portrait) --> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:orientation="vertical"> <FrameLayout android:id="@+id/FragmentFrame" android:layout_width="match_parent" android:layout_height="match_parent" /> <include android:id="@+id/include2" layout="@layout/frm1" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1.7" /> </LinearLayout> <!-- Second vertical LinearLayout (50% width in portrait) --> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:paddingLeft="5dp" android:orientation="vertical"> <include android:id="@+id/include" layout="@layout/layout_numpad5" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1.3" /> </LinearLayout> </LinearLayout>
Landscape Layout (res/layout-land/activity_return_area.xml)
Create this folder and file if it doesn't exist. Use the same structure, but adjust the weights to 2 and 1 for the 2/3 vs 1/3 split:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:background="@color/colorBackgroundGray" tools:context="com.myCompany.myProduct.activities.ReturnAreaActivity"> <!-- First vertical LinearLayout (2/3 width in landscape) --> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" android:orientation="vertical"> <FrameLayout android:id="@+id/FragmentFrame" android:layout_width="match_parent" android:layout_height="match_parent" /> <include android:id="@+id/include2" layout="@layout/frm1" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1.7" /> </LinearLayout> <!-- Second vertical LinearLayout (1/3 width in landscape) --> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:paddingLeft="5dp" android:orientation="vertical"> <include android:id="@+id/include" layout="@layout/layout_numpad5" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1.3" /> </LinearLayout> </LinearLayout>
Solution 2: Use ConstraintLayout (Modern, Single Layout File)
If you prefer to maintain one layout file, ConstraintLayout's percentage-based constraints can handle this. You'll need a tiny bit of Java code to switch constraints when the orientation changes:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorBackgroundGray" tools:context="com.myCompany.myProduct.activities.ReturnAreaActivity"> <!-- First vertical LinearLayout --> <LinearLayout android:id="@+id/first_container" android:layout_width="0dp" android:layout_height="match_parent" android:orientation="vertical" app:layout_constraintWidth_percent="0.5" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/second_container"> <FrameLayout android:id="@+id/FragmentFrame" android:layout_width="match_parent" android:layout_height="match_parent" /> <include android:id="@+id/include2" layout="@layout/frm1" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1.7" /> </LinearLayout> <!-- Second vertical LinearLayout --> <LinearLayout android:id="@+id/second_container" android:layout_width="0dp" android:layout_height="match_parent" android:paddingLeft="5dp" android:orientation="vertical" app:layout_constraintWidth_percent="0.5" app:layout_constraintLeft_toRightOf="@+id/first_container" app:layout_constraintRight_toRightOf="parent"> <include android:id="@+id/include" layout="@layout/layout_numpad5" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1.3" /> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
Then add this code to your ReturnAreaActivity.java to handle orientation changes:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); ConstraintLayout root = findViewById(R.id.root_layout); ConstraintSet constraintSet = new ConstraintSet(); constraintSet.clone(root); if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { constraintSet.setPercentWidth(R.id.first_container, 0.6667f); constraintSet.setPercentWidth(R.id.second_container, 0.3333f); } else { constraintSet.setPercentWidth(R.id.first_container, 0.5f); constraintSet.setPercentWidth(R.id.second_container, 0.5f); } constraintSet.applyTo(root); }
Don't forget to add android:configChanges="orientation|screenSize" to your activity in AndroidManifest.xml to avoid recreating the activity on rotation.
A quick note: I removed the hardcoded layout_marginStart="220dp" from your second include — hardcoded margins break on different screen sizes, and the layout weight/split will handle positioning automatically.
内容的提问来源于stack exchange,提问作者Tom

