뷰에서 프로그래밍 방식으로 스타일 속성을 설정하는 방법


107

아래 코드를 사용하여 XML에서보기를 얻습니다.

Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);

내가 사용할 각 버튼에 여러 스타일을 사용하기를 원하기 때문에 자바에서 어떻게 할 수있는 버튼에 대한 "스타일"을 설정하고 싶습니다.

답변:


52

일반적으로 프로그래밍 방식으로 스타일을 변경할 수 없습니다. 테마 또는 스타일을 사용하여 XML 레이아웃의 화면 또는 레이아웃의 일부 또는 개별 버튼의 모양을 설정할 수 있습니다 . 그러나 테마는 프로그래밍 방식으로 적용 할 수 있습니다 .

또한 포커스, 선택, 눌림, 비활성화 등의 StateListDrawable각 상태에 대해 다른 드로어 블을 정의 할 수 있는 것과 같은 것이 Button있습니다.

예를 들어 버튼을 눌렀을 때 색상이 변경되도록하려면 다음 res/drawable/my_button.xml과 같이 directory 라는 XML 파일을 정의 할 수 있습니다 .

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item
    android:state_pressed="true"
    android:drawable="@drawable/btn_pressed" />
  <item
    android:state_pressed="false"
    android:drawable="@drawable/btn_normal" />
</selector>

그런 다음 Button속성을 설정 하여이 선택기를에 적용 할 수 있습니다 android:background="@drawable/my_button".


4
내 문제는 내 버튼 정보를 설명하는 웹 서비스에서 데이터를로드한다는 것입니다. 버튼은 속한 카테고리에 따라 다른 스타일을 가져야합니다. 그래서 동적으로 스타일을 설정하고 싶습니다.
Lint_ 2010 년

3
Android style속성을 변경할 수는 없지만 Button, 충분하다면 다른 뷰에서 할 수 있는 것과 유사한 배경을 프로그래밍 방식으로 설정할 수 있습니다. 또한에서 Button상속 되므로 TextView텍스트 속성을 변경할 수 있습니다. 다음 항목에 대한 API 문서를 참조하십시오. developer.android.com/reference/android/view/…
Christopher Orr

나는 새로운 답변이 있는지 확인하기 직전에 그렇게 할 생각이었습니다. 감사합니다.
Lint_ 2010 년

5
텍스트 크기, 여백 등을 정의하는 버튼 스타일을 만든 다음 프로그래밍 방식으로 버튼에 적용 할 수 없습니까? 같은 스타일을 원하는 6 개의 버튼이 있다면 확실히 가능할까요?
2012 년

우리가 부 풀릴 수있는 속성은 무엇입니까? 여백, 패딩을 부 풀릴 수 있습니까?
Android Man

49

우선, 간단한 Button을 만들기 위해 레이아웃 인플레이터를 사용할 필요가 없습니다. 다음을 사용할 수 있습니다.

button = new Button(context);

버튼의 스타일을 지정하려면 두 가지 선택이 있습니다. 가장 간단한 방법은 다른 많은 답변이 제안하는 것처럼 코드의 모든 요소를 ​​지정하는 것입니다.

button.setTextColor(Color.RED);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);

다른 옵션은 XML로 스타일을 정의하고 단추에 적용하는 것입니다. 일반적인 경우에는 다음과 같이 사용할 수 있습니다 ContextThemeWrapper.

ContextThemeWrapper newContext = new ContextThemeWrapper(baseContext, R.style.MyStyle);
button = new Button(newContext);

TextView (또는 Button과 같은 하위 클래스)의 텍스트 관련 속성을 변경하려면 다음과 같은 특별한 방법이 있습니다.

button.setTextAppearance(context, R.style.MyTextStyle);

이 마지막 속성은 모든 속성을 변경하는 데 사용할 수 없습니다. 예를 들어 패딩을 변경하려면 ContextThemeWrapper. 그러나 텍스트 색상, 크기 등의 경우 setTextAppearance.


1
훌륭합니다. ContextThemeWrapper-내가 오랫동안 찾고 있던 것입니다.
Ayaz Alifov 16.

이것은 환상적으로 작동합니다. 이 솔루션을 잠시 찾고있었습니다.
jasonjwwilliams

14

예, 예를 들어 버튼에 사용할 수 있습니다.

Button b = new Button(this);
b.setBackgroundResource(R.drawable.selector_test);

5
그러면 배경이 설정되지만 스타일은 배경 이상을 지정할 수 있습니다. 많은 뷰 (버튼 포함)에는 스타일 ID를 매개 변수로 사용하는 생성자가있는 것 같습니다. 그러나 나는 그것을 작동시키는 데 문제가 있습니다. 버튼은 테두리 또는 아무것도없는 텍스트로 표시됩니다. 대신에 할 수있는 것은 버튼 만있는 레이아웃을 만들고 (스타일이 지정된) 레이아웃을 확장 한 다음 버튼 텍스트와 기타 항목을 설정하는 것입니다.
spaaarky21

