마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

TextInputEditText는 theme에서 사용할 수 없나요?

0 추천
여러개의 TextInputEditText에 공통으로 적용할 style을 만드려고하는데요,

일반적으로 <style name="" parent="상속받을 스타일"></style>이런식으로 할텐데..

여기 parent 상속받을 스타일에 TextInputLayout은 있는데 TextInputEditText는 없네요,

그래서 지금 TextInputEditText에 font 라던지 등등 정의를 못하고 있는데 기본 EditText로 상속을 받아서 style을 커스텀해야하나요?
codeslave (3,940 포인트) 님이 2022년 1월 8일 질문

1개의 답변

0 추천
아래 사이트에 보시면 어떻게 스타일링을 하는지 아실 수 있습니다.

https://material.io/components/text-fields/android#using-text-fields
spark (224,800 포인트) 님이 2022년 1월 8일 답변
앱 내의 모든 textfield 에 일괄적으로 같은 스타일을 적용할 때 제일 효과적인 방법은 them에 다음과 같이 설정하는 겁니다.

<style name="Theme.App" parent="Theme.MaterialComponents.*">
    ...
    <item name="textInputStyle">@style/Widget.App.TextInputLayout</item>
</style>

<style name="Widget.App.TextInputLayout" parent="Widget.MaterialComponents.TextInputLayout.*">
    <item name="materialThemeOverlay">@style/ThemeOverlay.App.TextInputLayout</item>
    <item name="shapeAppearance">@style/ShapeAppearance.App.SmallComponent</item>
    <item name="hintTextColor">?attr/colorOnSurface</item>
</style>

<style name="ThemeOverlay.App.TextInputLayout" parent="">
    <item name="colorPrimary">@color/shrine_pink_100</item>
    <item name="colorOnSurface">@color/shrine_pink_900</item>
    <item name="colorError">@color/shrine_red</item>
    <item name="textAppearanceSubtitle1">@style/TextAppearance.App.Subtitle1</item>
    <item name="textAppearanceCaption">@style/TextAppearance.App.Caption</item>
    <item name="editTextStyle">@style/Widget.MaterialComponents.TextInputEditText.*</item>
</style>

이 내용도 위의 링크에 나옵니다.

https://github.com/material-components/material-components-android/blob/master/docs/getting-started.md

https://github.com/material-components/material-components-android-examples

위의 링크도 도움이 되실 거예요.
감사합니다 그런데 저도 처음에 제일 먼저 찾아 본곳이 머티리얼디자인 문서였는데요,
해당 코드도 해보았지만 안돼서 여쭈어보는거였습니다ㅠ
parent="Widget.MaterialComponents.TextInputLayout.*" 이 코드가 아예 안되던데요..ㅜ
Material component를 사용하신다면 해당 문서대로 하시면 됩니다. 저도 프로젝트에 해당 문서를 보고 적용해서 사용하고 있어요.
앱 디펜던시에

implementation "com.google.android.material:material:1.x.x"

이렇게 추가되어 있어야 하구요. 제 스타일을 공유해 드리면 아래와 같습니다.

theme의 속성에
<item name="textInputStyle">@style/MyTextInputLayout.OutlinedBox.Dense</item>

 <style name="MyTextInputLayout.OutlinedBox.Dense" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense">
        <item name="android:layout_height">@dimen/edit_height</item>
        <item name="android:colorControlActivated">@color/lightBlue</item>
        <item name="android:colorControlNormal">@color/gey40</item>
        <item name="colorControlNormal">@color/grey40</item>
        <item name="boxBackgroundColor">@color/grey40</item>
        <item name="hintEnabled">false</item>
        <item name="boxStrokeColor">@color/lightBlue</item>
        <item name="boxStrokeErrorColor">@color/orange</item>
        <item name="hintTextColor">@color/inkTint40</item>
    </style>

그리고 추가적인 속성은 materail.io에 나온 것들을 참조하시면서 추가하시면 됩니다.

도움이 되셨으면 좋겠네요.
선생님 감사합니다 많은도움 되었습니다. 질문 몇가지 드리겠습니다.

1. 개발자문서에서 보길 <style name=""> 에서 스타일을 고유하기 식별하는 이름을 사용하여 style을 요소를 정의한다고 되어있는데요,
<style name="Widget.App.TextInputLayout" > 이라던지 <style name="ThemeOverlay.App.TextInputLayout" parent=""> 에서

Widget.App.TextInputLayout 과 ThemeOverlay.App.TextInputLayout 는
Widget과 ThemeOveraly 라이브러리를 그대로 사용하는건가요 아니면 정말 이러한 이름을 정의하는건가요?

style 이름을 Widget.App.~~와 ThemeOverlay.~~ 이렇게 정의해놓으니까 헷갈리네요..
실제로 제 안드로이드버전 기준 코드상에서는 Widget.App이 아니라
Widget.AppCompat이라고 뜨고 ThemeOverlay도 마찬가지입니다.
Widget.App은 안뜨고 AppCompat이라고 뜨니까 Widget.App이라는 라이브러리가 실제로 존재하는것인지 아니면 Widget.App.TextInputLayout을 진짜 고유한 이름으로 지은건지 잘모르겠어요..
선생님이 MyTextInputLayout.OutlinedBox.Dense 을 하신것처럼 이건 진짜 고유한 이름이잖아요?  MyTextInputLayout이라는 라이브러리가 존재하는것이 아니라 그냥 고유한 이름으로 점(.)을 이용해서 확장의 이름으로 네이밍을 하신거구요
Widget.App.TextInputLayout나 ThemeOverlay.App.~~도 진짜 라이브러리가 아니라 선생님처럼 그냥 단순 확장하는 네이밍인지 궁금해요.

