7

我正在尝试用应该完全相同的自定义复合视图替换一组视图。具体来说,我经常重复以下布局:

<LinearLayout style="@style/customLayoutStyle">
  <Button style="@style/customButtonStyle" />
  <TextView style="@style/customTextViewStyle" />
</LinearLayout>

我的目标是用一个<Highlighter />.

为此,我在 res/layout/highlighter.xml 中定义了类似

<merge xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/customLayoutStyle">
    <Button android:id="@+id/btnHighlighter" style="@style/customButtonStyle" />
    <TextView android:id="@+id/lblHighlighter" style="@style/customTextViewStyle" />    
</merge>

在我的自定义视图中,我有类似的东西

public class Highlighter extends LinearLayout {
    public Highlighter(Context context, AttributeSet attrs) {
        super(context, attrs);
        inflate(context, R.layout.highlighter, this);
    }
}

这主要是有效的,但似乎<merge>标签的一些布局参数被忽略了。此屏幕截图说明了似乎有问题的地方。底行的 3 个图像正确对齐,使用 3 倍我尝试替换的 LinearLayout 块。只有左上角的图像使用自定义视图。我的猜测是 padding 和 layout_weight 的布局参数丢失了。我做错了什么,还是需要解决方法?

4

3 回答 3

5

您对丢失的参数是正确的。要解决此问题,您可以将 Highlighter 的样式定义放在定义 Highlighter 的布局中。

例如

<yournamespace.Highlighter 
    style="@style/customLayoutStyle"
/>
于 2013-02-10T17:32:47.683 回答
2

多年后,这在 Android 上仍然很复杂,但可以做到。

您可以在自定义视图中使用样式属性,然后在主题中设置样式。

不要将样式设置为res/layout/highlighter.xml

<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <Button android:id="@+id/btnHighlighter" style="@style/customButtonStyle" />
    <TextView android:id="@+id/lblHighlighter" style="@style/customTextViewStyle" />    
</merge>

然后在您的自定义视图中:

public class Highlighter extends LinearLayout {
    public Highlighter(Context context, AttributeSet attrs) {
        // The third constructor parameter is you friend
        super(context, attrs, R.attr.highlighterStyle);
        inflate(context, R.layout.highlighter, this);
    }
}

在 中定义属性values/attrs_highlighter_view.xml

<resources>
    <attr name="highlighterStyle" format="reference" />
</resources>

现在您可以在主题中设置样式

<style name="YourAppTheme" parent="Theme.AppCompat">
    <item name="preferenceViewStyle">@style/customLayoutStyle</item>
</style>

这样,每当您使用Highlighter.

然后,您的自定义视图的使用就像您想要的那样:

<com.your.app.Highlighter
    android:id="@+id/highlighter"
    ... />

我还没有验证这是否适用于layout_weight,但它确实适用于paddingbackground

于 2020-04-08T14:33:42.933 回答
0

详细说明muscardinus 的答案,从 API 21 (Lollipop) 开始,View接受 adefStyleRes作为第四个构造函数参数,因此您可以跳过该attr部分并执行以下操作:

在styles.xml

<style name="CustomView">
    // Define your style here
</style>

自定义视图.kt

class CustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
) : LinearLayout(context, attrs, defStyleAttr, R.style.CustomView) {

    ...

}

请注意,您至少需要这样做minSdkVersion 21

于 2021-04-20T14:34:54.107 回答