2013-03-21 43 views
93

tôi đang cố gắng để tạo ra một ColorStateList programatically sử dụng này:Làm cách nào để tạo ColorStateList theo lập trình?

ColorStateList stateList = new ColorStateList(states, colors); 

Nhưng tôi không chắc chắn hai tham số là gì.

Theo tài liệu:

public ColorStateList (int[][] states, int[] colors) 

gia tăng ở mức API 1

Tạo một ColorStateList trả về các bản đồ quy định từ các tiểu bang để màu sắc.

Ai đó có thể giải thích cho tôi cách tạo điều này?

Ý nghĩa của mảng hai chiều cho các trạng thái là gì?

Trả lời

216

Xem http://developer.android.com/reference/android/R.attr.html#state_above_anchor cho một danh sách của các quốc gia có sẵn.

Nếu bạn muốn thiết lập màu sắc cho người khuyết tật, không tập trung tiểu bang, không được kiểm soát, vv chỉ phủ nhận trạng thái:

int[][] states = new int[][] { 
    new int[] { android.R.attr.state_enabled}, // enabled 
    new int[] {-android.R.attr.state_enabled}, // disabled 
    new int[] {-android.R.attr.state_checked}, // unchecked 
    new int[] { android.R.attr.state_pressed} // pressed 
}; 

int[] colors = new int[] { 
    Color.BLACK, 
    Color.RED, 
    Color.GREEN, 
    Color.BLUE 
}; 

ColorStateList myList = new ColorStateList(states, colors); 
+16

Cảm ơn thông tin về trạng thái "ngược lại"! – BVB

+0

Điều này có thể được sử dụng thay đổi màu sắc của một fab từ thư viện thiết kế. – Tapirboy

+0

THẬN TRỌNG: Xem câu trả lời của Roger Alien (và nhận xét đầu tiên của họ) để hiểu rằng thứ tự các trạng thái ở đây kém: vì "bật" trước tiên, nó sẽ ghi đè các trạng thái khác thường xảy ra khi nút được bật. Tốt hơn là đặt "bật" cuối cùng. (Hoặc thay vì "kích hoạt", một mục rỗng/mặc định cuối cùng.) – ToolmakerSteve

55

Thứ nguyên đầu tiên là một loạt các bộ trạng thái, thứ hai ist trạng thái được đặt. Mảng màu liệt kê các màu cho từng bộ trạng thái phù hợp, do đó độ dài của mảng màu phải khớp với thứ nguyên đầu tiên của mảng trạng thái (hoặc nó sẽ sụp đổ khi trạng thái "được sử dụng"). Ở đây và ví dụ:

ColorStateList myColorStateList = new ColorStateList(
         new int[][]{ 
           new int[]{android.R.attr.state_pressed}, //1 
           new int[]{android.R.attr.state_focused}, //2 
           new int[]{android.R.attr.state_focused, android.R.attr.state_pressed} //3 
         }, 
         new int[] { 
          Color.RED, //1 
          Color.GREEN, //2 
          Color.BLUE //3 
         } 
        ); 

hy vọng điều này sẽ hữu ích.

EDIT dụ: một xml màu danh sách nhà nước như:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_pressed="true" android:color="@color/white"/> 
    <item android:color="@color/black"/> 
</selector> 

sẽ trông như thế này

ColorStateList myColorStateList = new ColorStateList(
     new int[][]{ 
       new int[]{android.R.attr.state_pressed}, 
       new int[]{} 
     }, 
     new int[] { 
       context.getResources().getColor(R.color.white), 
       context.getResources().getColor(R.color.black) 
     } 
); 
+0

Bạn có thể te sẽ làm thế nào để đại diện cho bên dưới xml " " sử dụng chất tạo màu. – Satish

+0

@SatishKumar kiểm tra chỉnh sửa của tôi, tôi chưa thử nghiệm nó. –

+1

Đáng nói rằng để chỉ định trạng thái sai, bạn có thể phủ nhận giá trị của nó, vì vậy nếu bạn muốn chỉ định màu cho khi nó không được nhấn, bạn nên sử dụng: new int [] {- ​​android.R.attr.state_pressed} – tinsukE

8

Đáng tiếc là không ai trong số các giải pháp làm việc cho tôi.

  1. Nếu bạn không đặt trạng thái nhấn lúc đầu, nó sẽ không phát hiện được.
  2. Nếu bạn cài đặt nó, sau đó bạn cần phải xác định trạng thái trống để thêm màu sắc mặc định
