Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Ampliación de la clase de Android View para agregar un dropshadow

Quiero extender LinearLayout para que cuando mi diseño se dibuja una gota de sombra se añade por debajo de él. He jugado alrededor de sobrepasar el método onDraw , pero estoy un poco perdido. Cualquier ayuda con esto o incluso sugerencias de la biblioteca sería muy apreciada!

He aquí un ejemplo de la vista de sombra que estoy tratando de lograr. No creo que pueda usar un parche nueve aquí porque necesito que el contenido de la vista esté dentro de la caja blanca. Esto significaría que tendría que saber la distancia entre la frontera y el final de la PNG. Sin embargo, creo que diferentes densidades de pantalla significan que esta distancia será siempre la misma PX pero no la misma DP.

  • No se puede cambiar el tamaño de los niños de diseño lineal en android reaccionar módulo nativo
  • AppBarLayout transparente y CollapsingToolbarLayout
  • ¿Cómo detectar el golpe a la izquierda oa la derecha en Android?
  • Variables en los recursos XML: pasa valores de padres a hijos
  • Programar de forma programada android: layout_centerHorizontal
  • Utilizar la biblioteca DataBinding para establecer el recurso de color de fondo o null
  • Por lo tanto, para ser claro, necesito una forma de extender la clase View para que una sombra se dibuje debajo de ella cuando se agrega a un diseño. No hay soluciones XML o 9Patch por favor.

    Introduzca aquí la descripción de la imagen

    Gracias

    Jack

  • Menú como SKOUT y deslizamiento de una vista a otra mediante el toque en Android
  • Diapositiva xml animación en la actividad de cambio en android
  • Cambio de posición del cuadro de diálogo en la pantalla de Android
  • ¿Cómo mostrar un diseño encima del otro programmatically en mi caso?
  • ¿Cómo puedo alinear el menú / iconos de la barra de herramientas Android a la izquierda como en la aplicación de Google Maps?
  • Cómo agregar relleno entre los elementos del menú en android?
  • 3 Solutions collect form web for “Ampliación de la clase de Android View para agregar un dropshadow”

    Estoy de acuerdo con los comentarios sobre tu pregunta: el efecto dropshadow programático es una mala elección, y puedes lograr el mismo efecto con un simple 9patch (o un conjunto de ellos) como se indica aquí .

    BTW era demasiado curioso, y terminé con hackear una solución después del trabajo.

    El código presentado es una prueba, y debe ser concebido como una simple prueba de concepto (así que por favor, no downvote). Algunas de las operaciones que se muestran son bastante caras , y pueden afectar seriamente las actuaciones. (Hay muchos ejemplos alrededor, mire aquí , aquí para tener una idea). Debe ser una solución de último recurso sólo para un componente que se muestra una vez en uno.

     public class BalloonView extends TextView { protected NinePatchDrawable bg; protected Paint paint; protected Rect padding = new Rect(); protected Bitmap bmp; public BalloonView(Context context) { super(context); init(); } public BalloonView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public BalloonView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } @SuppressLint("NewApi") protected void init() { // decode the 9patch drawable bg = (NinePatchDrawable) getResources().getDrawable(R.drawable.balloon); // get paddings from the 9patch and apply them to the View bg.getPadding(padding); setPadding(padding.left, padding.top, padding.right, padding.bottom); // prepare the Paint to use below paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.rgb(255,255,255)); paint.setStyle(Style.FILL); // this check is needed in order to get this code // working if target SDK>=11 if( Build.VERSION.SDK_INT >= 11 ) setLayerType(View.LAYER_TYPE_SOFTWARE, paint); // set the shadowLayer paint.setShadowLayer( padding.left * .2f, // radius 0f, // blurX padding.left * .1f, // blurY Color.argb(128, 0, 0, 0) // shadow color ); } @Override protected void onDraw(Canvas canvas) { int w = getMeasuredWidth(); int h = getMeasuredHeight(); // set 9patch bounds according to view measurement // NOTE: if not set, the drawable will not be drawn bg.setBounds(0, 0, w, h); // this code looks expensive: let's do once if( bmp == null ) { // it seems like shadowLayer doesn't take into account // alpha channel in ARGB_8888 sources... bmp = Bitmap.createBitmap(w, h, Config.ARGB_8888); // draw the given 9patch on the brand new bitmap Canvas tmp = new Canvas(bmp); bg.draw(tmp); // extract only the alpha channel bmp = bmp.extractAlpha(); } // this "alpha mask" has the same shape of the starting 9patch, // but filled in white and **with the dropshadow**!!!! canvas.drawBitmap(bmp, 0, 0, paint); // let's paint the 9patch over... bg.draw(canvas); super.onDraw(canvas); } } 

    En primer lugar para conseguir la sombra programática de la gota usted tiene que ocuparse de Paint.setShadowLayer(...) como indicado aquí . Básicamente, debe definir una capa de sombra para el objeto Paint que se utiliza para dibujar en el Canvas de su vista personalizada. Desafortunadamente no puedes usar un objeto Paint para dibujar un NinePatchDrawable, así que necesitas convertirlo en un Bitmap (1st hack). Además, parece que las capas de sombra no pueden funcionar correctamente con las imágenes ARGB_8888, por lo que la única manera que encontré para obtener una sombra adecuada ha sido dibujar la máscara alfa del NinePatchDrawable dado (segundo hack) justo debajo de sí mismo.

    Aquí hay un par de sshots (probado en Android 2.3.3@mdpi y 4.2.2@xhdpi) Introduzca aquí la descripción de la imagenIntroduzca aquí la descripción de la imagen

    Edit: sólo para ser minucioso, adjunto el 9patch utilizado en la prueba (colocado en res/drawable/mdpi ) Introduzca aquí la descripción de la imagen

    Pruebe esta técnica.

    Container_dropshadow.xml

      <!-- Drop Shadow Stack --> <item> <shape> <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <solid android:color="#00CCCCCC" /> </shape> </item> <item> <shape> <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <solid android:color="#10CCCCCC" /> </shape> </item> <item> <shape> <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <solid android:color="#20CCCCCC" /> </shape> </item> <item> <shape> <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <solid android:color="#30CCCCCC" /> </shape> </item> <item> <shape> <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <solid android:color="#50CCCCCC" /> </shape> </item> <!-- Background --> <item> <shape> <solid android:color="@color/white" /> <corners android:radius="3dp" /> </shape> </item> 

    A continuación, puede aplicarlo a un diseño XML como fondo, como

    LinearLayout android: background = "@ drawable / container_dropshadow"

    Esta es la forma más simple de dejar caer la sombra a cualquier cosa ya sea de diseño, botón, etc background.xml

      <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item > <shape android:shape="rectangle"> <solid android:color="@android:color/darker_gray" /> <corners android:radius="5dp"/> </shape> </item> <item android:right="1dp" android:left="1dp" android:bottom="2dp"> <shape android:shape="rectangle"> <solid android:color="@android:color/white"/> <corners android:radius="5dp"/> </shape> </item> </layer-list> 

    En tu main.xml

     <LineaLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/background" /> 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.