【问题标题】:Custom view style, android's attributes are ignored自定义视图样式,android的属性被忽略
【发布时间】:2014-06-12 10:43:09
【问题描述】:

我创建了一个自定义复合视图 - 视图加载,没有崩溃,到目前为止一切顺利。

现在,我计划在我的应用程序中多次使用这个视图,所以这个视图需要一个样式。

我在 attr.xml 文件中为它声明了一个样式

  <declare-styleable name="MyCustomView">

        <attr name="ff_label" format="string" />
        <attr name="ff_fieldText" format="string" />
    </declare-styleable>
    
    <declare-styleable name="MyCustomViewStyle">
        <attr name="customViewStyle" format="reference" />
    </declare-styleable>

然后我去我的主题文件里面写了这个

<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">

    <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    //bunch of other stuff
    <item name="customViewStyle">@style/customViewStyle</item>
</style>

然后在我的android清单中我声明了

<application
        android:name="com.my.app.App"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

然后在我的 styles.xml 文件中我写了

   <style name="customViewStyleStyle" parent="@android:style/Widget.EditText">
        <item name="android:paddingBottom">@dimen/space_between_adjacent_widgets_vertical</item>
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="ff_label">@string/default_label_text</item>
        <item name="ff_fieldText">@string/default_label_text</item>
    </style>

我的问题:我的 OWN 属性被识别得很好。
为什么标记为"android:..." 的属性会被忽略?

MyCustomView.java

public MyCustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initAttributes(context, attrs, R.attr.customViewStyle);
}

public MyCustomView(Context context) {
    super(context);
    initAttributes(context, null, R.attr.customViewStyle);
}

private void initAttributes(Context context, AttributeSet attrs, int defStyle) {
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.custom_view, this, true);
    label = (TextView) findViewById(R.id.label);
    formField = (EditText) findViewById(R.id.formField);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyle,0);

    if (a.hasValue(R.styleable.MyCustomView_ff_label)) {
        labelText = a.getString(R.styleable.MyCustomView_ff_label);
        label.setText(labelText);
    }

    
    if (a.hasValue(R.styleable.MyCustomView_ff_fieldText)) {
        fieldText = a.getString(R.styleable.MyCustomView_ff_fieldText);
        field.setHint(fieldText);
    }
    
    
    a.recycle();
}

layout.xml

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.my.app"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

   <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <include layout="@layout/layout_set_default" />

</TableLayout>

1 视图的默认高度约为 30 dp - > 我不能为它使用列表视图。 每个视图之间应该有 10dp 的填充

【问题讨论】:

标签: android android-custom-view android-styles


【解决方案1】:

您必须像这里一样更改MyCustomView 的代码:

    ...
    public MyCustomView(Context context, AttributeSet attrs) {
            //Called by Android if <com.my.app.MyCustomView/> is in layout xml file without style attribute.
            //So we need to call MyCustomView(Context context, AttributeSet attrs, int defStyle) 
            // with R.attr.customViewStyle. Thus R.attr.customViewStyle is default style for MyCustomView.
            this(context, attrs, R.attr.customViewStyle);
    }

    public MyCustomView(Context context) {
            this(context, null);
    }

    public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
            //Called by Android if <com.my.app.MyCustomView/> is in layout xml with style attribute
            // For example:
            //         <com.my.app.MyCustomView
            //                android:layout_width="match_parent"
            //                android:layout_height="wrap_content"
            //                style="@style/customViewStyleStyle"
            //                />
            //
            super(context, attrs, defStyle);
            initAttributes(context, attrs, defStyle);
    }
    ...

然后您可以在layout.xml 中使用样式属性,customViewStyle 也将是MyCustomView 的默认样式。与textViewStyle 相同的是TextView 的默认样式

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/customViewStyleStyle"
      />

之前你有构造函数:

public MyCustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initAttributes(context, attrs, R.attr.customViewStyle);
}

如您所见,您将 R.attr.customViewStyle 传递给 initAttributes() 方法,但不将其传递给父构造函数。

【讨论】:

  • 我添加了一个主题,我写道,我将主题添加到我编写的应用程序中,“我自己的”属性被识别。被忽略的是“android:bottomPadding”为什么?
  • 这篇文章一步一步地展示了我是如何添加它们的——主题是有效的。只是如果我输入自定义样式的“普通”android 属性,它们就会被忽略......
  • 您的帖子信息量很大,但是您能添加您的布局 xml 和活动代码吗?
  • 我的意思是你使用 MyCustomView 的那部分。我认为问题就在那里。因为我已经使用您的资源从头开始制作应用程序,并且填充效果很好。但可以肯定的是,我使用了自己的 activity.xml 和 Activity 类。
  • 查看我编辑的答案。您的自定义属性是从自定义样式中获取的,因为 MyCustomView 具有 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyle,0);但默认充气机不知道您不想将 customViewStyleStyle 应用于 com.my.app.MyCustomView
猜你喜欢
  • 1970-01-01
  • 2017-04-05
  • 2012-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多