Cómo hacer un diseño con esquinas redondeadas …?

¿Cómo puedo hacer un diseño con esquinas redondeadas? Quiero aplicar esquinas redondeadas a mi LinearLayout .

1: defina layout_bg.xml en objetos dibujables :

        

2: agregue layout_bg.xml como fondo a su diseño

 android:background="@drawable/layout_bg" 

Para API 21+, use vistas de clip

El recorte de contorno redondeado se agregó a la clase View en API 21. Consulte este documento de capacitación o esta referencia para obtener más información.

Esta característica incorporada hace que las esquinas redondeadas sean muy fáciles de implementar. Funciona en cualquier vista o diseño y admite recorte adecuado.

Esto es lo que debe hacer:

  • Crea un dibujable de forma redondeada y configúralo como fondo de tu vista: android:background="@drawable/round_outline"
  • Según la documentación, todo lo que necesitas hacer es esto: android:clipToOutline="true"

Desafortunadamente, parece que hay un error y este atributo XML actualmente no se reconoce. Afortunadamente, podemos establecer el recorte en Java:

  • En su actividad o fragmento: View.setClipToOutline(true)

Cómo se ve:

enter image description here

Nota especial sobre ImageViews

setClipToOutline() solo funciona cuando el fondo de la Vista se establece en una forma dibujable. Si esta forma de fondo existe, View trata el contorno del fondo como los bordes para fines de recorte y sombreado.

Esto significa que si desea redondear las esquinas en un ImageView con setClipToOutline() , su imagen debe provenir de android:src lugar de android:background (ya que el fondo se usa para la forma redondeada). Si DEBE usar el fondo para establecer su imagen en lugar de src, puede usar esta solución anidada de vistas:

  • Crear un diseño externo con su fondo establecido en su forma dibujable
  • Envuelva ese diseño alrededor de su ImageView (sin relleno)
  • El ImageView (incluido todo lo demás en el diseño) ahora se recortará a la forma redondeada del diseño externo.

Aquí hay una copia de un archivo XML para crear un dibujable con un fondo blanco, borde negro y esquinas redondeadas:

         

guárdelo como un archivo xml en el directorio dibujable, utilícelo como si utilizara cualquier fondo dibujable (icono o archivo de recursos) usando su nombre de recurso (R.drawable.your_xml_name)

Lo he hecho de esta manera:

Ver captura de pantalla:

Diseño relativo Fondo

Crea un archivo custom_rectangle.xml nombrado con custom_rectangle.xml en una carpeta custom_rectangle.xml :

       

Ahora aplique el fondo Rectangle en la Vista :

 mView.setBackground(R.drawlable.custom_rectangle); 

Hecho

Use CardView en la biblioteca de soporte de android v7. Aunque es un poco pesado, resuelve todos los problemas, y es bastante fácil. No como el método de fondo dibujable, podría recortar las subvistas con éxito.

     

Creo que una mejor manera de hacerlo es fusionar 2 cosas:

  1. hacer un bitmap del diseño, como se muestra aquí .

  2. hacer un dibujante redondeado desde el bitmap, como se muestra aquí

  3. establece el dibujable en una imageView.

Esto manejará casos que otras soluciones no han podido resolver, como tener contenido con esquinas.

Creo que también es un poco más amigable para GPU, ya que muestra una sola capa en lugar de 2.

La única mejor manera es hacer una vista totalmente personalizada, pero eso es mucho código y puede llevar mucho tiempo. Creo que lo que sugerí aquí es lo mejor de ambos mundos.

Aquí hay un fragmento de cómo se puede hacer:

RoundedCornersDrawable.java

 /** * shows a bitmap as if it had rounded corners. based on : * http://rahulswackyworld.blogspot.co.il/2013/04/android-drawables-with-rounded_7.html * easy alternative from support library: RoundedBitmapDrawableFactory.create( ...) ; */ public class RoundedCornersDrawable extends BitmapDrawable { private final BitmapShader bitmapShader; private final Paint p; private final RectF rect; private final float borderRadius; public RoundedCornersDrawable(final Resources resources, final Bitmap bitmap, final float borderRadius) { super(resources, bitmap); bitmapShader = new BitmapShader(getBitmap(), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); final Bitmap b = getBitmap(); p = getPaint(); p.setAntiAlias(true); p.setShader(bitmapShader); final int w = b.getWidth(), h = b.getHeight(); rect = new RectF(0, 0, w, h); this.borderRadius = borderRadius < 0 ? 0.15f * Math.min(w, h) : borderRadius; } @Override public void draw(final Canvas canvas) { canvas.drawRoundRect(rect, borderRadius, borderRadius, p); } } 

