假设我们有自定义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
?但是哪里?当onDraw()
滚动时,甚至不会调用Listview
的{{1}}方法...可以在自定义视图中完成此操作,例如ListView
&#39}。的物品?或者可能是某些Color / Shader /不知道这里可以使用哪些叠加,但哪里?
编辑(添加图片示例):
以下是来自现实应用的一些作物的示例。有2个ListView
s:一个在左侧,另一个在右侧。玻璃是灰色矩形。现在,左侧列表已选择"美元" 货币。我以这种方式向右滚动ListView
,选择介于 USD 和 Afghan Afghani 之间。现在,我想要的是,左侧ListView
中的 USD 货币将以红色绘制(确切的颜色现在不重要,我稍后会将其更改为有意义的内容)和,同时,"美元" 的底部和"阿富汗阿富汗人" 的右上角ListView也将以相同的红色绘制。
这种颜色变化应该以动态的方式进行 - 在滚动列表期间,只应为玻璃矩形下的文本部分更改颜色。
*好的,欧元和美元这里是使用非标准青色绘制的特殊货币。问题是至少有 white 颜色的文字。但如果能够改变青色也会很棒。
答案 0 :(得分:3)
正如您在实施中所述,他们使用并更新ListAdapter
中的固定位置,然后他们更新相应匹配的View
,这对我来说是最简单,最简单的方法,但你没有得到半个半色的文字,我认为你仍然想要:)
所以这可能是我给出的最糟糕的答案之一,对不起,我可能会重新审视这个或希望有人能指出你更好的解决方案
您可以在以下位置看到模糊的演示:
肮脏的方式:
Paint
创建ColorMatrixColorFilter
,为了回答这个问题我只是去饱和,你必须找出ColorMatrix
的5x4矩阵才能获得青色你寻找。在下面绘制时,您还需要一些Rect
来定义source和dest。Bitmap
和Canvas
,这是在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);
}
}
所以说,我希望你最终得到一个更清洁的解决方案,即使你没有达到半个半性的性感:)
答案 1 :(得分: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);
}