Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解

时间:2022-09-17 17:35:42

废话不多说,本文将会层层深入给大家讲解如何动态的生成一个完整的界面。

本文内容:

  1. Java代码中动态生成View
  2. Java代码中动态设置View的位置,以及其他的属性
  3. LayoutParams详解

一、Java代码中动态的生成View

我们以创建一个Button为例子。 
1、首先我们在onCreate方法中创建一个Button实例:

Button button=new Button(this);        
  • 1

2、创建了Button实例下面我们就要指定它在哪个界面中显示: 
首先第一步找到我们要显示的界面: 
首先把setContentView()删掉(后文会讲)。 
有两种方法:

  • 使用LayoutInflate
  • 使用findViewById

1)LayoutInflate使用来找到一个布局文件:

      ViewGroup viewGroup = (ViewGroup) LayoutInflater.from(this).inflate(R.layout.activity_main, null);
  • 1

返回的是布局文件的最外层的View容器, 
贴一下布局文件中的XML代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.miko.zd.dynamicview.MainActivity"
android:id="@+id/relative"> </RelativeLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这里LayoutInflate返回的就是最外层的RelativeLayout。RelativeLayout继承于ViewGroup因此完全没有问题。 
2)通过FindViewByID返回最外层的View 
第二种方法以第一种一致都是返回最外层的RelativeLayout:

        View viewGroup2 = findViewById(R.id.relative);
  • 1

3、下一步就是要把我们的Button添加到RelativeLayout中了 
使用ViewGroup的addView方法:

 viewGroup.addView(button);
  • 1

运行代码,你会发现界面中什么都没有,为什么呢? 
前文中说过删除setContentView()这个方法,setContenView可以理解为,为Activity绑定一个显示的的布局,我们只是找到了ViewGroup,并且添加了Button,但是没有绑定Activity,因此这里添加一句setContentView(viewGroup);你可能会说,我一开始不删除这一句,不可以么? 
findViewById可以,setContentView()一旦调用,layout就会立刻显示UI,而后的findViewById,找到RelativeLayout实际上已经加载出来了,添加Button,可以理解为显示出UI后动态的添加View;而inflate只会把Layout形成一个以view类实现成的对象,有需要时再用setContentView(view)显示出来。 
运行结果: 
Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解 
可以看到,相当原始的界面,下一步我们就要设置Button的位置以及相关属性了

二、Java代码中动态设置View的位置,以及其他的属性

1、首先我们为我们的Button设置一个背景,以及文字:

button.setBackgroundColor(Color.RED);
button.setText("Hello World");
  • 1
  • 2

Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解 
2、我们下一步想给Button设置长宽: 
你可能会想button会有setHeight,setWidth方法,确实有,而且你可以实现设置长宽,但是如果你要设置Match_parent,Wrap_content,怎么实现呢?这时候我们就要使用LayoutParam方法了。 
首先创建一个Layoutparams实例:

RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(100,100);        
  • 1

不同的布局对应着不同的LayoutParams,我们这里是RelativeLayout所以当然是R.layoutParam这里的两个参数是Button的宽以及高,注意这里的100代表着100px,使用dp可以参照我之前的博客 
dp转px

那么上文中的MATCH 以及WRAP怎么实现呢?

RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
  • 1