CustomView.java

 public class CustomView extends ImageView { private View mMainContainer; private boolean mIsDirty=false; // TODO for each change of views/content, set mIsDirty to true and call invalidate @Override protected void onDraw(final Canvas canvas) { if (mIsDirty) { mIsDirty = false; drawContent(); return; } super.onDraw(canvas); } /** * draws the view's content to a bitmap. code based on : * http://nadavfima.com/android-snippet-inflate-a-layout-draw-to-a-bitmap/ */ public static Bitmap drawToBitmap(final View viewToDrawFrom, final int width, final int height) { // Create a new bitmap and a new canvas using that bitmap final Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); final Canvas canvas = new Canvas(bmp); viewToDrawFrom.setDrawingCacheEnabled(true); // Supply measurements viewToDrawFrom.measure(MeasureSpec.makeMeasureSpec(canvas.getWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(canvas.getHeight(), MeasureSpec.EXACTLY)); // Apply the measures so the layout would resize before drawing. viewToDrawFrom.layout(0, 0, viewToDrawFrom.getMeasuredWidth(), viewToDrawFrom.getMeasuredHeight()); // and now the bmp object will actually contain the requested layout canvas.drawBitmap(viewToDrawFrom.getDrawingCache(), 0, 0, new Paint()); return bmp; } private void drawContent() { if (getMeasuredWidth() <= 0 || getMeasuredHeight() <= 0) return; final Bitmap bitmap = drawToBitmap(mMainContainer, getMeasuredWidth(), getMeasuredHeight()); final RoundedCornersDrawable drawable = new RoundedCornersDrawable(getResources(), bitmap, 15); setImageDrawable(drawable); } } 

EDITAR: encontró una buena alternativa, basada en la biblioteca "RoundKornersLayouts" . Haga que se redondee una clase que se utilizará para todas las clases de diseño que desea extender:

 //based on https://github.com/JcMinarro/RoundKornerLayouts class CanvasRounder(cornerRadius: Float, cornerStrokeColor: Int = 0, cornerStrokeWidth: Float = 0F) { private val path = android.graphics.Path() private lateinit var rectF: RectF private var strokePaint: Paint? var cornerRadius: Float = cornerRadius set(value) { field = value resetPath() } init { if (cornerStrokeWidth <= 0) strokePaint = null else { strokePaint = Paint() strokePaint!!.style = Paint.Style.STROKE strokePaint!!.isAntiAlias = true strokePaint!!.color = cornerStrokeColor strokePaint!!.strokeWidth = cornerStrokeWidth } } fun round(canvas: Canvas, drawFunction: (Canvas) -> Unit) { val save = canvas.save() canvas.clipPath(path) drawFunction(canvas) if (strokePaint != null) canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, strokePaint) canvas.restreToCount(save) } fun updateSize(currentWidth: Int, currentHeight: Int) { rectF = android.graphics.RectF(0f, 0f, currentWidth.toFloat(), currentHeight.toFloat()) resetPath() } private fun resetPath() { path.reset() path.addRoundRect(rectF, cornerRadius, cornerRadius, Path.Direction.CW) path.close() } } 

Luego, en cada una de sus clases de diseño personalizadas, agregue un código similar a este:

 class RoundedConstraintLayout : ConstraintLayout { private lateinit var canvasRounder: CanvasRounder constructor(context: Context) : super(context) { init(context, null, 0) } constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { init(context, attrs, 0) } constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) { init(context, attrs, defStyle) } private fun init(context: Context, attrs: AttributeSet?, defStyle: Int) { val array = context.obtainStyledAttributes(attrs, R.styleable.RoundedCornersView, 0, 0) val cornerRadius = array.getDimension(R.styleable.RoundedCornersView_corner_radius, 0f) val cornerStrokeColor = array.getColor(R.styleable.RoundedCornersView_corner_stroke_color, 0) val cornerStrokeWidth = array.getDimension(R.styleable.RoundedCornersView_corner_stroke_width, 0f) array.recycle() canvasRounder = CanvasRounder(cornerRadius,cornerStrokeColor,cornerStrokeWidth) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { setLayerType(FrameLayout.LAYER_TYPE_SOFTWARE, null) } } override fun onSizeChanged(currentWidth: Int, currentHeight: Int, oldWidth: Int, oldheight: Int) { super.onSizeChanged(currentWidth, currentHeight, oldWidth, oldheight) canvasRounder.updateSize(currentWidth, currentHeight) } override fun draw(canvas: Canvas) = canvasRounder.round(canvas) { super.draw(canvas) } override fun dispatchDraw(canvas: Canvas) = canvasRounder.round(canvas) { super.dispatchDraw(canvas) } } 

