【问题标题】:Apply built-in Android widget styles in a custom view在自定义视图中应用内置的 Android 小部件样式
【发布时间】:2013-06-18 09:25:00
【问题描述】:

我已阅读并理解https://stackoverflow.com/a/5052401/305532,但我想要的不是一般样式和覆盖单个小部件样式,而是子小部件一部分的样式。

比如说,我有一个复合 RelativeLayout,它由一个标准 EditText 和一个标准 Button 组成。我可以覆盖android:buttonStyle 来设置这个Button 的样式,但我真正想要的是

<my.custom.Widget
  ...
  pkg:buttonStyle="@style/CustomStyle" />

CustomStyle 可以从android:style/Widget.Button 派生,但由于pkg:buttonStyle 而对于my.custom.Widget 的每个实例都可以更改。

我知道的唯一选择是将所有可设置样式的属性单独添加到我的attrs.xml 中(如果您的两个或多个子小部件需要相同的属性但具有不同的值,通常会发生冲突),然后手动复制 /在my.custom.Widget的构造函数/init方法中设置所有这些属性。

有没有办法做到这一点?

【问题讨论】:

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


    【解决方案1】:

    不幸的是,这似乎是不可能的。我能找到的唯一一个类似的例子是ActionBar:你可以传入标题、副标题和进度指示器的样式。查看ActionBarView的来源,标题和副标题TextViews'的样式应用setTextAppearance()ProgressBar class 有一个额外的构造函数,它接受样式的第四个参数。由于大多数View 类没有这个额外的构造函数,因此不可能将样式传递给它们。但是,有几种选择:

    1. 传递子视图的布局而不是样式,并在您的小部件中对其进行扩展。
    2. 如果子视图是TextView 的子视图(就像ButtonEditText 一样),则使用setTextAppearance() 作为传递的样式。这将为文本应用大量样式。如果您想允许用户应用其他样式,例如背景或填充,您仍然需要为每个样式添加自定义属性。如果您正在制作复合小部件,那么用户很有可能不需要将所有可能的样式应用于子视图,因此只公开一个子集可能就足够了。
    3. 添加主题范围的样式,正如您已经提到的。

    【讨论】:

      【解决方案2】:

      在自定义视图中使用内置小部件样式

      如果您创建一个作为 Android 小部件子类的自定义视图并希望使用内置的 Android 小部件样式对其进行样式设置,则必须实现以下结构。


      更改您的自定义 View 以从 Android Widget 样式继承其属性

      CustomTextView.java

      public class CustomTextView extends TextView {
          public CustomTextView(Context context, AttributeSet attrs) {
              super(context, attrs);
              TypedArray styledAttrs = context.obtainStyledAttributes(attrs,
                      R.styleable.CustomTextView, R.attr.customImageButtonStyle, 0);
              String fontName = styledAttrs.getString(
                      R.styleable.CustomTextView_customTypeface);
              styledAttrs.recycle();
      
              // Use custom attribute to do something...
          }
      }
      

      Context#obtainStyledAttributes()defStyleAttr 参数用于指定对要继承的样式的引用。在此示例中,您使用 R.attr.customImageButtonStyle。您在themes.xmlstyles.xml 中定义这些资源。

      themes.xml

      <resources>
          <style name="AppTheme">
              <!--Define a theme-wide customTextViewStyle -->
              <item name="customTextViewStyle">@style/Widget.TextView</item>
          </style>
      </resources>
      

      styles.xml

      <resources>
          <style name="Widget.TextView"
              parent="@android:style/Widget.TextView">
              <item name="customTypeface">custom_font_typeface</item>
          </style>
      </resources>
      

      attrs.xml

      <resources>
          <declare-styleable name="CustomTextView">
              <attr name="customTypeface" format="string" />
          </declare-styleable>
          <declare-styleable name="CustomTheme">
              <attr name="customTextViewStyle" format="reference"/>
          </declare-styleable>
      </resources>
      

      *activity_layout*

      <com.packagename.ui.view.CustomTextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="Bacon ipsum" />
      

      CustomTextView 不再需要您定义样式或customTypeface 属性,它已经在themes.xml 中的主题范围customTextViewStyle 中定义。

      【讨论】:

      • 这如何回答我的问题?我特意问了如何处理compound小部件...
      • 无论组件数量如何,这都将起作用。只需在所有复合视图中重新使用 CustomTheme 属性即可。每个视图都可以使用引用样式中定义的所有属性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-12
      • 2014-02-23
      • 1970-01-01
      • 2011-11-08
      相关资源
      最近更新 更多