IT TIP

Android : 프로그래밍 방식으로 선택기 (StateListDrawable)를 업데이트하는 방법

itqueen 2020. 12. 3. 21:31
반응형

Android : 프로그래밍 방식으로 선택기 (StateListDrawable)를 업데이트하는 방법


프로그래밍 방식으로 버튼 선택기를 업데이트하고 싶습니다.

아래에 주어진 xml 파일로 이것을 할 수 있습니다.

<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_enabled="false"
         android:drawable="@drawable/btn_off" />
   <item android:state_pressed="true"
         android:state_enabled="true" 
         android:drawable="@drawable/btn_off" />
   <item android:state_focused="true"
         android:state_enabled="true" 
         android:drawable="@drawable/btn_on" />
   <item android:state_enabled="true" 
         android:drawable="@drawable/btn_on" />
</selector>

프로그래밍 방식으로 동일한 작업을 수행하고 싶습니다. 나는 아래 주어진 것과 같은 것을 시도했다

private StateListDrawable setImageButtonState(int index)
{
    StateListDrawable states = new StateListDrawable();

    states.addState(new int[] {android.R.attr.stateNotNeeded},R.drawable.btn_off); 
    states.addState(new int[] {android.R.attr.state_pressed, android.R.attr.state_enabled},R.drawable.btn_off);
    states.addState(new int[] {android.R.attr.state_focused, android.R.attr.state_enabled},R.drawable.btn_on);
    states.addState(new int[] {android.R.attr.state_enabled},R.drawable.btn_on);

    return states;
}

하지만 작동하지 않았습니다.

설정 방법 android:state_enabled="false"또는 android:state_enabled="true"프로그래밍 방식.


필요한 상태의 음수 값을 사용해야합니다. 예 :

states.addState(new int[] {-android.R.attr.state_enabled},R.drawable.btn_disabled);

앞에 "-"기호가 android.R.attr.state_enabled있습니다.


여기에 매우 늦게 응답하지만 다른 사람이 StateListDrawable을 프로그래밍 방식으로 설정하는 데 문제가있는 경우에 대비합니다. 그러면 XML 파일과 마찬가지로 StateListDrawable에 상태를 설정하는 순서가 중요합니다.

예를 들어 이것은 예상대로 작동합니다.

StateListDrawable sld = new StateListDrawable();
sld.addState(new int[] { android.R.attr.state_pressed }, new ColorDrawable(Color.GRAY));
sld.addState(new int[] {}, new ColorDrawable(Color.GREEN));

이것은 :

StateListDrawable sld = new StateListDrawable();
sld.addState(new int[] {}, new ColorDrawable(Color.GREEN));
sld.addState(new int[] { android.R.attr.state_pressed }, new ColorDrawable(Color.GRAY));

댓글을 작성할 담당자가 충분하지 않지만 수락 된 답변이 저에게 효과적이지 않았습니다.

내 목표는 디자이너가 일부 버튼에 활성화, 비활성화 및 눌러 진 배경색을 설정하는 것이 었습니다. 나는 그들이 다른 디스플레이에서 색상을 테스트하는 데 사용하도록 의도했습니다.

나는 다른 사람들이 그들에게도 효과가 없다고 언급 한 것을 보았습니다.

정의해야하는 상태는 다음과 같습니다.

  • 누르지 않고 활성화되지 않은 경우 버튼이 활성화되고 누르지 않았을 때 표시됩니다.
  • 눌려서 활성화 됨, 이것은 버튼을 누르고 활성화했을 때 표시되는 것입니다.
  • 활성화되지 않았습니다. 버튼이 비활성화되었을 때 표시되는 내용입니다.

다음은 상태에 대한 아이디어를 제공하는 코드입니다. Color.Parse ()를 사용하여 색상에 대한 정수를 생성 한 다음이 메서드에 전달하여 StateListDrawable을 가져옵니다.

private StateListDrawable createDrawable(int enabled, int pressed, int disabled) {
  StateListDrawable stateListDrawable = new StateListDrawable();

  stateListDrawable.addState(new int[] { -android.R.attr.state_pressed, android.R.attr.state_enabled }, new ColorDrawable(enabled));
  stateListDrawable.addState(new int[] { android.R.attr.state_pressed, android.R.attr.state_enabled }, new ColorDrawable(pressed));
  stateListDrawable.addState(new int[] { -android.R.attr.state_enabled }, new ColorDrawable(disabled));

  return stateListDrawable;
}

I am going to answer your question "How to update the selector for a BUTTON programmatically?" by proposing to switch a button for a LinearLayout with embedded ImageView and TextView. There are a number of benefits to doing this, especially if you will later decide to customize your views. There is no loss of functionality resulting from this switch. You will still be able to attach same event listeners you can attach to a button, but will be able to avoid the buttons/tabs styling nightmares. Here is a relevant code from the layout.xml

    <LinearLayout 
        android:id="@+id/button"
        style="@style/ButtonStyle">
        <ImageView 
            android:id="@+id/background"
            android:src="@drawable/custom_image"/>
        <TextView 
            style="@style/TextStyle"
            android:text="Custom Button"
            android:id="@+id/text"/>
    </LinearLayout> 

Next, I have a selector file called custom_image.xml located in the drawable folder. Here is the content of the selector file

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/disabled_img"     android:state_enabled="false" />
    <item android:drawable="@drawable/unselected_img"     android:state_selected="false" />
    <item android:drawable="@drawable/selected_img"     android:state_selected="true" />
</selector>

The three source image files (disabled_img.png, unselected_img.png, selected_img.png) are also located in the drawable folder.

Now back to your Java code. There is no need for the funky StateListDrawable garbage for many reasons. First, it just looks ugly, and is hard to maintain. But most importantly it goes against the principles of keeping your logic separate from your presentation. If you are managing your drawable resources in Java code, you know you are doing something fundametally wrong.

Here is what I am proposing instead. Whenever you want your button to be selected, you just pop this one-liner in there:

((LinearLayout)findViewById(R.id.button)).setSelected(true);

Or whenever you want the button to be in the disabled state, here is another one-liner:

((ImageView)findViewById(R.id.background)).setEnabled(false);

Please notice that in this last example I am specifying the disabled state on the ImageView inside the LinearLayout. For some reason whenever you change the enabled / disabled state of the LinearLayout, the selector is not being triggered. It works fine when you do it on the ImageView instead.


I don't know how you are adding the StateListDrawable, since the code is not here. But be sure to be check the documentation and the adding the setState().

You can set the properties from the View, such as yourView.setEnabled(true)

I hope that helps

참고URL : https://stackoverflow.com/questions/5092649/android-how-to-update-the-selectorstatelistdrawable-programmatically

반응형