一、前期基础知识储备

首先看几个使用LayoutParams的实例:

1、《Android开发艺术探索》第8章,Java代码中动态设置按钮时 通过LayoutParams参数设置按钮位置x、y参数 及Gravity位置信息,从而动态的添加进一个随手势移动的按钮,类似于悬浮窗效果。

    public void onButtonClick(View view) {if (view == btnTest1) {btnTest = new Button(this);btnTest.setText("滑动按钮");layoutParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,0, 0,//0,0 分别是type和flags参数,在后面分别配置了PixelFormat.TRANSPARENT);layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;//申明以下type时 需要申请权限android.permission.SYSTEM_ALERT_WINDOWlayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;layoutParams.gravity = Gravity.LEFT | Gravity.TOP;layoutParams.x = 100;layoutParams.y = 300;windowManager.addView(btnTest2, layoutParams);btnTest.setOnTouchListener(this);}}

2、《Android开发艺术探索》第3章,通过设置LayoutParams参数实现控件的滑动。

 MarginLayoutParams params = (MarginLayoutParams) mButton.getLayoutParams();params += 100;params.leftParams += 100; //实现按钮控件往左滑动100pxmButton.requestLayout();//mButton.setLayoutParams(params);
        mPrimeViewPager = (ViewPager) view.findViewById(R.id.prime_viewPager);LinearLayout.LayoutParams viewPager_lp = (LinearLayout.LayoutParams)mPrimeViewPager.getLayoutParams();viewPager_lp.width = (int) (ScreenUtils.getScreenWidth() * 0.57);viewPager_lp.height = viewPager_lp.width * 16 / 9;mPrimeViewPager.setLayoutParams(viewPager_lp);

注意:LayoutParams,每个view都需要一个LayoutParams,告诉父容器的一些放入规则和方式,这时候该view的LayoutParams要与父容器的LayoutParam相互对应,比如该view的父容器使用的LinearLayout.LayoutParam,该view的布局类型也要对应着LinearLayout.LayoutParam,不然的话回报类型转换错误.。或者也可以直接使用ViewGroup.MarginLayoutParams。

3、在笔者之前的文章《横向滑动视图HorizontalScrollView精炼详解》 有以下代码,为HorizontalScrollView中动态添加TextView,进行数据填充。

 private void bindHZSWData()  { //为布局中textview设置好相关属性  LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,   ViewGroup.LayoutParams.WRAP_CONTENT);  lp.gravity = Gravity.CENTER;  lp.setMargins(20, 10, 20, 10);  for (int i = 0; i < data.size(); i++)  {TextView textView = new TextView(this);  textView.setText(data.get(i));  textView.setTextColor(Color.WHITE);textView.setLayoutParams(lp);  container.addView(textView);container.invalidate();    }  } 

4、实际开发中,笔者碰到自定义View时重写onMeasure()后改变View的布局时,view位置也要进行相应调整,所以写了一个方法,里面通过LayoutParams.Gravity= Gravity.CENTER,控制该view的位置为居中。

    public void setParams() {FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();lp.gravity = Gravity.CENTER;this.setLayoutParams(lp);this.invalidate();}

以上的例子都是利用LayoutParams类实现新view的添加或者已有view位置的调整。我们来看一下官方文档中对于这个类的描述。打开Android开发者文档,键入LayoutParams时会发现出来很多个和LayoutParams相关的类。本篇文章中,我们只关注ViewGroup.LayoutParams中的LayoutParams类。

public static class ViewGroup.LayoutParamsextends Object.可以看到ViewGroup.LayoutParams是一个静态的直接继承自Object的类,那么可以判断其为基类,文档往下看,我们看到:

果然,所有的LayoutParams类都是继承自ViewGroup.LayoutParams。其实ViewGroup.LayoutParams很好理解,这个类里面的成员变量最主要包括两个——width和height,对应在XML布局中的android:layout_height和android:layout_width,也就是所有的View控件都需要写入的两个属性。接着,笔者在截图中标注了四个具体的LayoutParams子类,这四个类在开发中是用到最多的。

二、上代码,具体使用LayoutParams类

(1)使用LayoutParams类动态创建新的布局元素

①定义一个XML布局,根布局为线性布局,布局中不放入任何控件;

    <?xml version="1.0" encoding="utf-8"?><LinearLayout 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:id="@+id/root_ll"tools:context="com.example.administrator.myviewtest.MainActivity"></LinearLayout>

②在Activity代码中动态的为整个布局增加一个TextView,要求对其属性进行设置;

private LinearLayout mLinearLayout;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mLinearLayout = (LinearLayout) findViewById(R.id.root_ll);//设置TextView的width和height 对应XML布局中的android:layout_width和android:layout_height属性//这里的ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT是作为构造方法的参数传入的LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);//设置TextView的gravity 对应于XML布局中layout_gravitylp.gravity = Gravity.CENTER_HORIZONTAL;//设置TextView的Margin属性,包括left、top、right、botomlp.setMargins(20,20,20,20);//新建TextView实例TextView textView = new TextView(this);textView.setText("Android cool");//为textView实例绑定创建好的LayoutParamstextView.setLayoutParams(lp);//调用LinearLayout的addView方法 动态的mLinearLayout.addView(textView);
}

这里,我们以LinearLayout的LayoutParams实例为例,进行创建。

(2)使用LayoutParams类动态改变已有的布局元素的位置信息

①定义一个XML布局,根布局为线性布局,布局中加入一个基础的文本控件;

    <?xml version="1.0" encoding="utf-8"?><LinearLayout 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:id="@+id/root_ll"tools:context="com.example.administrator.myviewtest.MainActivity"><--注意这里TextView是放在LinearLayout中的 所以待会取Params时使用的是LinearLayout的 --><TextViewandroid:id="@+id/textview"android:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout>

②在Activity中利用LayoutParams类动态的改变基础文本控件的位置信息;

private LinearLayout mLinearLayout;
private TextView mTextView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mLinearLayout = (LinearLayout) findViewById(R.id.root_ll);mTextView = (TextView) findViewById(R.id.textview);//传入已有控件的LayoutParams信息作为LinearLayout.LayoutParams构造方法的参数//注意TextView的父容器是LinearLayout,所以使用的是LinearLayout.LayoutParamsLinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(mTextView.getLayoutParams());//设置已有文本控件位置为横向居中lp.gravity = Gravity.CENTER_HORIZONTAL;//设置已有文本空间的Marginlp.setMargins(60,60,60,60);mTextView.setText("nice Android");//将创建好的LayoutParams绑定到已有文本控件mTextView.setLayoutParams(lp);
}

可以看到,这里使用LayoutParams的方法是一样的,只是在创建LayoutParams实例的时候传入构造方法的参数不一样了,在已有控件的前提下,我们传入的是已有空间的LayoutParams信息。

(3)LayoutParams类的构造方法

我们可以看见ViewGroup.LayoutParams的构造方法有三个(子类会多一个),我们在动态创建新View的时候,调用的是LayoutParams第二个构造方法,传入wrap_content或者match_parent常量或者固定值即可;在动态调整已有控件的位置信息时,我们调用的是LayoutParams的第三个构造方法,传入的参数是已有控件的LayoutParams的信息,利用view. getLayoutParams()即可获得。

总结:使用LayoutParams的最常见的两种场景就是文章中提到的两种:①动态创建新控件元素;②调整已有布局元素的位置信息,更难一点的用法出现在自定义View中,我们重写onMeasure()方法之后,通常需要对自定义view的位置进行新的调整,在这个过程中,我们不是通过onLayout()方法实现的(onLayout用于实现ViewGroup对其内部view重新布局时调用),而是使用设置自定义View的LayoutParams.gravity实现的,自定义View也是一个view,这里可以将这种LayoutParams的用法归为第二种-对已有控件的位置进行调整。

本文代码中是使用的LinearLayout.LayoutParams,实际开发中还可能使用到其他类型的LayoutParams,如开篇中,讲到的《Android开发艺术探索》中使用的就是WindowManager.LayoutParamsViewGroup.MarginLayoutParams,用法是类似的,但是各自可以设置的属性是不同的,比如,WindowManager.LayoutParams可以直接设置view的横纵坐标信息,直接控制view在屏幕中的显示位置;ViewGroup.MarginLayoutParams可以很方便的设置view各边的margin属性,可以用来实现滑动效果。感兴趣的读者可以到开发者文档中进行了解。

Android中LayoutParams类精炼详解相关推荐

  1. android studio parcelable,Android中Parcelable的使用详解

    Parcelable与Serializable Serializable是Java为我们提供的一个标准化的序列化接口. Parcelable是Android为我们提供的序列化的接口. 对比: 1.Pa ...

  2. Android中的四大组件详解

    Android中的四大组件详解 我们都知道Android系统应用层框架中,为开发者提供了四大组件来便于应用的开发,它们是Activity.Service.BroadcastReceiver.Conte ...

  3. C#中NameValueCollection类用法详解

    C#中NameValueCollection类用法详解,1.NameValueCollection类集合是基于 NameObjectCollectionBase 类. 但与 NameObjectCol ...

  4. Android刘海屏适配精炼详解

    一.前期基础知识储备 话不多说,这么多刘海屏手机今年集中爆发,所以尽管刘海屏不好看,但是还是要适配. 2017年苹果X开启了刘海屏时代,2018年集中爆发,纷纷采取刘海屏这一策略来实现全面屏的概念(看 ...

  5. RxJava操作符在android中的使用场景详解(一)

    转载请注明出处:http://www.wangxinarhat.com/2016/04/19/2016-04-19-rxjava-android-operate1/ 最近学习了RxJava在andro ...

  6. Android中图片压缩方案详解

    如感觉排版不舒服,可移步至此处查看 图片的展示可以说在我们任何一个应用中都避免不了,可是大量的图片就会出现很多的问题,比如加载大图片或者多图时的OOM问题,可以移步到Android高效加载大图.多图避 ...

  7. Android中R.java文件详解

    R.java文件有两种,两种文件作用一样都是获取资源的引用,区别在于一个存放着我们写的项目中资源的引用,另一个存放着系统定义好的一些资源 1.1 项目的R.java文件 先说第一种是项目编译出来的R. ...

  8. Java中String类intern()详解

    1.背景 在开发过程中很多朋友,由于不会正确使用intern(),导致开发的程序,执行效率比较差.同时最近发现一道非常有意思的关于intern()的面试题,这道面试题还是有不小的难度,相信很多朋友看到 ...

  9. Android中AIDL的使用详解

    Git: https://github.com/whtchl/AidlTemplate AIDL用来做什么 AIDL是Android中IPC(Inter-Process Communication)方 ...

最新文章

  1. 纷纷布局的全光网,是你所熟知的吗?
  2. nginx配置详解与优化
  3. ASP.NET常用语句(转载)
  4. Python ML环境搭建与学习资料推荐
  5. 单高斯分布模型GSM,高斯混合模型GMM
  6. 阿里云高级技术专家:面向5G的云网一体及云原生应用实践
  7. 工业相机硬汉!这款相机被NASA选择,全程记录毅力号登陆火星
  8. [Web 前端] CSS篇之 4. position 和 display 的取值和各自的意思和用法
  9. 项目“”受源代码管理,向源代码管理注册此项目时出错。。
  10. Don’t Worry.Be Scruffy.
  11. ES6学习之 -- Set数据结构
  12. java rails orm_php 模拟 rails 中的 ActionRecord 的 ORM (一)
  13. python3 xpath_【学习笔记】Python3-爬虫-xpath
  14. c4d打开没反应_(图文+视频)C4D野教程:总结四种制作漩涡样条的方法
  15. 常州大学移动宽带上网助手——安装包v1.4
  16. 教你查看sql server 2000 sp4补丁是否安装成功 (安装补丁后可以远程访问)
  17. appium之微信公众号自动化测试实战
  18. 1.1.从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队。如果该 年没有举办世界杯,则输出:没有举办世界杯。
  19. Windows光标选中字符切换到输入字符快捷键
  20. 41. 整合RabbitMQ发送短信

热门文章

  1. 已经发车的票还能取出来吗_我买了张高铁票(已付过钱),但是车已经开了,我没上车,票也没取,还能在取出票吗?...
  2. 比特大陆裁员85%,区块链行业彻底入深冬
  3. 一款可以制作像素破损撕拉花屏效果的AE脚本:Datamosh
  4. 红黑的宿命(米兰夺冠庆祝贴)
  5. 如何直接打开Visual Studio 2013 的帮助文档
  6. python网络编程web教程_python网络编程学习笔记(10):webpy框架
  7. 【PAT甲级】1001 A+B Format
  8. AutoLisp从入门到放弃(七)
  9. AutoLisp从入门到放弃(八)
  10. 冲刺酒馆第一股:海伦司即将负债上市,距离夜间星巴克还有多远?