Ответ 1
Вы пытаетесь решить эту проблему, используя иерархию вида, например:
- Родитель
- ListView
- InverterView
Проблема в том, что InverterView
не имеет контроля над тем, как рисуется ListView
. Но вы знаете, кто имеет контроль над тем, как рисуется ListView
? ListView
родительский макет. Другими словами, то, что вы действительно хотите, - это такая иерархия:
- Родитель
- InverterLayout
- ListView
- InverterLayout
Теперь InverterLayout
отвечает за рисование ListView
и может применять к нему эффекты.
class InverterLayout extends FrameLayout
{
// structure to hold our color filter
private Paint paint = new Paint();
// the color filter itself
private ColorFilter cf;
// the rectangle we want to invert
private Rect inversion_rect = new Rect(100, 100, 300, 300);
public InverterLayout(Context context)
{
super(context);
// construct the inversion color matrix
float[] mat = new float[]
{
-1, 0, 0, 0, 255,
0, -1, 0, 0, 255,
0, 0, -1, 0, 255,
0, 0, 0, 1, 0
};
cf = new ColorMatrixColorFilter(new ColorMatrix(mat));
}
@Override protected void dispatchDraw(Canvas c)
{
// create a temporary bitmap to draw the child views
Bitmap b = Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
Canvas cc = new Canvas(b);
// draw them to that temporary bitmap
super.dispatchDraw(cc);
// copy the temporary bitmap to screen without the inversion filter
paint.setColorFilter(null);
c.drawBitmap(b, 0, 0, paint);
// copy the inverted rectangle
paint.setColorFilter(cf);
c.drawBitmap(b, inversion_rect, inversion_rect, paint);
}
}
При использовании этого параметра убедитесь, что у вашего дочернего представления есть собственный фон. Если представление прозрачно и фон окна показывает, этот фон окна не будет инвертирован, потому что InverterLayout
не имеет никакого контроля над тем, как выглядит окно.