2012-02-27 41 views
17

Tôi cần tạo chế độ xem hình thu nhỏ với các góc được làm tròn và bóng bên trong. Thông thường tôi đang làm khung hình ImageView với 9patch, đã phục vụ tốt cho đến nay, nhưng lần này hiệu ứng tôi cần yêu cầu vẽ bóng bên trong trên đầu hình ảnh (và không chỉ xung quanh nó). Điều này dẫn tôi mở rộng lớp ImageView và ghi đè lên phương thức onDraw().ImageView với các góc tròn và bóng bên trong

public class ThumbnailImageView extends ImageView { 

Sau nhiều hướng dẫn (! Nhờ StackOverflow), tôi đã kết thúc với mã này cho) phương pháp OnDraw (:

@Override 
protected void onDraw(Canvas canvas) { 
    if (mBitmap == null) { 
     return; 
    } 

    int radius = 4; 
    int padding = 2; 
    int bleed = 2; 
    RectF frame = new RectF(padding, padding, getWidth() - padding, getHeight() - padding); 

    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    mPaint.setColor(0xFF000000); 
    canvas.drawRoundRect(frame, radius, radius, mPaint); 

    Shader bitmapShader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP); 
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    mPaint.setColor(0xFF000000); 
    mPaint.setMaskFilter(new BlurMaskFilter(bleed, Blur.INNER)); 
    mPaint.setShader(bitmapShader); 
    canvas.drawRoundRect(frame, radius, radius, mPaint); 
} 

Những gì tôi đang về cơ bản làm, được vẽ một hình chữ nhật tròn đen đầu tiên và sau đó vẽ một bitmap tròn góc với các cạnh mờ dần (với BlurMaskFilter) trên đầu trang của nó. Kết quả là những gì tôi muốn: giá trị onDraw() result các mBitmap được khởi tạo trong constructor ImageView như thế này:

mDrawable = getDrawable(); 
if (mDrawable != null) { 
    mBitmap = ((BitmapDrawable) mDrawable).getBitmap(); 
} 

Vấn đề là tôi trọng OnDraw() hoàn toàn (không super.onDraw()) được gọi , vì vậy tôi phải quy mô trước tất cả các hình ảnh với kích thước hình thu nhỏ mong muốn (ví dụ: 96x96) hoặc chỉ khác ở góc trên bên trái của hình ảnh được vẽ. Những gì tôi muốn để có thể làm là tận dụng lợi thế của tất cả các nhân rộng khuôn khổ đang làm khi tôi gán các giá trị xml sau vào ThumbnailImageView:

android:id="@+id/thumb" 
android:layout_width="96dp" 
android:layout_height="wrap_content" 
android:adjustViewBounds="true" 
android:scaleType="fitCenter" 

Để làm điều này, tôi nghĩ rằng tôi bằng cách nào đó nên gọi super.onDraw() trong khi nhận được các hiệu ứng tôi cần cùng một lúc. Tôi đã quản lý để có được rectange tròn bằng cách thêm một clipping đường dẫn đến vải, nhưng tôi không thể tìm thấy một cách để thêm bóng tối bên trong. Đây là OnDraw() mã mới:

@Override 
protected void onDraw(Canvas canvas) { 
    int radius = 4; 
    int padding = 4;   
    RectF frame = new RectF(padding, padding, getWidth() - padding, getHeight() - padding); 
    Path clipPath = new Path(); 
    clipPath.addRoundRect(frame, radius, radius, Path.Direction.CW); 
    canvas.clipPath(clipPath); 
    super.onDraw(canvas); 
    // add inner shadow 
} 

tôi có thể thấy hai lựa chọn:

1) Để đúng cách trước quy mô bitmap của ImageView. Nhưng đâu là nơi tốt nhất để làm điều đó? Trong constructor của nó? Trong phương thức onDraw() trong đó khung làm việc dường như đang làm việc đó? Là khuôn khổ thậm chí thay đổi kích thước bất kỳ bitmap hoặc là có một cách khác để vẽ một hình ảnh thu nhỏ trên vải mà không bị xấu cho hiệu suất?

2) Để thêm lớp bóng bên trong phía trên những gì super.onDraw() đang vẽ cho đến nay, nhưng tôi đang hết ý tưởng về cách thực hiện việc này.

Mọi trợ giúp sẽ được đánh giá cao.

Cảm ơn!

Trả lời

11

Hãy xem tài liệu trình bày của Eric (từ hình vuông) từ Hội nghị AndoridOpen của Oreilly năm ngoái trong bài giảng có tiêu đề Beautiful Android Nó có rất nhiều thông tin sẽ giúp bạn.

Tôi ước họ có video trình bày của anh ấy ở đâu đó. Tôi không thể tìm thấy nó. Rất xin lỗi.

EDIT: Nhờ @mykola cho yt link

+1

1 cho một liên kết rất hữu ích :) – Wesley

+1

đây là liên kết để video http://www.youtube.com/watch?v=jF6Ad4GYjRU – mykola

+0

@mykola OMG. bạn đá. cảm ơn vì liên kết yt !!!! – petey

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