运行结果:Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解 
为什么没有效果呢,因为定义了LayoutParam但是没有指定哪一个View因此还需要添加一句

        button.setLayoutParams(params);
  • 1

Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解 
没有任何问题。 
3、设置位置信息 
我们想要使Button居中显示,怎么实现呢? 
还是使用LayoutParams,使用他的addRules方法:

        params.addRule(RelativeLayout.CENTER_IN_PARENT);
  • 1

Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解 
addRules有两个方法:

  • addRule(int verb)
  • addRule(int verb, int anchor) 
    verb我们很好理解,就是各种规定位置的参数,anchor代表什么呢? 
    我们看源码注释: 
    The id of another view to use as an anchor, 
    * or a boolean value (represented as {@link RelativeLayout#TRUE} 
    * for true or 0 for false). For verbs that don’t refer to another sibling 
    * (for example, ALIGN_WITH_PARENT_BOTTOM) just use -1. 
    实际上verb参数可以分为两类,一种是不要任何相对view的,比如ALIGN_WITH_PARENT_BOTTOM这种的参数,另一种需要相对view的参数,例如above,right_of等等,需要一个view来表示位置的参数,这个时候就需要用到anchor,anchor代表的是相对view的id。 
    下面我们再创建一个Button:
ViewGroup viewGroup2 = (ViewGroup) viewGroup.findViewById(R.id.relative);

        Button button = new Button(this);
RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
button.setLayoutParams(params);
button.setBackgroundColor(Color.RED);
button.setText("Hello World");
button.setId(100); Button button1=new Button(this);
RelativeLayout.LayoutParams params1=new RelativeLayout.LayoutParams(200,200);
params1.addRule(RelativeLayout.BELOW,100);
button1.setLayoutParams(params1);
button1.setBackgroundColor(Color.RED);
button1.setText("Hello World"); viewGroup2.addView(button);
viewGroup2.addView(button1);
setContentView(viewGroup);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

注意我们要先给第一个button一个id,因为是动态创建的所以使用setId方法,设id为100, params1.addRule(RelativeLayout.BELOW,100);核心代码,意思是将button1设置在id为100的view的下方。 
运行结果: 
Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解

四、后记

上文我为大家详细解析了View的动态创建,以及动态的添加属性,有几点需要注意的: 
1、上文中的布局都是用的RelativeLayout,实际上你会发现只有RelativeLayout.layoutParam具有addRules方法,这其实是与XML中相对应的,你在LinearLayout中无法使用Right_of等等相对布局的属性,这些都是相通的。 实际上我认为在动态生成界面的几个布局中RelativeLayout是最简单也是最准确的。 
2、为什么要使用动态生成界面?我想在编程中使用XML是无可厚非的,但是App的大趋势是动态化来减少版本更替,这就涉及到一个不要写死的问题,国内已经有很多尝试,即通过服务器动态生成界面。

Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解的更多相关文章

  1. 根据数据库记录动态生成C&num;类及其公共属性并动态执行的解决方案

    原文:根据数据库记录动态生成C#类及其公共属性并动态执行的解决方案 问题: C#中,想动态产生这么一个类: public class StatisticsData    {        public ...

  2. 技巧:Linux 动态库与静态库制作及使用详解

    技巧:Linux 动态库与静态库制作及使用详解 标准库的三种连接方式及静态库制作与使用方法 Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 L ...

  3. 《手把手教你》系列技巧篇(四十四)-java&plus; selenium自动化测试-处理https 安全问题或者非信任站点-下篇(详解教程)

    1.简介   这一篇宏哥主要介绍webdriver在IE.Chrome和Firefox三个浏览器上处理不信任证书的情况,我们知道,有些网站打开是弹窗,SSL证书不可信任,但是你可以点击高级选项,继续打 ...

  4. Java日志管理:Logger&period;getLogger&lpar;&rpar;和LogFactory&period;getLog&lpar;&rpar;的区别(详解Log4j)

    Java日志管理:Logger.getLogger()和LogFactory.getLog()的区别(详解Log4j) 博客分类: Java综合   第一.Logger.getLogger()和Log ...

  5. &OpenCurlyDoubleQuote;全栈2019”Java多线程第二十八章:公平锁与非公平锁详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  6. &OpenCurlyDoubleQuote;全栈2019”Java多线程第二十二章:饥饿线程(Starvation)详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  7. Android——TextView属性XML详解

    Android_TextView属性XML详解 博客分类: android   属性名称    描述 android:autoLink    设置是否当文本为URL链接/email/电话号码/map时 ...

  8. &OpenCurlyDoubleQuote;全栈2019”Java第一百零四章:匿名内部类与外部成员互访详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  9. &OpenCurlyDoubleQuote;全栈2019”Java第九十七章:在方法中访问局部内部类成员详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

随机推荐

  1. 让C&plus;&plus;程序打印自身源码

    本人原创文章,欢迎阅读,禁止转载. 这绝对是惊艳到让你眼前一亮(为了简洁,故意没考虑资源问题和编译警告). #include <iostream> #include <fstream ...

  2. 微信公众平台开发&lpar;112&rpar; 自动更新微信access token

    关键字:Memcache access_token 更新 存储 7200 本文介绍如何存储及更新 access token的方法. 一.Access Token access_token是公众号的全局 ...

  3. Java File类基本操作

    我们可以利用Java.io.File类对文件进行操作,基本操作如下: 1)创建文件: public boolean createNewFile() throws IOException 2)删除文件: ...

  4. C&num;连接SQLite的字符串

    一.C#在不同情况下连接SQLite字符串格式 1.Basic(基本的) Data Source=filename;Version=3; 2.Using UTF16(使用UTF16编码) Data S ...

  5. 蘑菇街teamtalk简介

    这几天在看蘑菇街实时通讯程序teamtalk的安卓端代码.现在对程序的大概情况进行简单的介绍. 蘑菇街的teamtalk开源项目包含了服务器端,Android客户端和iPhone客户端的程序.想要进行 ...

  6. &amp&semi;&amp&semi;运算符,三木运算符与React的条件渲染

    在使用react框架的时候中往往会遇到需要条件渲染的情形,这时候,许多人会设想采用if语句来实现,比如下面,当满足条件condition时,conditonRender渲染组件ComponentA,当 ...

  7. OC语言的面向对象—类和对象、方法

    1. 面向对象和面向过程思想 OC是面向对象的,C是面向过程的.面向对象和面向过程只是解决问题的两种不同思想 1. 面向对象和面向过程的区别 1) 以用电脑听歌为例子 a) 面向过程 ➢ 打开电脑 ➢ ...

  8. Keepalived基础知识-运维小结

    keepalived介绍keepalived观察其名可知,保持存活,在网络里面就是保持在线了,也就是所谓的高可用或热备,它集群管理中保证集群高可用的一个服务软件,其功能类似于heartbeat,用来防 ...

  9. vue中使用全局函数

    方法一: 在mian.js中写入函数: Vue.prototype.bb = function () {        alert('OK'); } 然后在任何组件中都可以调用: this.bb() ...

  10. POJ2229--Sumsets&lpar;动态规划&rpar;

    Farmer John commanded his cows to search for different sets of numbers that sum to a given number. T ...