【问题标题】:How to simply create a custom view without duplicate LinearLayout?如何简单地创建一个没有重复 LinearLayout 的自定义视图?
【发布时间】:2020-01-17 13:15:04
【问题描述】:

我发现创建自定义视图的最简单方法是让它从 LinearLayout 继承,这样我就不必处理烦人的事情,比如重写 onLayout() 方法。我在我膨胀的关联 XML 文件的根目录下还有一个 LinearLayout,所以根目录下有 2 个。

如何通过删除其中一个额外的 LinearLayout 来优化这一点,但要保持创建自定义视图的简单性?

MyToolbar.kt:

class MyToolbar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) :
    LinearLayoutCompat(context, attrs, defStyleAttr) {

    private val binding = MyToolbarBinding.inflate(LayoutInflater.from(context), this, true)

    init {
         // [...] Initialization of my view ...
    }
}

my_toolbar.xml:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <!-- Actual content of my view -->

</LinearLayout>

【问题讨论】:

  • my_toolbar.xml 中使用&lt;merge&gt; 标签而不是&lt;LinearLayout&gt;

标签: android android-layout android-view


【解决方案1】:

在@Pawel 和@Cata 建议之后我现在拥有的东西。这不起作用,LinearLayout 使用父级的整个高度,但它应该只包装其内容。

MyToolbar.kt:

class MyToolbar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) :
    LinearLayoutCompat(context, attrs, defStyleAttr) {

    private val binding

    init {
        // Tried to add the attributes here as they seems ignored on the `merge` tag
        gravity = Gravity.CENTER_VERTICAL
        orientation = HORIZONTAL
        layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)

        binding = MyToolbarBinding.inflate(LayoutInflater.from(context), this)

        // [...] Initialization of the view ...
    }
}

my_toolbar.xml:

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <!-- Actual content of the view -->

</merge>

【讨论】:

    【解决方案2】:

    正如 Pawel 建议的那样,您可以使用 merge 来做到这一点。

    这是来自开发者网站的示例:

    <merge xmlns:android="http://schemas.android.com/apk/res/android">
    
        <!-- Here you can add your custom content views.. -->
        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/add"/>
    
        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/delete"/>
    
    </merge>
    

    【讨论】:

    • @Pawel 你完全跳过了LinearLayout 的属性(宽度、高度、重力和方向)。在膨胀子视图之前,我尝试以编程方式将它们添加到 init 函数中,但它不起作用。
    猜你喜欢
    • 1970-01-01
    • 2020-12-21
    • 2014-09-02
    • 2011-05-13
    • 2019-09-05
    • 1970-01-01
    • 2016-09-14
    • 2020-11-19
    • 1970-01-01
    相关资源
    最近更新 更多