2013-07-05 72 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); 
    }