从LayoutParams说起到代码动态布局

从LayoutParams说起到代码动态布局

本文说两点
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。其最终展现的效果和对顶代码布局代码如下:

    接下来在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());
        }
    }

    对比

    一.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子控件的位置

    这里写图片描述

    效果图大致如上,代码也是比较简单的,直接附上就好:

    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>
    

    本篇完。

    猜你喜欢

    转载自blog.csdn.net/zhangqunshuai/article/details/81189027