2011-12-31 21 views
14

Tôi đang cố gắng tạo hiệu ứng cho hai lớp có thể vẽ được để đạt được hiệu quả của chỉ báo tiến trình không xác định sau Honeycomb. XML rất đơn giản nhưng có vẻ như chỉ có một lớp sẽ sinh động khi chạy trên nền tảng trước Honeycomb.Animate Hai lớp Drawable Items Pre-Honeycomb

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item> 
     <rotate 
      android:drawable="@drawable/abs__spinner_48_outer_holo" 
      android:pivotX="50%" 
      android:pivotY="50%" 
      android:fromDegrees="0" 
      android:toDegrees="1080" /> 
    </item> 
    <item> 
     <rotate 
      android:drawable="@drawable/abs__spinner_48_inner_holo" 
      android:pivotX="50%" 
      android:pivotY="50%" 
      android:fromDegrees="720" 
      android:toDegrees="0" /> 
    </item> 
</layer-list> 

Đây có phải là chỉ đơn giản là một hạn chế của những nền tảng hoặc là có một cú pháp thay thế mà tôi có thể sử dụng (hoặc nói chung hoặc nhắm mục tiêu cụ thể là tại trước API11) để đạt được các chức năng mong muốn?

Trả lời

11

Có thực sự là một hạn chế nền tảng, mặc dù nó không phải là những gì bạn có thể nghĩ. Vấn đề là trước khi API11, RotateDrawable có một số mã thô trong đó để yêu cầu hoạt ảnh xoay theo chiều kim đồng hồ bằng cách kiểm tra xem toDegrees có lớn hơn fromDegrees hay không; nếu không, hai người bị buộc phải bằng nhau. Nếu bạn sửa đổi ví dụ của mình để di chuyển mục thứ hai theo hướng chuyển tiếp (từ 0 đến 720 hoặc thậm chí -720 đến 0), cả hai hình ảnh sẽ tạo hiệu ứng tốt trên tất cả các nền tảng; mặc dù tôi nhận ra rằng đánh bại mục đích của những gì bạn đang nhắm tới.

Hãy xem phiên bản được lưu trong bộ nhớ cache Google Codesearch có RotateDrawable.inflate(), là phiên bản 2.3 của phương pháp được sử dụng để biến XML thành đối tượng và bạn sẽ thấy ý tôi.

RotateDrawable.java ... mã vi phạm là khoảng dòng 235 ...

float fromDegrees = a.getFloat(
      com.android.internal.R.styleable.RotateDrawable_fromDegrees, 0.0f); 
    float toDegrees = a.getFloat(
      com.android.internal.R.styleable.RotateDrawable_toDegrees, 360.0f); 

    toDegrees = Math.max(fromDegrees, toDegrees); //<--There's the culprit 

này có một khối XML như mục thứ hai mà bạn có ở đó, và biến nó thành một RotateDrawable rằng kết thúc với cùng một giá trị cho fromDegreestoDegrees (trong trường hợp của bạn là 720) khiến cho hình ảnh chỉ đứng yên. Bạn có thể hiển thị kiểm tra điều này bằng cách đặt giá trị bắt đầu thành một số giá trị không phải là bội số của 360 (như 765). Bạn sẽ thấy rằng hình ảnh vẫn không hoạt ảnh, nhưng được xoay đến tọa độ ban đầu.

Kiểm tra khó xử này đã bị xóa trong các nguồn Honeycomb/ICS, đó là lý do tại sao bạn có thể thực hiện xoay vòng ngược trên các nền tảng đó. Ngoài ra, nó không giống như có một cách để thiết lập các giá trị từ mã Java, do đó, một tùy chỉnh RotateDrawableCompat có thể trong tương lai của bạn :)

HTH

+1

Thông tin chi tiết tuyệt vời về hoạt động bên trong. Cảm ơn bạn! –

+0

Cập nhật liên kết tham chiếu: https://github.com/android/platform_frameworks_base/blob/android-2.3.7_r1/graphics/java/android/graphics/drawable/RotateDrawable.java#L230-235 –

1

Có vẻ như là giải pháp nhanh chóng và dơ bẩn để có được điều này làm việc trong tổ ong trước là chỉ cần lật từ và đến trong vòng xoay thứ hai. Đây không phải là lý tưởng nhưng ít nhất là điều quay xung quanh (ngay cả khi nó là một chút "nhàm chán"). Đây là cách ABS dường như đã giải quyết nó.

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item> 
     <rotate 
      android:drawable="@drawable/abs__spinner_48_outer_holo" 
      android:pivotX="50%" 
      android:pivotY="50%" 
      android:fromDegrees="0" 
      android:toDegrees="1080" /> 
    </item> 
    <item> 
     <rotate 
      android:drawable="@drawable/abs__spinner_48_inner_holo" 
      android:pivotX="50%" 
      android:pivotY="50%" 
      android:fromDegrees="0" 
      android:toDegrees="720" /> <!-- Like this --> 
    </item> 
    </layer-list>