Comment faire la disposition avec des coins arrondis..?
Comment puis-je faire une mise en page avec des coins arrondis? Je veux appliquer des coins arrondis à mon LinearLayout
.
16 réponses
1: Définir layout_bg.xml dans 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: Ajouter layout_bg.xml
comme arrière-plan à votre mise en page
android:background="@drawable/layout_bg"
pour API 21+ , utilisez les vues de Clip
La coupure de contour arrondi a été ajoutée à la classe View
de L'API 21. Voir ce formation doc ou ce référence pour plus d'informations.
cette caractéristique intégrée rend les coins arrondis très faciles à mettre en œuvre. Il fonctionne sur n'importe quelle vue ou layout et soutient la coupure appropriée.
voici ce Qu'il faut faire:
- créez une forme arrondie dessinable et mettez-la comme arrière-plan de votre vue:
android:background="@drawable/round_outline"
- selon la documentation, alors tout ce que vous devez faire est ceci:
android:clipToOutline="true"
malheureusement, il semble y avoir un bug et cet attribut XML n'est pas reconnu actuellement. Heureusement, nous pouvons mettre la coupure en Java:
- In votre activité ou fragment:
View.setClipToOutline(true)
À Quoi Il Ressemble:
Note Spéciale Sur ImageViews
setClipToOutline()
ne fonctionne que lorsque le fond de la vue est réglé sur une forme pouvant être dessinée. Si cette forme d'arrière-plan existe, View traite le contour de l'arrière-plan comme les frontières pour découper et shadowing but.
cela signifie que si vous voulez arrondir les coins sur une ImageView avec setClipToOutline()
, votre image doit venir de android:src
au lieu de android:background
(puisque l'arrière-plan est utilisé pour la forme arrondie). Si vous devez utiliser l'arrière-plan pour définir votre image au lieu de src, vous pouvez utiliser ce contournement de vues emboîtées:
- créer une disposition extérieure avec son arrière-plan réglé à votre forme dessinable
- envelopper cette disposition autour de votre ImageView (sans rembourrage)
- L'ImageView (y compris tout ce qui est dans la mise en page) sera maintenant clippé sur la forme arrondie de la mise en page extérieure.
voici une copie D'un fichier XML pour créer un dessin avec un fond blanc, un bord noir et des coins arrondis:
<?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>
enregistrer en tant que fichier xml dans le répertoire drawable, Utilisez - le comme si vous utilisiez n'importe quel arrière-plan dessinable(icône ou fichier ressource) en utilisant son nom de ressource (R. drawable.your_xml_name)
j'ai fait de cette façon:
Vérifier La Capture D'Écran:
Créer drawable fichier nommé avec custom_rectangle.xml
dans drawable dossier:
<?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>
Maintenant appliquer Rectangle de fond sur Vue :
mView.setBackground(R.drawlable.custom_rectangle);
fait
utilisez CardView dans la bibliothèque d'assistance V7 android. Si c'est un peu lourd, il résout tout problème, et assez facile. Pas comme la méthode set drawable background, elle pourrait Clipper des sous-vues avec succès.
<?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>
je pense qu'une meilleure façon de le faire est de fusionner deux choses:
-
faites un bitmap de la disposition, comme indiqué ici .
-
faites un dessin arrondi à partir du bitmap, comme indiqué ici
-
définit le drawable sur un imageView.
cela permettra de traiter les cas que d'autres solutions n'ont pas réussi à résoudre, comme avoir un contenu qui a des coins.
je pense que C'est aussi un peu plus convivial GPU, car il montre une seule couche au lieu de 2 .
La seule meilleure façon est de faire une totalement personnalisé en vue, mais c'est beaucoup de code et peut prendre beaucoup de temps. Je pense que ce que j'ai suggéré ici est le meilleur des deux mondes.
Voici un extrait de comment cela peut être fait:
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: trouvé une belle alternative, basée sur les "RoundKornersLayouts" bibliothèque . Avoir une classe qui sera utilisée pour toutes les classes de layout vous souhaitez prolonger, pour être arrondi:
//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()
}
}
puis, dans chacune de vos classes de mise en page personnalisées, ajoutez un code similaire à celui-ci:
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 vous souhaitez prendre en charge des attributs, utilisez ceci comme écrit sur la bibliothèque:
<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>
une autre alternative, qui pourrait être plus facile pour la plupart des utilisations: utiliser Matérialcardview . Il permet de personnaliser les coins arrondis, la couleur de course et la largeur, et l'élévation.
exemple:
<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>
et le résultat:
notez Qu'il y a un léger problème d'artefacts aux bords de la touche (laisse quelques pixels du contenu là), si vous l'utilisez. Vous pouvez le remarquer si vous zoomez. J'ai rapporté à propos de ce numéro ici .
essayez ceci...
1.créer drawable xml (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.ajouter votre vue arrière-plan
android:background="@drawable/custom_layout"
Une meilleure façon de le faire serait:
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>
cela fonctionnera aussi sous API 21, et vous donnera quelque chose comme ceci:
si vous êtes prêt à faire un peu plus d'effort pour mieux contrôler, puis utilisez android.support.v7.widget.CardView
avec son attribut cardCornerRadius
(et mettez elevation
attribut à 0dp
pour se débarrasser de n'importe quelle ombre de goutte d'accompagnement avec la cardView). De plus, cela fonctionnera à partir D'un niveau D'API aussi bas que 15.
utilisez CardView pour obtenir des bords arrondis pour toutes les mises en page. Utilisez card_view: cardCornerRadius=" 5dp " pour cardview pour obtenir les contours arrondis.
<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>
<?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, il suffit de mettre le rembourrage de la même valeur que la course, de sorte que la bordure peut être visible, sans égard à la taille de l'image
la meilleure et la plus simple méthode serait de faire usage de card_background drawable in your layout. Cela suit également les lignes directrices de Google en matière de conception de matériel. Il suffit de l'inclure dans votre paiement en ligne:
android:background="@drawable/card_background"
ajoutez ceci à votre répertoire et nommez-le 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>
fonction pour le rayon de coin réglé programmatically
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);
}
utilisant
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setColor(Color.GREEN);
setCornerRadius(gradientDrawable, 20f);
//or setCornerRadius(gradientDrawable, 20f, 40f, 60f, 80f);
view.setBackground(gradientDrawable);
Si vous souhaitez faire votre mise en page arrondis, il est préférable d'utiliser le CardView, il a fourni de nombreuses fonctionnalités pour rendre le design magnifique.
<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>
avec ce card_view:cardCornerRadius=" 5dp", vous pouvez changer le rayon.
créez votre xml dans drawable, layout_background.xml
<solid android:color="@color/your_colour" />
<stroke
android:width="2dp"
android:color="@color/your_colour" />
<corners android:radius="10dp" />
</shape>
<-- largeur,la couleur,le rayon doit être selon votre condition-->
enfin dans votre mise en page.inscrire le fichier xml sous la ligne
android:background="@drawable/layout_background"
<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" />
j'ai pris la réponse @gauravsapiens avec mes commentaires à l'intérieur pour vous donner une appréhension raisonnable de ce que les paramètres vont affecter.
<?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 vous êtes juste à la recherche de créer une forme qui fait le tour des coins, en enlevant le rembourrage et la course fera l'affaire. Si vous retirez aussi le solide, vous aurez, en effet, créé des coins arrondis sur un fond transparent.
pour être paresseux j'ai créé une forme en dessous, qui est juste un fond blanc avec des coins arrondis - profitez-en! :)
<?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>