validar studio from android xml image layout

studio - imageview xamarin android



¿Cómo hacer el diseño con esquinas redondeadas..? (16)

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


1: Definir layout_bg.xml en drawables :

<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#FFFFFF"/> <stroke android:width="3dp" android:color="#B1BCBE" /> <corners android:radius="10dp"/> <padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" /> </shape>

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

android:background="@drawable/layout_bg"


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

<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#ffffffff"/> <stroke android:width="3dp" android:color="#ff000000" /> <padding android:left="1dp" android:top="1dp" android:right="1dp" android:bottom="1dp" /> <corners android:bottomRightRadius="7dp" android:bottomLeftRadius="7dp" android:topLeftRadius="7dp" android:topRightRadius="7dp"/> </shape>

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


Crea tu xml en drawable, layout_background.xml

<solid android:color="@color/your_colour" /> <stroke android:width="2dp" android:color="@color/your_colour" /> <corners android:radius="10dp" /> </shape>

<- el ancho, el color, el radio deben ser de acuerdo con sus requisitos ->

Finalmente en tu archivo layout.xml escribe debajo de la línea

android:background="@drawable/layout_background"


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

  1. haga un mapa de bits del diseño, como se muestra here .

  2. haz un dibujo redondeado desde el mapa de bits, como se muestra here

  3. establece el dibujable en una imageView.

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

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

La única forma mejor de hacerlo 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); } }

EDIT: encontré una buena alternativa, basada en la biblioteca "RoundKornersLayouts" . Tenga una clase que se utilizará para todas las clases de diseño que desee ampliar, para redondear:

//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.restoreToCount(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:

<resources> <declare-styleable name="RoundedCornersView"> <attr name="corner_radius" format="dimension"/> <attr name="corner_stroke_width" format="dimension"/> <attr name="corner_stroke_color" format="color"/> </declare-styleable> </resources>

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 del trazo y la elevación.

Ejemplo:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" android:clipToPadding="false" tools:context=".MainActivity"> <com.google.android.material.card.MaterialCardView android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center" app:cardCornerRadius="8dp" app:cardElevation="8dp" app:strokeColor="#f00" app:strokeWidth="2dp"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:background="#0f0"/> </com.google.android.material.card.MaterialCardView> </FrameLayout>

Y el resultado:

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. Puede notarlo si hace zoom. He informado sobre este problema here .


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

android:background="@drawable/card_background"

Agregue esto a su directorio dibujable y llámelo card_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="#BDBDBD"/> <corners android:radius="5dp"/> </shape> </item> <item android:left="0dp" android:right="0dp" android:top="0dp" android:bottom="2dp"> <shape android:shape="rectangle"> <solid android:color="#ffffff"/> <corners android:radius="5dp"/> </shape> </item> </layer-list>


Función para establecer el radio de la esquina programáticamente

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);


He hecho de esta manera:

Compruebe la captura de pantalla:

Cree el archivo custom_rectangle.xml nombrado con custom_rectangle.xml en la carpeta custom_rectangle.xml :

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="@android:color/white" /> <corners android:radius="10dip" /> <stroke android:width="1dp" android:color="@android:color/white" /> </shape>

Ahora aplique el fondo del rectángulo en la vista :

mView.setBackground(R.drawlable.custom_rectangle);

Hecho


Prueba esto...

1.create un xml dibujable (custom_layout.xml):

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <solid android:color="#FFFFFF" /> <stroke android:width="2dp" android:color="#FF785C" /> <corners android:radius="10dp" /> </shape>

2.add su vista de fondo

android:background="@drawable/custom_layout"


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

<android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" card_view:cardCornerRadius="5dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight=".3" android:text="@string/quote_code" android:textColor="@color/white" android:textSize="@dimen/text_head_size" /> </LinearLayout> </android.support.v7.widget.CardView>

Con esta card_view: cardCornerRadius = "5dp", puedes cambiar el radio.


Tomé la respuesta de @gauravsapiens con mis comentarios en el interior para darle una comprensión razonable de lo que afectarán los parámetros.

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Background color --> <solid android:color="@color/white" /> <!-- Stroke around the background, width and color --> <stroke android:width="4dp" android:color="@color/drop_shadow"/> <!-- The corners of the shape --> <corners android:radius="4dp"/> <!-- Padding for the background, e.g the Text inside a TextView will be located differently --> <padding android:left="10dp" android:right="10dp" android:bottom="10dp" android:top="10dp" /> </shape>

Si solo busca crear una forma que redondee las esquinas, eliminar el relleno y el trazo serán suficientes. Si elimina el sólido, en efecto, habrá creado esquinas redondeadas sobre un fondo transparente.

Para ser perezoso, he creado una forma debajo, que es solo un fondo blanco sólido con esquinas redondeadas, ¡disfrútalo! :)

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Background color --> <solid android:color="@color/white" /> <!-- The corners of the shape --> <corners android:radius="4dp"/> </shape>


Una mejor manera de hacerlo sería:

background_activity.xml

<?xml version="1.0" encoding="UTF-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:gravity="fill"> <color android:color="@color/black"/> </item> <item> <shape android:gravity="fill"> <solid android:color="@color/white"/> <corners android:radius="10dip"/> <padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" /> </shape> </item> </layer-list>

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

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


Utilice 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 establecido, podría recortar subvistas con éxito.

<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" card_view:cardBackgroundColor="@android:color/transparent" card_view:cardCornerRadius="5dp" card_view:cardElevation="0dp" card_view:contentPadding="0dp"> <YOUR_LINEARLAYOUT_HERE> </android.support.v7.widget.CardView>


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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" card_view:cardCornerRadius="5dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="15dp" android:weightSum="1"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight=".3" android:text="@string/quote_code" android:textColor="@color/white" android:textSize="@dimen/text_head_size" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight=".7" android:text="@string/quote_details" android:textColor="@color/white" android:textSize="@dimen/text_head_size" /> </LinearLayout> </android.support.v7.widget.CardView> </LinearLayout>


Para API 21+, usar 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 reference 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 el recorte adecuado.

Esto es lo que debe hacer:

  • Cree una forma redondeada android:background="@drawable/round_outline" como fondo de su vista: android:background="@drawable/round_outline"
  • De acuerdo con 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)

Lo que parece:

Nota especial sobre ImageViews

setClipToOutline() solo funciona cuando el fondo de la Vista se establece en una forma dibujable. Si existe esta forma de fondo, la vista 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 background se usa para la forma redondeada). Si DEBE usar el fondo para configurar su imagen en lugar de src, puede usar esta solución de vista anidada:

  • Cree un diseño exterior con su fondo configurado a su forma dibujable
  • Envuelva ese diseño alrededor de su ImageView (sin relleno)
  • El ImageView (incluyendo cualquier otra cosa en el diseño) ahora se recortará a la forma redondeada del diseño exterior.

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:padding="@dimen/_10sdp" android:shape="rectangle"> <solid android:color="@color/header" /> <corners android:bottomLeftRadius="@dimen/_5sdp" android:bottomRightRadius="@dimen/_5sdp" android:topLeftRadius="@dimen/_5sdp" android:topRightRadius="@dimen/_5sdp" />


<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#FFFFFF"/> <stroke android:width="3dip" android:color="#B1BCBE" /> <corners android:radius="10dip"/> <padding android:left="3dip" android:top="3dip" android:right="3dip" android:bottom="3dip" /> </shape>

@David, simplemente coloque el mismo valor de relleno que el trazo, para que el borde pueda ser visible, sin importar el tamaño de la imagen