ColorStateList themeColorStateList = new ColorStateList(
     new int[][]{ 
       new int[]{android.R.attr.state_pressed}, 
       new int[]{android.R.attr.state_enabled}, 
       new int[]{android.R.attr.state_focused, android.R.attr.state_pressed}, 
       new int[]{-android.R.attr.state_enabled}, 
       new int[]{} // this should be empty to make default color as we want 
     }, 
     new int[]{ 
       pressedFontColor, 
       defaultFontColor, 
       pressedFontColor, 
       disabledFontColor, 
       defaultFontColor 
     } 
); 

Đây là nhà xây dựng từ mã nguồn:

/** 
* Creates a ColorStateList that returns the specified mapping from 
* states to colors. 
*/ 
public ColorStateList(int[][] states, int[] colors) { 
    mStateSpecs = states; 
    mColors = colors; 

    if (states.length > 0) { 
     mDefaultColor = colors[0]; 

     for (int i = 0; i < states.length; i++) { 
      if (states[i].length == 0) { 
       mDefaultColor = colors[i]; 
      } 
     } 
    } 
} 
+2

Cũng giống như một sidenote: Bạn phải đối xử với nó như bạn sẽ là một if-elseif. Nó chọn trạng thái đầu tiên đúng. Vì vậy, nếu bạn có state_enabled là trạng thái đầu tiên, nó sẽ được chọn trước khi state_pressed - trừ khi khung nhìn bị tắt. – LeoFarage

+0

FWIW, vì bạn đã có một yếu tố mặc định cuối cùng, tôi không nghĩ rằng phần tử "được kích hoạt" đầu tiên đang làm bạn tốt. Tại sao không gỡ bỏ hoàn toàn? – ToolmakerSteve

1

nếu bạn sử dụng các tài nguyên của Màu sắc.xml

int[] colors = new int[] { 
       getResources().getColor(R.color.ColorVerificaLunes), 
       getResources().getColor(R.color.ColorVerificaMartes), 
       getResources().getColor(R.color.ColorVerificaMiercoles), 
       getResources().getColor(R.color.ColorVerificaJueves), 
       getResources().getColor(R.color.ColorVerificaViernes) 

     }; 

ColorStateList csl = new ColorStateList(new int[][]{new int[0]}, new int[]{colors[0]}); 

    example.setBackgroundTintList(csl); 
+2

vì 'getResources()' không còn được dùng nữa, bây giờ nó là 'ContextCompat.getColor (điều này, R.color.colorname);' hoặc 'ContextCompat.getColor (getActivity(), R.color.colorname);' để sử dụng trong một Fragment – iBobb

+0

Để làm rõ cho các độc giả khác, 'new int [0]' (như một phần tử trong danh sách tham số đầu tiên) là một mảng có độ dài bằng không, và đại diện cho thiết lập màu mặc định. Đây là phần tử duy nhất, có nghĩa là màu được áp dụng cho * tất cả * trạng thái của nút. Điều này tương đương với 'new int [] {}' được nhìn thấy trong câu trả lời của Roger Alien. – ToolmakerSteve

8

Đôi khi điều này sẽ đủ:

int colorInt = getResources().getColor(R.color.ColorVerificaLunes); 
ColorStateList csl = ColorStateList.valueOf(colorInt); 
1

lớp builder của tôi cho tạo ColorStateList

private class ColorStateListBuilder { 
    List<Integer> colors = new ArrayList<>(); 
    List<int[]> states = new ArrayList<>(); 

    public ColorStateListBuilder addState(int[] state, int color) { 
     states.add(state); 
     colors.add(color); 
     return this; 
    } 

    public ColorStateList build() { 
     return new ColorStateList(convertToTwoDimensionalIntArray(states), 
       convertToIntArray(colors)); 
    } 

    private int[][] convertToTwoDimensionalIntArray(List<int[]> integers) { 
     int[][] result = new int[integers.size()][1]; 
     Iterator<int[]> iterator = integers.iterator(); 
     for (int i = 0; iterator.hasNext(); i++) { 
      result[i] = iterator.next(); 
     } 
     return result; 
    } 

    private int[] convertToIntArray(List<Integer> integers) { 
     int[] result = new int[integers.size()]; 
     Iterator<Integer> iterator = integers.iterator(); 
     for (int i = 0; iterator.hasNext(); i++) { 
      result[i] = iterator.next(); 
     } 
     return result; 
    } 
} 

Ví dụ Sử dụng

ColorStateListBuilder builder = new ColorStateListBuilder(); 
builder.addState(new int[] { android.R.attr.state_pressed }, ContextCompat.getColor(this, colorRes)) 
     .addState(new int[] { android.R.attr.state_selected }, Color.GREEN) 
     .addState(..., some color); 

if(// some condition){ 
     builder.addState(..., some color); 
} 
builder.addState(new int[] {}, colorNormal); // must add default state at last of all state 

ColorStateList stateList = builder.build(); // ColorStateList created here 

// textView.setTextColor(stateList); 
Các vấn đề liên quan