2013-02-12 33 views
5

Tôi mới phát triển Android và tôi đang viết một ứng dụng nhỏ để hiểu cách hoạt động của nó. Tôi đã có tất cả các công việc, nhưng tại thời điểm này tôi không thể có được một điểm về các quốc gia có thể tùy chỉnh drawable ... hãy để tôi giải thích với một số mẫu mã.Không thể hiểu trạng thái có thể tùy chỉnh của Android

Đây là attrs.xml của tôi, trong đó tôi khai báo một thuộc tính với tên "oddMonth", mà là boolean:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="DayView"> 
     <attr name="oddMonth" format="boolean"/> 
    </declare-styleable> 
</resources> 

Sau đó, tôi có một tùy chỉnh xem:

<?xml version="1.0" encoding="utf-8"?> 
<com.example.calendar.DayView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="90dp" 
    android:background="@drawable/dayview_state" > 
    <TextView android:id="@+id/day_number" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentRight="true" 
     android:paddingRight="3dp" /> 
</com.example.calendar.DayView> 

Vì vậy, tôi đặt dòng "android: background =" @ drawable/dayview_state "", có nghĩa là tệp dayview_state.xml:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:easycalendar="http://schemas.android.com/apk/res/com.example.calendar"> 

    <item easycalendar:oddMonth ="true" android:drawable="@drawable/customborder_odd" /> 
    <item easycalendar:oddMonth ="false" android:drawable="@drawable/customborder_even"/> 

</selector> 

Vì vậy, f ar ... cho những gì tôi có thể hiểu .... Tôi có một thuộc tính được định nghĩa trong attrs.xml. Thuộc tính này thể hiện trạng thái cho chế độ xem tùy chỉnh của tôi. Theo giá trị boolean của thuộc tính này, ứng dụng của tôi sẽ tải một trong hai xml khác nhau (không quan trọng ở đây), mỗi một định nghĩa có thể vẽ khác nhau. Vì vậy, bước cuối cùng là xây dựng lớp tùy chỉnh của tôi! Theo dõi trích xuất từ ​​lớp học:

public class DayView extends RelativeLayout { 
    private static final int[] STATE_ODD_MONTH = { R.attr.oddMonth }; 
    private boolean mOddmonth = true; 

    public DayView(Context mContext, AttributeSet attrs) { 
     super(mContext, attrs); 
    } 

    @Override 
    protected int[] onCreateDrawableState(int extraSpace) { 
     if (mOddmonth) { 
      final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
      mergeDrawableStates(drawableState, STATE_ODD_MONTH); 

      return drawableState; 
     } else { 
      return super.onCreateDrawableState(extraSpace); 
     } 
    } 

    public boolean isOddMonth() { 
     return mOddmonth; 
    } 

    public void setOddMonth(boolean oddMonth) { 
     if (mOddmonth != oddMonth) { 
      mOddmonth = oddMonth; 

      refreshDrawableState(); 
     } 
    } 
} 

Ok ... vì vậy tôi có một biến riêng tư mOddMonth, whith getter và setter. Hàm khởi tạo được sử dụng để tăng lượt xem này ở nơi khác. Biến riêng tư khác:

private static final int[] STATE_ODD_MONTH = { R.attr.oddMonth }; 

là một mảng được tạo thành chỉ có một giá trị int, đó là tham chiếu đến thuộc tính oddMonth được định nghĩa trong attrs.xml. Và phương pháp kế thừa:

@Override 
    protected int[] onCreateDrawableState(int extraSpace) { 
     if (mOddmonth) { 
      final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
      mergeDrawableStates(drawableState, STATE_ODD_MONTH); 

      return drawableState; 
     } else { 
      return super.onCreateDrawableState(extraSpace); 
     } 
    } 

mà tôi có thể không thực sự "vô cùng" hiểu ... tốt, có vẻ như với tôi rằng tôi thêm một nhà nước nếu biến mOddMonth địa phương là đúng, và ngược lại. Vì vậy, ... mã của tôi chỉ hoạt động nếu tôi thay dayview_state.xml của tôi với những điều sau đây:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:easycalendar="http://schemas.android.com/apk/res/com.example.calendar"> 

    <item easycalendar:oddMonth ="true" android:drawable="@drawable/customborder_odd" /> 
    <item android:drawable="@drawable/customborder_even"/> 