11

다음과 같이 스타일 속성을 수행 할 수 있습니다.

Button myButton = new Button(this, null,android.R.attr.buttonBarButtonStyle);

대신에:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btn"
    style="?android:attr/buttonBarButtonStyle"

    />

7
버튼을 고려한 좋은 답변이 만들어 질 것입니다. 기존 버튼에 대해 수행하는 방법을 보는 것이 좋을 것입니다.
Quality Catalyst

cesards의 답변을 참조하십시오.
Kristy Welsh

10

지원 라이브러리를 사용하는 경우 간단히 사용할 수 있습니다.

TextViewCompat.setTextAppearance(textView, R.style.AppTheme_TextStyle_ButtonDefault_Whatever);

TextViews 및 Buttons. 나머지 뷰에도 비슷한 클래스가 있습니다. :-)


이 스타일을 얻으려면 어떤 R 패키지를 사용해야합니까?
htafoya

6

Material 답변을 찾고있는 사람은이 SO 게시물을 참조하십시오 : Material Design 및 AppCompat을 사용하는 Android의 Coloring Buttons

이 답변의 조합을 사용하여 버튼의 기본 텍스트 색상을 흰색으로 설정했습니다. https://stackoverflow.com/a/32238489/3075340

그런 다음이 답변 https://stackoverflow.com/a/34355919/3075340 프로그래밍 방식으로 배경색을 설정합니다. 그 코드는 다음과 같습니다.

ViewCompat.setBackgroundTintList(your_colored_button,
 ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));

your_colored_buttonButton원하는 경우 일반 또는 AppCompat 버튼 일 수 있습니다. 위의 코드를 두 가지 유형의 버튼으로 테스트했으며 작동합니다.

편집 : 사전 롤리팝 장치가 위의 코드에서 작동하지 않음을 발견했습니다. 사전 롤리팝 장치에 대한 지원을 추가하는 방법에 대한이 게시물을 참조하십시오. https://stackoverflow.com/a/30277424/3075340

기본적으로 다음을 수행하십시오.

Button b = (Button) findViewById(R.id.button);
ColorStateList c = ContextCompat.getColorStateList(mContext, R.color.your_custom_color;
Drawable d = b.getBackground();
if (b instanceof AppCompatButton) {
    // appcompat button replaces tint of its drawable background
    ((AppCompatButton)b).setSupportBackgroundTintList(c);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Lollipop button replaces tint of its drawable background
    // however it is not equal to d.setTintList(c)
    b.setBackgroundTintList(c);
} else {
    // this should only happen if 
    // * manually creating a Button instead of AppCompatButton
    // * LayoutInflater did not translate a Button to AppCompatButton
    d = DrawableCompat.wrap(d);
    DrawableCompat.setTintList(d, c);
    b.setBackgroundDrawable(d);
}

6

변경하려는 스타일 속성에 따라 파리 라이브러리를 사용할 수 있습니다.

Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);
Paris.style(view).apply(R.style.YourStyle);

background, padding, textSize, textColor 등과 같은 많은 속성이 지원됩니다.

면책 조항 : 나는 도서관을 작성했습니다.


5

@Dayerman과 @h_rules의 대답이 맞습니다. 코드로 정교한 예제를 제공하려면 드로어 블 폴더에 button_disabled.xml이라는 xml 파일을 만듭니다.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="10dp">   
 <solid android:color="@color/silver"/>
<corners
   android:bottomRightRadius="20dp"
   android:bottomLeftRadius="20dp"
   android:topLeftRadius="20dp"
   android:topRightRadius="20dp"/>
</shape>

그런 다음 Java에서

((Button) findViewById(R.id.my_button)).setEnabled(false);
((Button) findViewById(R.id.my_button)).setBackgroundResource(R.drawable.button_disabled);

그러면 버튼의 속성이 비활성화되고 색상이 은색으로 설정됩니다.

[색상은 color.xml에서 다음과 같이 정의됩니다.

<resources>

    <color name="silver">#C0C0C0</color>

</resources>

4
@Pacerier : 질문은 전혀 그렇게 말하지 않습니다. 스타일이 XML인지 Java인지는 모호합니다. 프로그래밍 방식으로 스타일을 설정하는 방법 만 묻습니다.
Harvey

3

런타임에 버튼에 원하는 스타일을 알 수 있습니다. 따라서 미리 레이아웃 폴더의 xml에서 필요한 스타일로 모든 버튼을 사용할 수 있습니다. 따라서 레이아웃 폴더에 button_style_1.xml이라는 파일이있을 수 있습니다. 해당 파일의 내용은 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<Button
    android:id="@+id/styleOneButton"
    style="@style/FirstStyle" />

조각으로 작업하는 경우 onCreateView에서 다음과 같이 해당 버튼을 팽창시킵니다.

Button firstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);

