首页 文章

如何在特定区域中叠加列表项文本颜色?

提问于
浏览
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 内的部分应更改其文本颜色 . 列表项是没有任何背景的简单TextView .

怎么能实现这个目标?也许任何 ColorFilter 分配给 Paint ?但是哪里?当 ListView 滚动时,甚至不会调用 onDraw() Listview 的方法...可以在自定义视图中完成此操作,例如,这将是 ListView 的项目吗?或者可能是某些Color / Shader /不知道这里可以使用哪些叠加,但 where

EDIT (added image examples):

这是来自现实应用程序的一些作物的示例 . 有2个 ListView s:一个在左侧,另一个在右侧 . 玻璃是灰色矩形 . 现在,左侧列表已选择 "United States Dollar" 货币 . 而且我正在以这种方式向右滚动,选择介于美元和阿富汗阿富汗之间 . 现在,我想要的是,左边的 ListView 中的美元货币将以红色绘制(现在确切的颜色无关紧要,我稍后会将其改为有意义的东西)并且,同时,"United States Dollar"的底部和顶部右侧ListView中"Afghan Afghani"的一部分也将以相同的红色绘制 .

此颜色更改应以动态方式完成 - 仅在滚动列表期间,应仅更改玻璃矩形下文本部分的颜色 .

*好的,欧元和美元这里是使用非标准青色绘制的特殊货币 . 问题是至少有白色文字 . 但如果能够改变青色也会很棒 .

List example

2 回答

  • 1

    你可以在他们的实现中告诉他们使用并更新 ListAdapter 中的固定位置,然后他们更新相应匹配的 View ,这对我来说是最容易和最简单的方法,但是你没有得到半个半彩色文字,我觉得你还想要:)


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

    所以这可能是我给出的最糟糕的答案之一,对不起,我可能会重新审视这个或者希望有人能指出你更好的解决方案

    您可以在以下位置看到模糊的演示:

    http://telly.com/Y98DS5

    肮脏的方式:

    • 使用正确的 ColorMatrixColorFilter 创建一个 Paint ,为了回答这个问题,我必须找出_x56219_的5x4矩阵,以获得您想要的青色 . 在下面绘制时,您还需要一些 Rect 来定义source和dest .

    • 创建一个关闭 BitmapCanvas ,你_1252224_在 onSizeChanged 完成,所以我们有适当的视图布局值,在这里你可以开始注意到肮脏,因为你必须分配一个 Bitmap 大到你的 ListView 所以你可能得到 OutOfMemoryException .

    • 覆盖 draw 以使用您的屏幕 Canvas 并让 ListView 绘制到它,然后您可以将 Bitmap 绘制到将照常绘制列表的给定 Canvas ,然后绘制 Bitmap 的一部分,将使用 Paint 进行不同的绘制我们之前定义过,你会得到那些像素的透支 .

    • 最后画出预制的玻璃 Bitmap ,我会推荐一个n-patch(9-patch),所以它在屏幕和密度上缩放并看起来很清晰,然后你会得到更多的那些像素透支 .

    整个蛋糕看起来像:

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

    所以说,我希望你最终得到一个更清洁的解决方案,即使你没有得到那半半性感:)

  • 3

    首先,保留一个备用位图和画布:

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

相关问题