2013-07-05 40 views
8

Giả sử chúng ta có tùy chỉnh ListView mở rộng phương thức onDraw() bằng cách vẽ một số hình chữ nhật trong đó.Cách phủ màu văn bản của mục danh sách trong khu vực cụ thể?

class Listpicker extends ListView { 
//..Some other methods here..// 
    @Override 
    protected void onDraw(android.graphics.Canvas canvas) { 
    super.onDraw(canvas); 
    canvas.drawBitmap(glassPickerBitmap, null, glassRect, semiTransparrentPaint); 
    } 
} 

Bitmap được vẽ đại diện cho một số loại kính là hình chữ nhật có chiều rộng bằng chiều rộng của listview và một số chiều cao. Những gì tôi muốn là khi mục danh sách cuộn vào hình chữ nhật này, màu được sử dụng để vẽ văn bản (không phải tất cả các mục có nền và vv) sẽ được thay đổi thành một số màu khác. Vì vậy, ví dụ, khi mục danh sách phù hợp để chỉ có một nửa chiều cao của văn bản phù hợp với glassPickerBitmap, phần bên ngoài của mục danh sách phải giữ nguyên màu sắc của nó và phần bên trong glassPickerBitmap sẽ thay đổi màu văn bản của nó. Các mục danh sách là TextView đơn giản mà không có bất kỳ nền nào.

Làm cách nào để đạt được điều này? Có thể bất kỳ ColorFilter nào được gán cho Paint? Nhưng ở đâu? Phương pháp onDraw() của Listview thậm chí không được gọi khi ListView được cuộn ... Có thể thực hiện điều này bên trong các chế độ xem được tùy chỉnh, ví dụ, đó sẽ là các mục của ListView? Hoặc có thể là một số màu/Shader/không biết những gì khác lớp phủ có thể được sử dụng ở đây, nhưng nơi?

EDIT (thêm ví dụ hình ảnh):

Dưới đây là ví dụ về một số cây trồng từ ứng dụng thực tế cuộc sống. Có 2 ListView s: một ở bên trái, ở bên phải. Glass là hình chữ nhật màu xám. Bây giờ, danh sách trái có "Đô la Mỹ" đơn vị tiền tệ được chọn. Và tôi di chuyển sang phải ListView theo cách đó, lựa chọn đó là nơi nào đó giữa USD và Afghanistan Afghanistan. Bây giờ, những gì tôi muốn, đó làUSD tiền tệ trong ListView trái sẽ được rút ra trong màu đỏ (màu chính xác không quan trọng bây giờ, tôi sẽ thay đổi nó sau một cái gì đó có ý nghĩa) AND, trong cùng một thời điểm, phần dưới cùng của "Đô la Mỹ" và phần trên cùng của "Afghanistan Afghanistan" ở bên phải ListView cũng sẽ được vẽ cùng màu đỏ.

thay đổi màu sắc này nên được thực hiện theo cách năng động - màu nên được thay đổi chỉ cho một phần của văn bản đó là dưới hình chữ nhật kính trong suốt cuộn danh sách.

* OK, EUR và USD dưới đây là loại tiền tệ đặc biệt được vẽ bằng màu lục lam không chuẩn. Câu hỏi đặt ra là ít nhất văn bản có màu màu trắng. Nhưng nếu nó sẽ có thể thay đổi màu lục lam cũng sẽ rất tuyệt.

List example

+0

'View.setWillNotDraw' (boolean willNotDraw) nên được' onDraw' gọi trong 'ListView'. Cho dù điều đó sau đó sẽ cho phép bạn đạt được những gì bạn muốn là gây tranh cãi. Tuy nhiên, câu hỏi thú vị. – techiServices

+0

@Prizoff bạn có thể cung cấp hai hình ảnh (một trong những mục thông thường và mặt hàng khác của mặt hàng bên dưới kính) không? – eveliotc

+0

@EvelioTarazona thực hiện – Prizoff

Trả lời

3

Như bạn có thể nói trong việc thực hiện của họ, họ sử dụng và cập nhật một vị trí cố định trong ListAdapter của họ như vậy thì họ cập nhật View phù hợp cho phù hợp, đó là đối với tôi là cách dễ nhất và đơn giản để làm điều đó, nhưng bạn không nhận được văn bản nửa nửa màu, mà tôi nghĩ rằng bạn vẫn muốn :)


http://i.imgur.com/jHvuBcL.png

Vì vậy, đây có lẽ là một trong những điều tồi tệ nhất câu trả lời tôi đã đưa ra, xin lỗi về điều đó, tôi có lẽ sẽ xem xét lại này hoặc hy vọng ai đó có thể chỉ cho bạn một giải pháp tốt hơn

Bạn có thể thấy một bản demo mờ tại địa chỉ:

http://telly.com/Y98DS5