여기서 container는 조각을 만들 때 재정의하는 onCreateView 메서드와 관련된 ViewGroup 컨테이너입니다.

그런 버튼이 두 개 더 필요하십니까? 다음과 같이 만듭니다.

Button secondFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
Button thirdFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);

이러한 버튼을 사용자 정의 할 수 있습니다.

secondFirstStyleBtn.setText("My Second");
thirdFirstStyleBtn.setText("My Third");

그런 다음 onCreateView 메서드에서 부풀린 레이아웃 컨테이너에 사용자 정의 된 스타일 화 된 버튼을 추가합니다.

_stylizedButtonsContainer = (LinearLayout) rootView.findViewById(R.id.stylizedButtonsContainer);

_stylizedButtonsContainer.addView(firstStyleBtn);
_stylizedButtonsContainer.addView(secondFirstStyleBtn);
_stylizedButtonsContainer.addView(thirdFirstStyleBtn);

이것이 스타일 화 된 버튼으로 동적으로 작업 할 수있는 방법입니다.


0

홀더 패턴을 사용하여이를위한 도우미 인터페이스를 만들었습니다.

public interface StyleHolder<V extends View> {
    void applyStyle(V view);
}

이제 실용적으로 사용하려는 모든 스타일에 대해 인터페이스를 구현하십시오. 예를 들면 다음과 같습니다.

public class ButtonStyleHolder implements StyleHolder<Button> {

    private final Drawable background;
    private final ColorStateList textColor;
    private final int textSize;

    public ButtonStyleHolder(Context context) {
        TypedArray ta = context.obtainStyledAttributes(R.style.button, R.styleable.ButtonStyleHolder);

        Resources resources = context.getResources();

        background = ta.getDrawable(ta.getIndex(R.styleable.ButtonStyleHolder_android_background));

        textColor = ta.getColorStateList(ta.getIndex(R.styleable.ButtonStyleHolder_android_textColor));

        textSize = ta.getDimensionPixelSize(
                ta.getIndex(R.styleable.ButtonStyleHolder_android_textSize),
                resources.getDimensionPixelSize(R.dimen.standard_text_size)
        );

        // Don't forget to recycle!
        ta.recycle();
    }

    @Override
    public void applyStyle(Button btn) {
        btn.setBackground(background);
        btn.setTextColor(textColor);
        btn.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
    }
}

당신의 stylable를 선언 attrs.xml,이 예를 들어 styleable입니다 :

<declare-styleable name="ButtonStyleHolder">
    <attr name="android:background" />
    <attr name="android:textSize" />
    <attr name="android:textColor" />
</declare-styleable>

다음은 선언 된 스타일입니다 styles.xml.

<style name="button">
    <item name="android:background">@drawable/button</item>
    <item name="android:textColor">@color/light_text_color</item>
    <item name="android:textSize">@dimen/standard_text_size</item>
</style>

그리고 마지막으로 스타일 홀더의 구현 :

Button btn = new Button(context);    
StyleHolder<Button> styleHolder = new ButtonStyleHolder(context);
styleHolder.applyStyle(btn);

이것은 쉽게 재사용 할 수 있고 코드를 깨끗하고 장황하게 유지하기 때문에 매우 유용하다는 것을 알았습니다. 모든 스타일을 설정 한 후에 가비지 수집기가 작업을 수행 할 수 있도록 로컬 변수로만 사용하는 것이 좋습니다. .


-1

나는 최근에 같은 문제에 직면했습니다. 여기에 내가 해결 한 방법이 있습니다.

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

    <!-- This is the special two colors background START , after this LinearLayout, you can add all view that have it for main background-->
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:weightSum="2"

    android:background="#FFFFFF"
    android:orientation="horizontal"
    >

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#0000FF" />

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#F000F0" />
    </LinearLayout>
    <!-- This is the special two colors background END-->

   <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:gravity="center"
    android:text="This Text is centered with a special backgound,
    You can add as much elements as you want as child of this RelativeLayout"
    android:textColor="#FFFFFF"
    android:textSize="20sp" />
</RelativeLayout>
  • android : weightSum = "2"와 함께 LinearLayout을 사용했습니다.
  • 두 개의 자식 요소 android : layout_weight = "1"에 부여했습니다 (부모 공간 (너비 및 높이)의 각 50 %를 부여했습니다)
  • 마지막으로 최종 효과를 내기 위해 두 개의 자식 요소에 서로 다른 배경색을 부여했습니다.

감사 !

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.