android动态添加View,margin未失效

一:如何动态插入View (源码:SDK30)
在讲实现前,我们先看下如何动态插入View,因为这里是通过xml文件来写的布局,所以就涉及到一个xml转换成View的问题,可以通过LayoutInflater类来转换
主要看inflate方法,他有三个参数:
第一个(resource):布局代码,例如R.layout.xx
第二个(root):需要插入的布局的父布局
第三个(attachToRoot):是否需要附加到root上

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)`

二:布局两种情况

第一种,设置root==mainRoot,attchToRoot==false

//解析R.layout.layout_run_view,返回View对象,
//attachToRoot == true,返回的就是root
//attachToRoot == false,返回的就是设置LayoutParams的View
val mRunTipView = LayoutInflater.from(this).inflate(R.layout.layout_run_view, mainRoot, false)
val layoutParams = mRunTipView.layoutParams as ConstraintLayout.LayoutParams
layoutParams.apply {
    topToTop = ConstraintLayout.LayoutParams.PARENT_ID
}
//把View添加到布局中
mainRoot?.addView(mRunTipView, layoutParams)

第二种,设置root==null,attchToRoot==false

与第一种的区别是,此时inflate返回的是没有设置LayoutParams的View,就需要我们自己生成一个ConstraintLayout.LayoutParams传进去,如下代码:

val mRunTipView =
        LayoutInflater.from(this).inflate(R.layout.layout_run_view1, null,false)
//创建LayoutParams
val layoutParams = ConstraintLayout.LayoutParams(
    ConstraintLayout.LayoutParams.MATCH_PARENT,
    ConstraintLayout.LayoutParams.WRAP_CONTENT
).apply {
    topToTop = ConstraintLayout.LayoutParams.PARENT_ID
}
 
//把View添加到布局中
mainRoot?.addView(mRunTipView, layoutParams)

两种情况都不会生效,原因是因为我们设置的LayoutParams的高是WRAP_CONTENT,而他布局里又没有子控件自然就没有高度

三:解决方法有两个:
1.修改LayoutParams,固定高度如下:

val layoutParams = ConstraintLayout.LayoutParams(
    ConstraintLayout.LayoutParams.MATCH_PARENT,
    100
)

2.在插入布局中增加子控件或者padding
修改下R.layout.layout_run_view的布局,代码如下:
仅仅是把layout_height变成wrap_content,增加paddingBottom="50dp"(你也可以在布局里放个50dp的View)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="50dp"
    android:layout_margin="50dp"
    android:background="#EE000000">
<!--中间代码省略-->
</RelativeLayout>

四:总结

  1. 在代码中,ConstraintLayout与其他布局的区别。在xml中很常见,但是在代码中却容易疏漏。
  2. 在需要在代码中插入布局时,可分为以下几种
    2.1. 不需要返回生成的View,直接插入到对应的布局中
LayoutInflater.from(this).inflate(R.layout.layout_run_view, mainRoot,true)
//或者
LayoutInflater.from(this).inflate(R.layout.layout_run_view, mainRoot)

2.2. 需要返回生成的View,可能需要对View进行一些动画操作,比较方便

val mRunTipView =
        LayoutInflater.from(this).inflate(R.layout.layout_run_view, mainRoot,false)
mainRoot?.addView(mRunTipView)
//mRunTipView 旋转,平移。。。

2.3. 需要返回生成的View,自己对View的位置大小进行修改

val mRunTipView =
      LayoutInflater.from(this).inflate(R.layout.layout_run_view, null)
//等价于下面这种
val mRunTipView =
      LayoutInflater.from(this).inflate(R.layout.layout_run_view, null,false)
 
 
//创建LayoutParams
val layoutParams = ConstraintLayout.LayoutParams(
  100,
  100
).apply {
  topMargin = 100
}
 
//把View添加到布局中
mainRoot?.addView(mRunTipView,layoutParams)
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/21945,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?