2013-07-05 35 views
8

假設我們有自定義ListView,它通過在其中繪製一些矩形來擴展onDraw()方法。如何覆蓋特定區域的列表項文字顏色?

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); 
    } 
} 

繪製位圖代表某種玻璃中的哪一個矩形與寬度等於ListView和一些高度的寬度。我想要的是,當列表項滾動到這個矩形中時,用於繪製文本的顏色(並非所有具有背景等的項目)都會變成另一種顏色。因此,例如,當列表項適合只有文本的一半高度符合glassPickerBitmap時,列表項的外部部分應保持其順序顏色,並且glassPickerBitmap內部的部分應更改其文本顏色。列表項是簡單的TextViews,沒有任何背景。

這怎麼能實現?也許ColorFilter被分配到Paint?但是哪裏? onDraw()方法Listview甚至在ListView被滾動時不會調用...可以在定製視圖內完成這個操作,例如,這將是ListView的項目?或者可能是一些顏色/着色器/不知道可以在這裏使用什麼覆蓋圖,但是其中

編輯(添加的圖像的例子):

這裏是例如從現實生活中的應用中的一些作物。有2 ListView s:一個在左側,另一個在右側。玻璃是灰色的矩形。現在,左側列表中有「美元」貨幣選中。我正在以這種方式滾動ListView,該選擇介於USD阿富汗阿富汗尼之間。現在,我想要的是,USD左邊的ListView中的貨幣將被繪製成紅色(確切的顏色現在無關緊要,我會稍後將其更改爲有意義的東西),同時,的底部部分「美元」和頂部的「阿富汗阿富汗尼」在右側的ListView中也會以相同的紅色繪製。

這種顏色變化應該在動態的方式來完成 - 顏色應該只對文本的一部分是列表的滾動過程在玻璃下的矩形改變。

*確定,歐元和美元是用非標準青色繪製的特殊貨幣。問題是至少與文本白色顏色。但是,如果能夠改變青色的話,那就太好了。

List example

+0

'View.setWillNotDraw'(布爾willNotDraw)應該得到'onDraw'堪稱'ListView'。無論那麼就會使你達到你想要的東西是值得商榷的。但有趣的問題。 – techiServices

+0

@Prizoff可以提供兩張圖片(常規項目和玻璃下方的其他項目)? – eveliotc

+0

@EvelioTarazona完成 – Prizoff

回答

3

正如你可以在他們用自己的實現告訴我們,在他們的ListAdapter更新一個固定的位置,然後他們更新View即相應匹配,這是我做的最簡單,最簡單的方法,但你沒有得到半半彩色文本,我覺得你還是想:)


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

因此,這裏可能是最差的一個答案我已經給了,這件事很抱歉,我可能會再次討論這個還是希望有人能指出你一個更好的解決方案

你可以看到一個模糊的演示:

http://telly.com/Y98DS5

骯髒的方式:

  • 創建一個具有適當ColorMatrixColorFilter一個Paint,回答這個我只是去飽和的目的,你必須搞清楚你的​​5x4的矩陣ColorMatrix讓你找青色。在下面繪製時,您還需要一些Rect來定義源和目標。
  • 創建關閉屏幕BitmapCanvas您可以使用它來繪製你的列表,在onSizeChanged的完成,所以我們有正確的看法佈局值,在這裏你可以開始注意到髒物,你將不得不分配Bitmap一樣大你的ListView,所以你可能得到OutOfMemoryException
  • 覆蓋draw使用你關閉屏幕Canvas,讓ListView平局,那麼你可以得出Bitmap給定Canvas這將吸引你的列表像往常一樣,然後繪製只是將使用繪製不同的是Bitmap的一部分我們之前定義的Paint,您將獲得這些像素的透支。
  • 最後提醒你預製玻璃Bitmap,我會建議正補丁(9補丁),所以它擴展,看上去尖銳跨屏和密度,然後你得到更多透支了這些像素。

整個蛋糕的樣子:

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); 
    } 
} 

這樣說,我希望你最終有一個清潔的解決方案,即使你沒有得到半生性感:)

+0

是的,我使用Max OS X精確地Maverixks – eveliotc

+0

如何使用'getDrawingCache()'而不是一個單獨的位圖? –

+0

@ S.D。你可以使用它,事實上做類似的事情,只是帶來了一些額外的怪癖,如現在不推薦使用的最大緩存大小,空白位圖,其他人也可以使用該圖形緩存,因爲我記得你應該只使用它對於軟件層來說,在這種情況下(並不總是)管理你自己的緩存給你控制和一些安心:你肯定知道這是你的錯;)無論如何,正如我之前提到的,這是骯髒的,你應該避免它(最壞有史以來的銷售員) – eveliotc

1

首先,將一根備用的位圖和帆布:

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

確保它是正確的大小:

@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); 
    } 

當我們來繪製列表:

@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); 
    }