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

Pri*_*off 8 java android listview overlay colors

假设我们有自定义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);
    }
}
Run Code Online (Sandbox Code Playgroud)

绘制的位图代表某种玻璃,它是矩形,宽度等于listview的宽度和一些高度.我想要的是当列表项滚动到此矩形时,用于绘制文本的颜色(不是所有带背景的项目等)将被更改为另一种颜色.因此,例如,当列表项适合使得只有文本的一半高度适合时glassPickerBitmap,列表项的外部部分应保持其序数颜色,而内部部分glassPickerBitmap应更改其文本颜色.列表项是没有任何背景的简单TextView.

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

编辑(添加图像示例):

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

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

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

列举示例

eve*_*otc 3

正如您在他们的实现中可以看出的那样,他们使用并更新了其中的固定位置,ListAdapter因此他们View相应地更新了匹配的位置,这对我来说是最简单、最简单的方法,但是您不会得到半彩色文本,我想你仍然想要:)


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

因此,这可能是我给出的最糟糕的答案之一,对此感到抱歉,我可能会重新审视这个问题,或者希望有人能为您指出更好的解决方案

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

http://telly.com/Y98DS5

肮脏的方式:

  • 创建一个Paint适当的ColorMatrixColorFilter,为了回答这个问题,我只是去饱和,你必须弄清楚你的 5x4 矩阵才能ColorMatrix得到你想要的青色。Rect另外,在下面绘图时,您将需要一些s 来定义源和目标。
  • 创建一个离屏BitmapCanvas您将用它来绘制列表,这样做是onSizeChanged为了我们有正确的视图布局值,在这里您可以开始注意到脏乱,因为您必须分配一个Bitmap与您一样大的值ListView,这样您就可以得到OutOfMemoryException.
  • 覆盖draw以使用您的屏幕外Canvas并让其ListView绘制,然后您可以将 绘制Bitmap到将像往常一样绘制您的列表的给定部分,然后仅绘制将使用我们之前定义的以不同方式绘制的Canvas部分,您将过度绘制对于那些像素。BitmapPaint
  • 最后绘制你的预制玻璃Bitmap,我会推荐一个 n 补丁(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);
  }
}
Run Code Online (Sandbox Code Playgroud)

也就是说,我希望你最终能得到一个更干净的解决方案,即使你没有得到那种一半一半的性感:)