Android Custom EditText设置自定义默认样式(如果未提供)

时间:2020-09-15 10:34:16

标签: android

我创建了一个自定义视图(将作为库提供),如果用户在其项目中使用该视图时未提供默认样式,则希望该视图使用默认样式。

class SuggestionTextView
@JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = androidx.appcompat.R.attr.editTextStyle
) : AppCompatEditText(context, attrs, defStyleAttr) 

此样式位于我的模块中,如果开发人员未提供其自己的样式,我想使用它:

 <style name="Widget.AppCompat.SuggestionTextView" parent="Widget.AppCompat.EditText">
        <item name="imageTintColor">@color/myBlue</item>
        <item name="android:textColor">@color/myBlue</item>
        <item name="android:textColorHint">@color/myLightGray</item>
        <item name="android:background">@drawable/bg_white_border_gray</item>
        <item name="android:textAppearance">@style/SuggestionTextViewTextAppearance</item>
    </style>

    <style name="SuggestionTextViewTextAppearance" parent="TextAppearance.AppCompat">
        <item name="android:textSize">20sp</item>
        <item name="android:fontFamily">sans-serif-light</item>
    </style>

如果用户在使用我的视图时提供了自己的视图,我想改用该视图,即:

<com.mypackage.suggestionscomponent.SuggestionTextView
            android:id="@+id/suggestionTextView"
            style="@style/Widget.AppCompat.UserCustomSuggestionTextView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textHeader" />

谢谢

1 个答案:

答案 0 :(得分:0)

为此找到了解决方案(Google确实很难做到)。

  1. 在attrs.xml上为您的自定义视图(仅用于自定义属性)创建可声明样式:
<declare-styleable name="SuggestionTextView">
    <attr name="nResults" format="integer" />
    <attr name="language" format="string" />
    <attr name="imageTintColor" format="color" />
</declare-styleable>
  1. 同样在attrs.xml上为您的主题创建一个attr
<declare-styleable name="CustomTheme">
    <attr name="customSuggestionTextViewStyle" format="reference"/>
</declare-styleable>
  1. 在styles.xml (步骤1中的自定义属性没有android:xx,即imageTintColor)上创建默认样式
<style name="Widget.AppCompat.SuggestionTextView" parent="Widget.AppCompat.EditText">
    <item name="imageTintColor">@color/myRed</item>
    <item name="android:textColor">@color/myBlue</item>
    <item name="android:background">@drawable/bg_white_border_gray</item>
    <item name="android:textColorHint">@color/myLightGray</item>
    <item name="android:textAppearance">@style/SuggestionTextViewTextAppearance</item>
</style>

<style name="SuggestionTextViewTextAppearance" parent="TextAppearance.AppCompat">
   <item name="android:textSize">33sp</item>
   <item name="android:fontFamily">sans-serif-light</item>
</style>
  1. 在themes.xml上创建您的主题,并将attr customSuggestionTextViewStyle设置为在步骤3中创建的样式。
<style name="SuggestionTextViewTheme" parent="@android:style/Theme">
    <item name="customSuggestionTextViewStyle">@style/Widget.AppCompat.SuggestionTextView</item>
</style>
  1. 使用ContextThemeWrapper设置自定义视图构造函数,并在超级调用上将主题设置为4.,在第二步将defStyleAttr作为我们的自定义属性,在init上加载自定义属性,记住要调用recycle()。
class SuggestionTextView
@JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = R.attr.customSuggestionTextViewStyle
) : AppCompatEditText(ContextThemeWrapper(context, R.style.SuggestionTextViewTheme), attrs, defStyleAttr) {

init {
        context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.SuggestionTextView,
            defStyleAttr, R.style.SuggestionTextViewTheme
        ).apply {
            try {
                nResults = getInteger(R.styleable.SuggestionTextView_nResults, 3)
                language = getString(R.styleable.SuggestionTextView_language) ?: "en"
                imageTintColor = getColor(
                    R.styleable.SuggestionTextView_imageTintColor,
                    ContextCompat.getColor(context, R.color.myRed)
                )
            } finally {
                recycle()
            }
        }
}
  1. 使用在步骤3中创建的自定义样式,在活动中使用自定义控件。
<com.mypackage.suggestionscomponent.SuggestionTextView
    android:id="@+id/suggestionTextView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
  1. 创建另一种样式来覆盖默认样式(如果需要)
  2. 应用新样式:
<com.mypackage.suggestionscomponent.SuggestionTextView
     style="@style/Widget.AppCompat.DifferentSuggestionTextView"
     android:id="@+id/suggestionTextView"
     android:layout_width="match_parent"
     android:layout_height="wrap_content" />

就这样:)