背景:app中在横竖屏切换的时候需要对布局做一些调整,但是xml布局文件中布局已经写死(其实也可以用两套布局layout来实现,但这里不讨论这种方法),所以需要结合onConfigurationChange方法在代码中对布局的属性参数做一些修改,对于如何做的修改写此文作为记录
总述:修改布局主要有下面三步
1.通过控件对象获取对应的布局参数对象
2.用参数对象设置需要的属性调整布局
3.将此参数对象设置回原先的控件对象
下面举例分步解释:
先贴示例布局
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/xxx1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/xxx2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/xxx3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</RelativeLayout>
我们使用上面布局中xxx1和xxx2控件来作为例子讲解,在activity中获取这两个控件对象
private TextView textView1,textView2;
textView1 = (TextView) findViewById(R.id.xxx1);
textView2 = (TextView) findViewById(R.id.xxx2);
onConfigurationChanged方法中做具体布局修改的操作
1.通过控件对象获取对应的布局参数对象:一般是new出来LinearLyout.LayoutParams、ReletiveLayout.LyoutParam两种其中一种并且将需要设置的控件的LayoutParam作为参数传入,是用LinearLyout.LayoutParams还是ReletiveLayout.LyoutParam由你需要设置的控件的父控件决定,注意是其父控件决定,所以如果需要获取textView1和textView2的布局参数对象的话通过布局可以看出textView1是LinearLyout.LayoutParams,而textView2是ReletiveLayout.LyoutParam,故获取代码如下:
LinearLayout.LayoutParams paramTextView1 = new LinearLayout.LayoutParams(textView1.getLayoutParams());
RelativeLayout.LayoutParams paramTextView2 = new RelativeLayout.LayoutParams(textView2.getLayoutParams());
这样,通过上面的两行代码即可获取到布局参数对象paramTextView1和paramTextView2,还有另外一种写法直接通过控件获取到布局参数对象后直接强转,如下:
LinearLayout.LayoutParams paramTextView1 = (LinearLayout.LayoutParams) textView1.getLayoutParams();
RelativeLayout.LayoutParams paramTextView2 = (RelativeLayout.LayoutParams) textView2.getLayoutParams();
上面这两种方式应该都可以。
2.用参数对象设置需要的属性调整布局:1中已经获取到布局参数对象,下面通过此对象设置需要的属性
最基本的控件宽高设置,有三种设置的值1.充满父控件2.自适应内容3.直接设置具体值(注意这里设置的值均为px单位)
paramTextView1.width = LinearLayout.LayoutParams.MATCH_PARENT;//充满父控件
paramTextView1.width = LinearLayout.LayoutParams.WRAP_CONTENT;//自适应内容
paramTextView1.width = DisplayUtils.dp2px(this, 10);//直接设置具体值
其他的设置的参数下面源码给出,其中DispalyUtils是一个工具类其中的静态方法dp2px负责把dp值转化为px值,下面源码也会给出
3.最后将此参数对象设置回原先的控件对象使布局修改生效:
textView1.setLayoutParams(paramTextView1);
部分代码源码
public class DisplayUtils {
public static Point getScreenResolution(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point screenResolution = new Point();
if (android.os.Build.VERSION.SDK_INT >= 13) {
display.getSize(screenResolution);
} else {
screenResolution.set(display.getWidth(), display.getHeight());
}
return screenResolution;
}
public static int dp2px(Context context, float dpValue) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.getResources().getDisplayMetrics());
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int config = newConfig.orientation;
if(config == Configuration.ORIENTATION_PORTRAIT) {
//textView1-----------------------------------------------------------------------------
//获取布局参数对象
LinearLayout.LayoutParams paramTextView1 = new LinearLayout.LayoutParams(textView1.getLayoutParams());
//通过布局参数对象修改控件参数
//修改控件宽
paramTextView1.width = LinearLayout.LayoutParams.MATCH_PARENT;//充满父控件
paramTextView1.width = LinearLayout.LayoutParams.WRAP_CONTENT;//自适应内容
paramTextView1.width = DisplayUtils.dp2px(this, 10);//直接设置具体值
//修改控件高
paramTextView1.height = LinearLayout.LayoutParams.MATCH_PARENT;//充满父控件
paramTextView1.height = LinearLayout.LayoutParams.WRAP_CONTENT;//自适应内容
paramTextView1.height = DisplayUtils.dp2px(this, 10);//直接设置具体值
//修改控件gravity
paramTextView1.gravity = Gravity.CENTER;//居中
paramTextView1.gravity = Gravity.CENTER_HORIZONTAL;//水平居中
paramTextView1.gravity = Gravity.CENTER_VERTICAL;//垂直居中
paramTextView1.gravity = Gravity.NO_GRAVITY;//不设置gravity属性
//一次性设置左,上,右,下四个方位的margin均为10dp
paramTextView1.setMargins(DisplayUtils.dp2px(this, 10), DisplayUtils.dp2px(this, 10), DisplayUtils.dp2px(this, 10), DisplayUtils.dp2px(this, 10));
//设置左margin为10dp
paramTextView1.leftMargin = DisplayUtils.dp2px(this, 10);
//设置左margin为10dp
paramTextView1.rightMargin = DisplayUtils.dp2px(this, 10);
//设置左margin为10dp
paramTextView1.topMargin = DisplayUtils.dp2px(this, 10);
//设置左margin为10dp
paramTextView1.bottomMargin = DisplayUtils.dp2px(this, 10);
//将布局参数对象设置到控件对象中
textView1.setLayoutParams(paramTextView1);
//textView2-----------------------------------------------------------------------------
//获取布局参数对象
RelativeLayout.LayoutParams paramTextView2 = new RelativeLayout.LayoutParams(textView2.getLayoutParams());
//通过布局参数对象修改控件参数
//修改控件宽
paramTextView1.width = RelativeLayout.LayoutParams.MATCH_PARENT;
paramTextView1.width = RelativeLayout.LayoutParams.WRAP_CONTENT;
paramTextView1.width = DisplayUtils.dp2px(this, 10);
//修改控件高
paramTextView1.height = RelativeLayout.LayoutParams.MATCH_PARENT;
paramTextView1.height = RelativeLayout.LayoutParams.WRAP_CONTENT;
paramTextView1.height = DisplayUtils.dp2px(this, 10);
//修改控件位置为水平居中
paramTextView2.addRule(RelativeLayout.CENTER_HORIZONTAL);
//修改控件位置为id为xxx3的控件上方
paramTextView2.addRule(RelativeLayout.ABOVE, R.id.xxx3);
//将布局参数对象设置到控件对象中
textView2.setLayoutParams(paramTextView2);
}else if(config == Configuration.ORIENTATION_LANDSCAPE){
// TODO: 18/2/22
}
}