【问题标题】:android margins not working when dynamically inserting views动态插入视图时android边距不起作用
【发布时间】:2017-07-03 01:05:00
【问题描述】:

我有一个简单的看法:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/contact_selected"
    android:layout_marginTop="10dp"
    android:layout_marginEnd="5dp"
    android:orientation="horizontal"
    android:padding="3dp">
    <TextView
        android:id="@+id/txt_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Billy Bob"
        />
</LinearLayout>

当我将 LinearLayout 标记静态复制到我的主要活动布局中时,边距符合预期。但是,当我动态地将视图添加到主活动布局中时,边距会被忽略。这是我插入视图的方式

LayoutInflater inflater = (LayoutInflater)
        getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.test, null);
TextView txt_title = (TextView)view.findViewById(R.id.txt_title);
txt_title.setText("Dynamic #1");
llayout.addView(view, llayout.getChildCount()-1);

View view2 = inflater.inflate(R.layout.test, null);
txt_title = (TextView)view2.findViewById(R.id.txt_title);
txt_title.setText("Dynamic #2");
llayout.addView(view2, llayout.getChildCount()-1);

它是这样的:

主布局中的容器是一个LinearLayout,它是一个Horizo​​ntalScrollView的子级。任何见解都值得赞赏。

【问题讨论】:

    标签: android dynamic margins


    【解决方案1】:

    当动态添加视图时,您不应该使用 null ViewGroup 父级来扩充 View。所以,换句话说,你应该使用inflater.inflate(R.layout.test, linearLayout, false);。在确定要生成哪种类型的布局参数时使用父级。传递您的父容器(在本例中为您的线性布局),以便它正确地从您的 XML 实例化 ViewGroup.MarginLayoutParams。

    【讨论】:

    • 谢谢,这是一个干净的解决方案,也是我的首选方式。对于其他学习这些东西的人,请注意,因为 inflate(view,parent) 将视图膨胀到父级(作为最后一个子级附加),所以我的测试代码中添加视图的行(即 llayout.addView())将导致一个错误,因为视图已经被插入。在我的情况下,我需要保持一个固定的视图作为最后一个孩子,并在它前面插入新的孩子。因此,我删除了 inflate() 之前的最后一个视图,并将其添加回 inflate() 之后。像魅力一样工作。
    • @JohnWard 实际上,如果您将“inflater.inflate(R.layout.test, linearLayout, false)”与最后一个布尔参数一起使用,您仍然需要 addView。
    • @Flyview 是的。但它也允许您稍后将视图插入到您想要的索引中
    【解决方案2】:

    发生这种情况是因为您需要动态地为布局提供“Margin”。您可以通过创建“LayoutPrams”对象来做到这一点,如下所示:-

    LinearLayout ll = new LinearLayout(this);
    ll.setOrientation(LinearLayout.VERTICAL);
    
    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
     LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    layoutParams.setMargins(30, 20, 30, 0);
    

    在这里,您可以将 LayoutParams 设置为线性布局:

    ll.addView(okButton, layoutParams);
    

    希望对你有帮助。

    【讨论】:

    • 很抱歉,我正在将已批准的答案更改为 Submersed 提供的答案。你的回答很有用,教会了我一些我不知道的东西,但他的回答更清晰,不会强迫我计算边距的下降。再次感谢。
    • 感谢约翰的反馈。
    • 我想知道为什么会这样?为什么不能只在布局文件中设置?
    【解决方案3】:

    首先,您必须获得显示密度。 相关文档为https://developer.android.com/reference/android/util/DisplayMetrics.html

    并获取要设置边距视图的 ID。 就我而言,

    layout_login_box = (ConstraintLayout)findViewById(R.id.login_layout_box);
    
    float density = getResources().getDisplayMetrics().density;
    
    ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams)layout_login_box.getLayoutParams();
    params.setMargins((int) (24  * density),0,(int) (24  * density),(int) (16  * density));
    layout_login_box.setLayoutParams(params);
    

    另外,您可以将 ConstraintLayout 更改为您自己的视图。

    【讨论】:

      猜你喜欢
      • 2020-05-19
      • 2017-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-30
      • 1970-01-01
      • 2011-10-28
      • 1970-01-01
      相关资源
      最近更新 更多