</selector> 

Bằng cách này, bố trí đầu tiên được nạp nếu có nhà nước, nếu không sẽ được nạp thứ hai. Nhưng NHỮNG GÌ VỀ GIÁ TRỊ của tiểu bang? Không nơi nào trong mã của tôi, tôi đặt giá trị cho biến/thuộc tính này .... nơi tôi sai?

+0

Dường như nó hoạt động với bộ chọn mặc định và chỉ đặt giá trị đúng:

+0

Và như vậy? những gì về bộ chọn tùy chỉnh của tôi? – Stefano

+0

Tôi không nghĩ rằng tôi hiểu câu hỏi của bạn cho mỗi biến - mOddmonth biến được đặt thành true vì vậy đó là lý do tại sao bạn kết thúc với trạng thái STATE_ODD_MONTH trong onCreateDrawableState. Vì vậy, chính xác những gì bạn có nghĩa là bởi "NHỮNG GÌ GIÁ TRỊ của nhà nước? Không nơi nào trong mã của tôi, tôi đặt giá trị cho biến/thuộc tính này" –

Trả lời

0

tôi sẽ khuyên bạn xây dựng lại và câu hỏi của bạn b/c nó không được rõ ràng những gì bạn đã yêu cầu cho đến khi tôi đọc comment của bạn để trả lời @ kcoppock, mà là -

"những gì tôi muốn làm (hoặc Tôi nghĩ tôi nên làm) là đặt giá trị này ở đâu đó trong mã theo trạng thái thực tế của chế độ xem tùy chỉnh của tôi, và sau đó buộc nó hiển thị lại .... Hoặc tôi không nên? "

Tại thời điểm bất kỳ, bạn có thể truy vấn các quan điểm để có được nó bang drawable sử dụng View.getDrawableState.

Nếu dựa trên điều này, bạn muốn hiển thị lại nội dung có thể vẽ của mình, sau đó bạn có một số tùy chọn.

Trước hết, bạn có thể gọi Drawable.invalidateSelf. Nhưng bạn hiếm khi cần phải làm điều đó bởi vì thường drawable của bạn được thiết lập như là một nền của view drawable được tự động rút ra cho bạn trong phương thức vẽ (không onDraw, đó là những gì bạn vẽ). Vì vậy, tất cả những gì bạn cần làm trong trường hợp đó là làm mất hiệu lực chế độ xem (view.invalidate), nó sẽ tự động vẽ lại nền của bạn có thể drawable (do đó chọn thay đổi trạng thái có thể kéo).

Nếu bạn đang sử dụng bản vẽ có thể vẽ không phải là nền nhưng đối với bản vẽ chính của bạn thì bạn vẽ các bản vẽ của mình trong trênDraw. Một myDrawable.draw (canvas) đơn giản là đủ. Nhưng hãy nhớ xem vall view.invalidate để kích hoạt phương thức onDraw.

0

Bạn chính xác; bạn sẽ cần phải gán giá trị đó trong hàm tạo của bạn với biến AttributeSet:

TypedArray values = context.obtainStyledAttributes(attrs, STATE_ODD_MONTH); 
boolean isOddMonth = values.getBoolean(R.attr.oddMonth, false); 
mOddmonth = isOddMonth; 
values.recycle(); 

Tôi tin rằng điều này nên thực hiện thủ thuật. Tôi thường sử dụng một thẻ tuyên bố theo kiểu trong attrs.xml thay vì hardcoding một int [], nhưng tôi tin rằng nó sẽ làm việc giống hệt nhau.

+0

Cảm ơn bạn đã trả lời! tốt ... Nhưng TypedArray không được sử dụng để lấy giá trị của thuộc tính oddMonth được định nghĩa trong attrs.xml? những gì tôi muốn làm (hoặc tôi nghĩ rằng tôi nên làm) là đặt giá trị này ở đâu đó trong mã theo tình trạng thực tế của chế độ xem tùy chỉnh của tôi, và sau đó buộc nó để render lại .... Hoặc tôi không nên? – Stefano

+0

Ồ tôi hiểu; Tôi tin rằng tôi hiểu lầm câu hỏi, xin lỗi. – kcoppock

+0

@Stefano xem câu trả lời của tôi bên dưới. –

Các vấn đề liên quan