Si desea admitir atributos, use esto como está escrito en la biblioteca:

        

Otra alternativa, que podría ser más fácil para la mayoría de los usos: use MaterialCardView. Permite personalizar las esquinas redondeadas, el color y el ancho, y la elevación del trazo.

Ejemplo:

      

Y el resultado:

enter image description here

Tenga en cuenta que hay un pequeño problema de artefactos en los bordes del trazo (deja algunos píxeles del contenido allí), si lo usa. Puedes notarlo si haces un acercamiento. He informado acerca de este problema aquí .

Prueba esto…

1.createable xml (custom_layout.xml):

       

2.añadir su fondo de vista

 android:background="@drawable/custom_layout" 

Una mejor forma de hacerlo sería:

background_activity.xml

              

Esto funcionará debajo de API 21 también, y le dará algo como esto:

Resultado


Si está dispuesto a hacer un poco más de esfuerzo para controlar mejor, use android.support.v7.widget.CardView con su atributo cardCornerRadius (y establezca el atributo de elevation en 0dp para deshacerse de cualquier sombra paralela con cardView). Además, esto funcionará desde un nivel API tan bajo como 15.

Use CardView para obtener bordes redondeados para cualquier diseño. Use card_view: cardCornerRadius = “5dp” para que cardview obtenga bordes de diseño redondeados.

         
        

@David, simplemente coloque el mismo valor de relleno como un trazo, para que el borde pueda ser visible, independientemente del tamaño de la imagen

El mejor y más simple método sería hacer uso de card_background dibujable en su diseño. Esto también sigue las pautas de diseño de materiales de Google. Solo incluye esto en ti LinearLayout:

 android:background="@drawable/card_background" 

Agregue esto a su directorio dibujable y asígnele el nombre card_background.xml :

                

Función para establecer el radio de la esquina mediante progtwigción

 static void setCornerRadius(GradientDrawable drawable, float topLeft, float topRight, float bottomRight, float bottomLeft) { drawable.setCornerRadii(new float[] { topLeft, topLeft, topRight, topRight, bottomRight, bottomRight, bottomLeft, bottomLeft }); } static void setCornerRadius(GradientDrawable drawable, float radius) { drawable.setCornerRadius(radius); } 

Utilizando

 GradientDrawable gradientDrawable = new GradientDrawable(); gradientDrawable.setColor(Color.GREEN); setCornerRadius(gradientDrawable, 20f); //or setCornerRadius(gradientDrawable, 20f, 40f, 60f, 80f); view.setBackground(gradientDrawable); 

Si desea redondear su diseño, es mejor usar CardView, que ofrece muchas características para que el diseño sea hermoso.

      

Con este card_view: cardCornerRadius = “5dp”, puede cambiar el radio.

crea tu xml en drawable, layout_background.xml

      

<- ancho, color, radio debe ser según su requisito ->

finalmente en su archivo layout.xml escriba debajo de la línea

 android:background="@drawable/layout_background" 
     

He respondido a @gauravsapiens con mis comentarios en el interior para darte una comprensión razonable de los efectos que tendrán los parámetros.

            

Si solo buscas crear una forma que redondee las esquinas, eliminar el relleno y el trazo funcionarán. Si también quita el sólido, en realidad habrá creado esquinas redondeadas sobre un fondo transparente.

Por el simple hecho de ser flojo, he creado una forma debajo, que es solo un sólido fondo blanco con esquinas redondeadas. ¡Disfrútalo! 🙂