2. 선생님처럼 TextInputLayout을 정의한 후에 적용은 성공했습니다만 궁금한것이 font는 적용이 안되더라구요, font는 TextInputEditText에 직접 폰트를 설정하거나 스타일을 만든후에 스타일을 지정해야하나요?
(Theme 레벨에 전체적으로 폰트를 설정해서 모든 뷰의 폰트를 일괄적으로 변경은 시켰으나 그냥 궁금한점입니다.)

3.2번이랑 유사한 질문일수도있는데 TextInputEditText 에만 적용돼야하는 것들(maxLine 같은것들)은 스타일로 어떻게 정의시켜야할까요..? 정확하게는 parent로 무엇을 상속받아야하는지입니다..예를들어 Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense을 상속받아 스타일을 정의하고 theme 아이템 textInputStyle에  maxLine을 정의시켜도 적용이 안됩니다..

+) 4. 선생님 그리고 layout_height를 style에서 설정하시고 Theme 속성에 적용하셨는데 이거 에러안나시던가요? style을 만들고 TextinputLayout에 style을 적용하면 안나지만 Theme만 적용시키면 아예 에러가나버리는데 TextInputLayout에 style까지 적용하신건가요
1. Widget.App이나 ThemeOverlay.App 으로 시작하는 것은 해당 앱에서만 사용하는 스타일입니다. material 은 MatrialComponent나 AppCompat 이런 접두어가 붙어 있어서 쉽게 구분이 갑니다. ThemeOverlay는 보통의 스타일과는 약간 다른 특별한 녀석이라 ThemeOverlay로 시작하는 것이구요.

2. typography와 관련된 속성도 material.io에 다 나옵니다.

참고로 제 프로젝트는 theme만이 9가지나 되서 엄청나게 theme이 복잡해요. 실시간에 변경도 가능하구요. 디자인해준 사람이 모바일에 대해서는 전혀 몰라서, 저도 결국은 이 문서를 보고 이것저것 해보고 디자인을 맞춥니다.
typography는 textAppearance 속성을 통해 설정을 합니다. 개별 검포넌트마다 지원되는 속성입니다.

아래의 두가지 속성이 보통 많이 사용하는 EditText의 textAppearance이네요.
 app:hintTextAppearance
 android:textAppearan

3. ThemeOverlay를 한번 살펴 보세요.

4. 에러 안납니다. 원래는 사이즈를 스타일에 넣는 건 권장사항은 아닌데, 디자인이 약간 요상한 요구사항들이 많아서 사용하게 됐어요. 스타일에 적용하는 거랑 theme에 적용하는 거랑 왜 다른지 모르겠네요. 공유해드린 스타일은 저희 희사에서 사용거라, 필요없으시면 layout_height는 지우세요. 기본값이 더 좋습니다. layout_height를 적용하시면 추가로 작업이 더 필요해집니다.

Material.io에 보시면 어떤 값이 기본값인지 같이 나옵니다. 즉 theme에서 기본값을 오버라이드 하면 개별 컴포넌트에서 해당 속성을 지정하지 않아도 전체적으로 반영된다는 말입니다.

Material theme은 많이 복잡해요. 기본 스타일을 사용하지 않는 한 손이 많이 갈 수 밖에 없고 결국은 문서나 구글 샘플같은 것에 의존할 수 밖에 없어요.
한가지 중요한 점이 있습니다.
<style name="Widget.App.TextInputLayout" parent="Widget.MaterialComponents.TextInputLayout.*">

<style name="Widget.App.TextInputLayout">

위의 둘은 어떤 부모 컴포넌트를 사용하는가에 대한 점에서 많이 다릅니다. 첫번째 처럼 parent가 지정되면 parent를 상속받게 되고 두번째같이 parent가 없을 경우는 style에 있는 이름은 OOP의 상속처럼 동작합니다. 즉,
Widget.App.TextInputLayout은 Widget.App를 상속 받습니다.
감사합니다. 부모를 설정안하면 상속을 안받는것이 아니라 Widget.App을 상속받는군요. 이게 자바나 kotlin에서 클래스가 아무것도 상속을 받지않아도 Object나 Any타입(맞나?)를 상속받는거랑 똑같다고 보면될까요?

그리고 width와 height가 어차피 값이 똑같아 코드도줄인다고 그랬는데 그냥 스타일에 적용하고 Theme에 적용했는데 이건 안되고 TextInputLayout style에 적용을 하면 되네요..

이건되고 저건안되고 이런게 많고 폰트 문제도 아직 안되고 생각보다 Theme이 좀 많이 어렵네요..
theme 상속은 클래스 상속과는 좀 다른 형태로 보는게 맞습니다.
그리고 강제로  텍스트필드의 높이를 기본값보다 작게 설정하면 에디티 텍스트에 패딩을 주지 않으면 텍스트의 위아래가 살짝 잘려 나올 수 있으니 주의하세요. 특별한 요구사항이 없다면 기본 높이를 그대로 사용하는 것이 제일 좋습니다.
...