从LayoutParams说起到代码动态布局
2017-02-17 本文已影响8138人
阿敏其人
本文说两点
1、介绍LayoutParams并且简单代码实现xml布局效果
2、代码动态控制RelativeLayout子控件的布局变化
一、LayoutParams
LayoutParams
如果直接从字面上来看,这应该是 布局参数 的意思。
我们常常利用LayoutParams来做代码动态布局,现在再来赘述一下它吧。
在安卓的布局世界里面就2个东西,要么是容器(ViewGroup),要么是控件(View)。
个性与规则并存,我们一个小小控件,要张扬个性,也要遵守规矩,基本宽高我们时候要的,左对齐还是居中对齐我们也不一样,这些不用如果在xml的布局文件自然是几行代码的事情,但是换成Java代码的话就需要LayoutParams来出力了。
一.1、LayoutParams的几个小特点
LayoutParams 是 子控件 用来告诉 父控件 自己要如何布局时用的。
- LayoutParams 是ViewGroup的一个内部类,这是一个基类,主要描述了宽高.
宽与高有三种指定方式- FILL_PARENT (renamed MATCH_PARENT in API Level 8 and higher) 填充父窗体
- WRAP_CONTENT 包裹内容
- an exact number 精准描述
- 每一个继承自ViewGroup的容器比如RelativeLayout等自己对应的LayoutParams,而且这些LayoutParams又有自己独特的属性,比如RelativeLayout.LayoutParams可以设置RelativeLayout.RIGHT
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(vgLp);
params.addRule(RelativeLayout.RIGHT_OF,R.id.mTvBlue);
- 子控件在获取LayoutParams一定要和当前父控件的容器类型保持一致。
比如TextView是在LinearLayout下面的,那么LayoutParams就必须是 LinearLayout.LayoutParams。比如上面例子代码中的
LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(textView.getLayoutParams());
textParams.width = dip2px(LikeXmlActivity.this,200);
textParams.height = dip2px(LikeXmlActivity.this,30);
textView.setLayoutParams(textParams);
.
.
.
一.2、代码简单实现xml效果
文字说完了,来点代码吧
我们先看下面的代码
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:layout_width="200dp"
android:layout_height="30dp"
android:text="代码在此"
android:gravity="center"
android:background="#6f00"
/>
</LinearLayout>
这个一段非常简单的安卓布局文件的代码,一个LinearLayout里面放了一个TextView。其最终展现的效果和对顶代码布局代码如下:
Paste_Image.png接下来在Activity中换成代码来实现布局
public class LikeXmlActivity extends AppCompatActivity {
private LinearLayout mRootView;
private LinearLayout mLinearLayout;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_like_xml);
mRootView = (LinearLayout) findViewById(R.id.mRootView);
// 第一步,把 LinearLayout 添加到布局里面
// 给LinearLayoutnew一个LinearLayout.LayoutParams,并且通过 etLayoutParams 让layout更新
// LayoutParams可以从父窗体获得也可以自己new出来,这里我们采用自己new的方式
mLinearLayout = new LinearLayout(LikeXmlActivity.this);
mLinearLayout.setBackgroundColor(Color.parseColor("#0000ff"));
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
mLinearLayout.setLayoutParams(layoutParams);
mRootView.addView(mLinearLayout);
// 第二步,把TextView 添加到 第一步的 LinearLayout 里面
TextView textView = new TextView(LikeXmlActivity.this);
textView.setText("代码在此2");
textView.setBackgroundColor(Color.parseColor("#ff0000"));
textView.setGravity(Gravity.CENTER);
mLinearLayout.addView(textView);
// 第三步,把TextView获取对应父窗体类型的LayoutParams 并且设置参数更新layout
LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(textView.getLayoutParams());
textParams.width = dip2px(LikeXmlActivity.this,200);
textParams.height = dip2px(LikeXmlActivity.this,30);
//textParams.gravity = Gravity.CENTER; // 无效,这样并不能让文字在控件里居中
textView.setLayoutParams(textParams);
}
private int dip2px(Context context, float dipValue)
{
Resources r = context.getResources();
return (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, dipValue, r.getDisplayMetrics());
}
}
对比
Paste_Image.png一.3、LayoutParams的使用小结
step 1、获得对应父窗体类型的LayoutParams
LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(textView.getLayoutParams());
step 2、对控件本身的宽高和特有的属性比如对齐方式等进行设置
textParams.width = dip2px(LikeXmlActivity.this,200);
textParams.height = dip2px(LikeXmlActivity.this,30);
step 3、利用setLayoutParams方法对控件的layout进行布局更新
textView.setLayoutParams(textParams);
.
.
.
二、DEMO —— 代码动态控制RelativeLayout子控件的位置
lp.gif效果图大致如上,代码也是比较简单的,直接附上就好:
Activity
public class MoveActivity extends AppCompatActivity {
private ImageView mIv;
private TextView mTvBlue;
private TextView mTvGreen;
private ViewGroup.LayoutParams mVgLp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_move);
mIv = (ImageView) findViewById(R.id.mIv);
mTvBlue = (TextView) findViewById(R.id.mTvBlue);
mTvGreen = (TextView) findViewById(R.id.mTvGreen);
mVgLp = mIv.getLayoutParams();
findViewById(R.id.mTvMoveRight).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ViewGroup.LayoutParams vg_lp = mIv.getLayoutParams();
// RelativeLayout.LayoutParams 不可抽取为成员变量
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(vg_lp);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, R.id.mIv);
mIv.setLayoutParams(params); //使layout更新
}
});
findViewById(R.id.mTvMoveLeft).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 左 (默认处于顶部,所以看起来是左上)
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(mVgLp);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
mIv.setLayoutParams(params);
}
});
findViewById(R.id.mTvCenter).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 居中
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(mVgLp);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
mIv.setLayoutParams(params);
}
});
findViewById(R.id.mTvLeftVer).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 左部垂直居中
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(mVgLp);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT|RelativeLayout.CENTER_VERTICAL);
mIv.setLayoutParams(params);
}
});
findViewById(R.id.mTvRightBot).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 右下
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(mVgLp);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
mIv.setLayoutParams(params);
}
});
// 绿在蓝右边
findViewById(R.id.mTvaGRightB).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ViewGroup.LayoutParams vgLp = mTvGreen.getLayoutParams();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(vgLp);
params.addRule(RelativeLayout.RIGHT_OF,R.id.mTvBlue);
mTvGreen.setLayoutParams(params);
}
});
// 绿在蓝下边
findViewById(R.id.mTvGElowB).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ViewGroup.LayoutParams vgLp = mTvGreen.getLayoutParams();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(vgLp);
params.addRule(RelativeLayout.BELOW,R.id.mTvBlue);
mTvGreen.setLayoutParams(params);
}
});
}
}
.
.
.
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.amqr.movetest.MoveActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="@+id/mTvMoveLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#6600ff00"
android:padding="10dp"
android:layout_margin="10dp"
android:text="黑色最左!!"/>
<TextView
android:id="@+id/mTvMoveRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#6600ff00"
android:layout_margin="10dp"
android:text="黑色最右!!"/>
<TextView
android:id="@+id/mTvCenter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#6600ff00"
android:padding="10dp"
android:layout_margin="10dp"
android:text="黑色居中"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="@+id/mTvLeftVer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#6600ff00"
android:layout_margin="10dp"
android:text="黑色靠左垂直居中"/>
<TextView
android:id="@+id/mTvRightBot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#6600ff00"
android:padding="10dp"
android:layout_margin="10dp"
android:text="黑色右下角"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="@+id/mTvaGRightB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#6600ff00"
android:layout_margin="10dp"
android:text="绿在蓝右边"/>
<TextView
android:id="@+id/mTvGElowB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#6600ff00"
android:padding="10dp"
android:layout_margin="10dp"
android:text="绿在蓝下边"/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200px"
android:background="#66ff0000"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RelativeLayout"
android:layout_centerInParent="true"
/>
<ImageView
android:id="@+id/mIv"
android:layout_width="30dp"
android:layout_height="40px"
android:background="#000"
android:layout_centerHorizontal="true"
/>
<TextView
android:id="@+id/mTvBlue"
android:layout_width="20dp"
android:layout_height="20dp"
android:text="蓝"
android:gravity="center"
android:background="#660000ff"
/>
<TextView
android:id="@+id/mTvGreen"
android:layout_width="20dp"
android:layout_height="20dp"
android:text="绿"
android:gravity="center"
android:background="#6600ff00"
android:layout_below="@id/mTvBlue"
/>
</RelativeLayout>
</LinearLayout>
本篇完。