[번역] EditText 색 변경항목 정리

[번역] EditText 색 변경항목 정리

Oct 31, 2016. | By: pluulove

본 포스팅은 EditTextの色変更箇所まとめ 을 기본으로 번역하여 작성했습니다

제 일본어 실력으로 인하여 오역이나 오타가 발생할 수 있습니다.

EditText의 밑줄이나 커서 색상 등, 어떻게 지정해야 하는가 매번 잊어버리니 메모해둡니다.

정리

변경항목 지정항목 설명
colorControlActivated 손끝으로 터치되어 있는 부분. text selection handle라고 부른다고 한다
colorControlNormal 포커스 되어있지 않은 경우의 밑줄 부분
colorControlActivated 포커스시의 밑줄 부분. Tint 되어있어 지정한 색보다 약간 투명이 적용되어있고, 길게 누르면 지정한 색이된다.
android:textColorHighlight 텍스트 선택색
android:textColorHint 입력전의 Hint (포커스 Holder)
android:textColor 텍스트 색
android:textCursorDrawable 커서 색. drawable 지정되지만, 색을 설정하는것도 된다

코드

레이아웃 xml의 EditText는 이런 모습입니다. AppCompatEditText를 사용하고 있지만, EditText라도 같습니다.

styleapp:theme 둘 다 지정하는 것은, style만으로는 colorControlNormalcolorControlActivated의 적용이 되지않기때문입니다.

이 부근은 내부 코드를 읽어보지 않았지만, Activity나 Application으로 지정한 테마의 스타일이 적용됩니다.

// activity_main.xml
<android.support.v7.widget.AppCompatEditText
    android:id="@+id/edit_text"
    style="@style/EditTextStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="ヒント"
    app:theme="@style/EditTextStyle" />

style.xml은 이런 모습입니다. 덧붙여서 android:~의 attributes는 style이 아니고 직접 레이아웃에 지정해도 적용되지만, colorControl~의 attributes는 적용되지 않습니다.

// styles.xml
<style name="EditTextStyle" parent="Widget.AppCompat.EditText">
    <item name="colorControlNormal">@color/amber500</item>
    <item name="colorControlActivated">@color/pink500</item>
    <item name="android:textCursorDrawable">@color/indigo500</item>
    <item name="android:textColor">@color/orange500</item>
    <item name="android:textColorHint">@color/teal500</item>
    <item name="android:textColorHighlight">@color/purple500</item>
</style>

색상을 알기 쉽도록 style.xml를 캡쳐해서 붙입니다.

EditText 코드를 읽고 style이나 theme가 어떻게 적용되는가를 찾으면 좀 더 자세하게 알 수 있지만, 우선 이걸로 대부분 색은 변경 가능합니다.


댓글 이야기

alzybaad : http://qiita.com/alzybaad

  • 이해하기 쉽게 되어있네요
  • colorControl〜 부분은 EditText의 backgroundDrawable로 사용되어, API Level 21 이상에서는 아래의 XML입니다.
// edit_text_material.xml
<inset xmlns:android="http://schemas.android.com/apk/res/android"
  android:inset="@dimen/control_inset_material">
  <ripple android:color="?attr/colorControlActivated">
    <item>
      <selector>
        <item android:state_enabled="false">
          <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
            android:tint="?attr/colorControlNormal"
            android:alpha="?attr/disabledAlpha" />
        </item>
        <item>
          <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
            android:tint="?attr/colorControlNormal" />
        </item>
      </selector>
    </item>
    <item android:id="@+id/mask" android:drawable="@drawable/textfield_activated_mtrl_alpha" />
  </ripple>
</inset>

View의 backgroundDrawable를 로드시에는 그 Viewstyle이 사용되는 것이 아니라, Activity 등의 테마가 적용되어있어, app:theme를 지정하지 않으면 적용되지 않습니다.

// TypedArray#getDrawable
@Nullable
public Drawable getDrawable(int index) {
  if (mRecycled) {
    throw new RuntimeException("Cannot make calls to a recycled instance!");
  }

  final TypedValue value = mValue;
  if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
    if (value.type == TypedValue.TYPE_ATTRIBUTE) {
      throw new UnsupportedOperationException(
          "Failed to resolve attribute at index " + index + ": " + value);
    }
    return mResources.loadDrawable(value, value.resourceId, mTheme);
  }
  return null;
}

app:theme을 지정해야 적용되는 것은 AppCompatViewInflater에서, 그 테마를 적용한 ContextView의 생성자에 지정되기 때문이지요.

// AppCompatViewInflater
public final View createView(View parent, final String name, @NonNull Context context,
    @NonNull AttributeSet attrs, boolean inheritContext,
    boolean readAndroidTheme, boolean readAppTheme) {
  ...
  if (readAndroidTheme || readAppTheme) {
    // We then apply the theme on the context, if specified
    context = themifyContext(context, attrs, readAndroidTheme, readAppTheme);
  }
  ...
    view = new AppCompatEditText(context, attrs);
  ...
}

private static Context themifyContext(Context context, AttributeSet attrs,
    boolean useAndroidTheme, boolean useAppTheme) {
  final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.View, 0, 0);
  int themeId = 0;
  if (useAndroidTheme) {
    // First try reading android:theme if enabled
    themeId = a.getResourceId(R.styleable.View_android_theme, 0);
  }
  if (useAppTheme && themeId == 0) {
    // ...if that didn't work, try reading app:theme (for legacy reasons) if enabled
    themeId = a.getResourceId(R.styleable.View_theme, 0);

    if (themeId != 0) {
      Log.i(LOG_TAG, "app:theme is now deprecated. "
          + "Please move to using android:theme instead.");
    }
  }
  a.recycle();

  if (themeId != 0 && (!(context instanceof ContextThemeWrapper)
      || ((ContextThemeWrapper) context).getThemeResId() != themeId)) {
    // If the context isn't a ContextThemeWrapper, or it is but does not have
    // the same theme as we need, wrap it in a new wrapper
    context = new ContextThemeWrapper(context, themeId);
  }
  return context;
}

comments powered by Disqus

Currnte Pages Tags

Android

About

Pluu, Android Developer Blog Site

이전 블로그 링크 :네이버 블로그

Using Theme : SOLID SOLID Github

Social Links