¿Cómo superponer el color del texto del elemento de la lista en una región específica?
Supongamos que tenemos el ListView
personalizado que extiende el método onDraw()
dibujando un rectángulo en él.
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); } }
El mapa de bits dibujado representa algún tipo de vidrio que es rectángulo con ancho igual al ancho de listview y algo de altura. Lo que quiero es cuando el elemento de lista se desplaza en este rectángulo el color utilizado para el texto de dibujo (no todos los elementos con fondo y etc.) se cambiarían en otro color. Por ejemplo, cuando el elemento de lista encaja de manera que sólo la mitad de la altura del texto encaje en glassPickerBitmap
, la parte externa del elemento de lista debe permanecer en sus colores ordinales y la parte que está dentro de glassPickerBitmap
debe cambiar su color de texto. Los elementos de lista son simples TextViews sin ningún fondo.
- Superposición de imagen en dos filas en una vista de lista
- Cómo guardar la superposición con vista previa de la cámara en android?
- Uso de getTileURL en la aplicación Android con GeoServer
- Cómo crear un diseño de superposición en una vista de lista
- No se puede agregar la ventana android.view.ViewRoot$W@44da9bc0 - permiso denegado para este tipo de ventana
¿Cómo puede lograrse esto? Tal vez cualquier ColorFilter
s asignado a la Paint
? ¿Pero donde? onDraw()
de Listview
ni siquiera se llama cuando ListView
se desplaza … ¿Se puede hacer esto dentro de vistas personalizadas, por ejemplo, que serán los elementos de ListView
? O puede ser algún Color / Shader / no sabe qué más superposición se puede utilizar aquí, pero ¿ dónde ?
EDIT (ejemplos de imágenes añadidas):
A continuación, se muestra el ejemplo de algún cultivo de la aplicación de la vida real. Hay 2 ListView
s: uno en el lado izquierdo, otro en el derecho. El vidrio es el rectángulo gris. Ahora, la lista izquierda tiene "dólar de los Estados Unidos" moneda seleccionada. Y estoy desplazando ListView
derecho de esa manera, que la selección está en algún lugar entre USD y Afghan Afghani . Ahora, lo que quiero, es que la moneda del USD en el ListView
izquierdo se dibujara en rojo (el color exacto no importa ahora, lo cambiaré después a algo significativo) Y, al mismo tiempo, la parte inferior de "United States Dólar " y la parte superior de " Afghan Afghani " en el ListView derecho se dibujarían también en el mismo color rojo.
Este cambio de color se debe hacer de forma dinámica – el color debe cambiarse sólo para la parte del texto que está bajo el rectángulo de vidrio durante el desplazamiento de la lista.
* OK, EUR y USD aquí son monedas especiales dibujadas con color cian no estándar. La pregunta está sobre por lo menos el texto con el color blanco . Pero si será posible cambiar también el color cian sería genial.
- Superposición transparente GLSurfaceview en la vista existente en android?
- Android: Cuando el teclado aparece, el diseño es invisible. ¿Cómo puedo solucionar esto?
- Mi mapa no muestra el mapa sólo muestra los elementos de superposición
- Detección de la superposición de pantalla: cómo manejar esto en una aplicación de superposición de pantalla
- La importación com.android.internal.R no se puede resolver
- Dibujo sobre otras aplicaciones en Android
- SetFocus (overlayItem) de ItemizedOverlay no funciona
- Creación de una ventana de superposición del sistema (siempre en la parte superior)
Como puedes ver en su implementación, usan y actualizan una posición fija en su ListAdapter
para que luego actualicen la View
que coincida en consecuencia, que es para mí la forma más fácil y sencilla de hacerlo, pero no obtienes la mitad Color de texto, que creo que todavía quieren 🙂
Así que aquí es probablemente una de las peores respuestas que he dado, lo siento, probablemente volveré a esto o espero que alguien puede señalar a una mejor solución
Puede ver una demo borrosa en:
La manera sucia:
- Crear una
Paint
con unColorMatrixColorFilter
adecuado, con el fin de responder a esto estoy desaturando sólo, tendrá que averiguar su matriz de 5×4 paraColorMatrix
para obtener el cian su buscando. También necesitará algunosRect
para definir fuente y dest al dibujar abajo. - Crear un
Bitmap
pantalla yCanvas
fuera de pantalla que se utiliza para dibujar su lista, que se hace enonSizeChanged
por lo que tenemos valores de diseño de vista adecuada, aquí puede empezar a notar la suciedad ya que tendrá que asignar unBitmap
tan grande comoListView
para Puede obtenerOutOfMemoryException
. - Anote el
draw
para usar elCanvas
pantalla y deje queListView
dibuje, entonces puede dibujar elBitmap
deBitmap
alCanvas
dado que dibujará su lista como de costumbre y dibujará sólo la parte de eseBitmap
deBitmap
que se dibujará de manera diferente usando elPaint
we Definido antes, obtendrá overdraw para esos píxeles. - Por último, dibuje su
Bitmap
vidrio pre-fabricado, yo recomendaría un n-parche (9 parches) por lo que se escala y se ve agudo a través de las pantallas y densidades, a continuación, obtendrá más sobregiro para esos píxeles.
La torta entera parece:
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); } }
Así que dicho, espero que termines con una solución más limpia, incluso si usted no consigue que la mitad de la sensualidad mitad 🙂
Primero, mantenga un bitmap y un lienzo de repuesto:
class Listpicker extends ListView { Bitmap bitmapForOnDraw = null; Canvas canvasForOnDraw = null;
Asegúrese de que es el tamaño correcto:
@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); }
Y cuando llegamos a dibujar la lista:
@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); }
- El depurador de Android Studio no muestra variables locales
- Dibujo sobre lienzo y varios objetos de pintura