Cách bẩn :

  • Tạo một Paint với một hợp ColorMatrixColorFilter, nhằm mục đích trả lời này tôi chỉ desaturating, bạn sẽ phải tìm ra ma trận 5x4 của bạn cho ColorMatrix để có được những cyan bạn đang tìm kiếm. Ngoài ra, bạn sẽ cần một số Rect s để xác định nguồn và đích khi vẽ bên dưới.
  • Tạo màn hình tắt BitmapCanvas bạn sẽ sử dụng để vẽ danh sách, được thực hiện trong onSizeChanged. ListView để bạn có thể nhận được OutOfMemoryException.
  • Override draw sử dụng tắt màn hình của bạn Canvas và để ListView hòa với nó, sau đó bạn có thể vẽ Bitmap đến cho Canvas rằng sẽ vẽ danh sách của bạn như bình thường, sau đó rút ra chỉ là một phần của Bitmap rằng đó sẽ được rút ra cách khác nhau sử dụng số Paint mà chúng tôi đã xác định trước đó, bạn sẽ bị thấu chi cho những pixel đó.
  • Cuối cùng vẽ kính được chế tạo sẵn Bitmap, tôi muốn giới thiệu một bản vá (9-patch) để nó cân và trông sắc nét trên màn hình và mật độ, sau đó bạn sẽ nhận được nhiều tiền hơn cho những pixel đó.

Toàn bộ bánh trông giống như:

public class OverlayView extends ListView { 
    private RectF mRect; 
    private Rect mSrcRect; 
    private Paint mPaint; 

    private Canvas mCanvas; 
    private Bitmap mBitmap; 
    private float mY; 
    private float mItemHeight; 

    public OverlayView(Context context) { 
    super(context); 

    initOverlay(); 
    } 

    public OverlayView(Context context, AttributeSet attrs) { 
    super(context, attrs); 

    initOverlay(); 
    } 

    public OverlayView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 

    initOverlay(); 
    } 

    private void initOverlay() { 
    // DO NOT DO THIS use attrs 
    final Resources res = getResources(); 
    mY = res.getDimension(R.dimen.overlay_y); 
    mItemHeight = res.getDimension(R.dimen.item_height); 
    // 
    mRect = new RectF(); 
    mSrcRect = new Rect(); 
    mPaint = new Paint(); 

    ColorMatrix colorMatrix = new ColorMatrix(); 
    colorMatrix.setSaturation(0); 
    mPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); 
    } 

    @Override 
    public void draw(Canvas canvas) { 
    super.draw(mCanvas); 
    canvas.drawBitmap(mBitmap, 0, 0, null); 

    canvas.drawBitmap(mBitmap, mSrcRect, mRect, mPaint); 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 

    mRect.set(0, mY, w, mY + mItemHeight); 
    mRect.roundOut(mSrcRect); 

    mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
    mCanvas = new Canvas(mBitmap); 
    } 
} 

Vì vậy, những gì đã nói, tôi hy vọng bạn kết thúc với một giải pháp sạch hơn, ngay cả khi bạn không nhận được rằng một nửa nửa quyến rũ :)

+0

Yup Tôi sử dụng Max OS X chính xác Maverixks – eveliotc

+0

Làm thế nào về việc sử dụng 'getDrawingCache()' thay vì một bitmap riêng biệt? –

+0

@ S.D. Bạn cũng có thể sử dụng nó, trên thực tế, có một số thứ khác như kích thước bộ nhớ cache tối đa không được chấp nhận, bitmap trống, ai đó cũng có thể sử dụng bộ nhớ cache đó và tôi nhớ bạn chỉ nên sử dụng nó đối với các lớp phần mềm, trong trường hợp này (không phải lúc nào) quản lý bộ nhớ cache của riêng bạn cho phép bạn kiểm soát và yên tâm: bạn biết chắc chắn đó là lỗi của bạn;) như tôi đã đề cập trước đây là bẩn, và bạn nên tránh nó (tồi tệ nhất) nhân viên bán hàng bao giờ) – eveliotc

1

Thứ nhất, giữ một bitmap tùng và vải:

class Listpicker extends ListView { 
    Bitmap bitmapForOnDraw = null; 
    Canvas canvasForOnDraw = null; 

Hãy chắc chắn rằng đó là kích thước phù hợp:

@override 
    protected void onSizeChanged (int w, int h, int oldw, int oldh) { 
     if (bitmapForOnDraw != null) bitmapForOnDraw.recycle(); 
     bitmapForOnDraw = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     canvasForOnDraw = new Canvas(bitmapForOnDraw); 
    } 

Và khi chúng ta đến vẽ danh sách:

@override 
    protected void onDraw(android.graphics.Canvas realCanvas) { 
     // Put the list in place 
     super.onDraw(realCanvas); 

     // Now get the same again 
     canvasForOnDraw.drawColor(0x00000000, PorterDuff.Mode.CLEAR); 
     super.onDraw(canvasForOnDraw); 
     // But now change the colour of the white text 
     canvasForOnDraw.drawColor(0xffff00ff, PorterDuff.Mode.MULTIPLY); 

     // Copy the different colour text into the right place 
     canvas.drawBitmap(bitmapForOnDraw, glassRect, glassRect overwritePaint); 

     // finally, put the box on. 
     canvas.drawBitmap(glassPickerBitmap, null, glassRect, semiTransparrentPaint); 
    } 
Các vấn đề liên quan