it-swarm.dev

Jak udělat rozložení se zaoblenými rohy ..?

Jak mohu vytvořit rozložení se zaoblenými rohy? Chci použít zaoblené rohy na můj LinearLayout.

421
Addy

1: Definice layout_bg.xml v zásuvkách:

<?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: Přidejte layout_bg.xml jako pozadí do rozvržení

Android:background="@drawable/layout_bg"
870
Gaurav Arora

Pro rozhraní API 21+, použijte zobrazení klipů

Do třídy View v API 21 bylo přidáno zaokrouhlené ořezové oříznutí. Pro více informací si přečtěte toto školení doc nebo toto odkaz .

Tato vestavěná funkce usnadňuje implementaci zaoblených rohů. Pracuje na jakémkoli pohledu nebo rozložení a podporuje správné oříznutí.

Co dělat:

  • Vytvořte zakulacený tvar a nastavte ho jako pozadí zobrazení: Android:background="@drawable/round_outline"
  • Podle dokumentace pak stačí vše: Android:clipToOutline="true"

Bohužel se zdá, že chyba a tento atribut XML není v současné době rozpoznán. Naštěstí můžeme nastavit výstřižek v jazyce Java:

  • Ve vaší aktivitě nebo fragmentu: View.setClipToOutline(true)

Jak to vypadá:

enter image description here

Zvláštní poznámka o ImageViews

setClipToOutline() funguje pouze tehdy, když je pozadí zobrazení nastaveno na nakreslený tvar. Pokud tento tvar pozadí existuje, View považuje obrys pozadí za ohraničení pro účely oříznutí a stínování.

To znamená, že pokud chcete zaokrouhlit rohy na ImageView s setClipToOutline(), musí váš obrázek pocházet z Android:src namísto Android:background (protože pozadí se používá pro zakulacený tvar). Pokud chcete nastavit obrázek namísto src, musíte použít toto řešení vnořených pohledů:

  • Vytvořte vnější rozvržení s pozadím nastaveným do tvaru, který bude možné nakreslit
  • Zabalte toto rozvržení kolem ImageView (bez paddingu)
  • ImageView (včetně všeho jiného v rozvržení) bude nyní oříznut do zaobleného tvaru vnějšího rozložení.
85
hungryghost

Zde je kopie souboru XML, který vytvoří kreslicí plochu s bílým pozadím, černým okrajem a zaoblenými rohy:

 <?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>

uložte jej jako soubor xml do adresáře s možností kreslení, použijte jej jako byste použili jakýkoli obrázek na pozadí (ikonu nebo soubor prostředků) pomocí názvu zdroje (R.drawable.your_xml_name)

56
kyogs

Udělal jsem to takto:

Zkontrolovat snímek obrazovky:

 Relative layout Background

Vytvořit drawable soubor pojmenovaný custom_rectangle.xml in drawable folder:

<?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>

Použít Rectangle pozadí on Zobrazit :

mView.setBackground(R.drawlable.custom_rectangle);

Hotovo

25
Hiren Patel

Použijte CardView v Android v7 knihovně podpory. Ačkoli je to trochu těžké, řeší všechny problémy a je to snadné. Ne jako nastavená metoda kreslení pozadí, mohla úspěšně podvázat podřízené stránky.

<?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>
24
Evan JIANG

Myslím, že lepší způsob, jak to udělat, je sloučit 2 věci:

  1. vytvořte bitmapu rozvržení, jak je zobrazeno zde .

  2. udělejte z bitmapy zaokrouhlovatelnou kresbu, jak je zobrazeno zde

  3. nastavit kreslení na imageView.

To bude řešit případy, které se nepodařilo vyřešit jinými řešeními, jako je například obsah, který má rohy.

Myslím, že je to také o něco více GPU-přátelský, protože ukazuje jednu vrstvu místo 2.

Jediný lepší způsob je vytvořit zcela přizpůsobený pohled, ale je to spousta kódu a může to trvat hodně času. Myslím, že to, co jsem zde navrhl, je nejlepší z obou světů.

Zde je ukázka toho, jak to lze udělat:

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: našel alternativu Nice, založenou na knihovně "RoundKornersLayouts" . Mít třídu, která bude použita pro všechny třídy rozvržení, které chcete rozšířit, zaokrouhlit:

//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()
    }

}

Pak v každé z vašich vlastních tříd rozvržení přidejte kód podobný tomuto:

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

}

Pokud chcete podporovat atributy, použijte tento postup v knihovně:

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

Další alternativa, která může být pro většinu použití snadnější: použití MaterialCardView. Umožňuje přizpůsobit zaoblené rohy, barvu a šířku tahu a výšku.

Příklad:

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

A výsledek:

 enter image description here

Všimněte si, že na okrajích tahu je malý problém s artefakty (ponechá tam nějaké pixely obsahu), pokud jej používáte. Můžete si to všimnout, pokud přiblížíte. O tomto problému jsem informoval zde .

20

Zkuste to...

1.vytvoření kreslení 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.add pozadí zobrazení

Android:background="@drawable/custom_layout"
10

Lepší způsob, jak to udělat, by bylo:

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>

To bude fungovat i pod API 21 a dá vám něco takového:

 Result


Pokud jste ochotni udělat o něco více úsilí lépe, pak použijte Android.support.v7.widget.CardView s jeho atributem cardCornerRadius (a nastavte elevation atribut na 0dp, abyste se zbavili jakýchkoliv doprovodných stínů s kartouView). Také to bude fungovat od úrovně API až 15.

5
Abdul Wasae

Pokud byste chtěli, aby vaše rozložení zaokrouhlené, je nejlepší použít CardView, poskytl mnoho funkcí, aby design krásný.

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

S tímto card_view: cardCornerRadius = "5dp" můžete změnit poloměr.

5
Farruh Habibullaev

Použijte CardView, abyste získali zaoblené hrany pro všechna rozvržení. Použijte card_view: cardCornerRadius = "5dp" pro zobrazení karty zaokrouhlenými hranami.

<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>
4
vishnuc156
<?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, stačí dát polstrování stejnou hodnotu jako mrtvice, takže hranice mohou být viditelné, bez ohledu na velikost obrázku

3
escar

Nejlepší a nejjednodušší metodou by bylo použití card_background drawable ve vašem rozvržení. To také odpovídá směrnicím společnosti Google o konstrukci materiálu. Stačí to zahrnout do LinearLayout:

Android:background="@drawable/card_background"

Přidejte ji do svého adresáře s názvem a pojmenujte ho 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>
3

Programově programovaná funkce pro nastavený poloměr rohu

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

Použitím

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

view.setBackground(gradientDrawable);
3
Phan Van Linh

Vzal jsem @gauravsapiens odpověď s mými komentáři dovnitř, abych vám rozumné obavy o tom, co parametry ovlivní.

<?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>

Pokud hledáte jen vytvořit tvar, který zaokrouhluje rohy, odstraní se polstrování a tah. Pokud odstraníte i pevné, budete mít ve skutečnosti vytvořené zaoblené rohy na průhledném pozadí.

Abych byl líný, vytvořil jsem pod ním tvar, který je jen pevným bílým pozadím se zaoblenými rohy - užijte si to! :)

<?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>
1
ZooMagic
Create your xml in drawable, layout_background.xml

 <?xml version="1.0" encoding="utf-8"?>
        <shape xmlns:Android="http://schemas.Android.com/apk/res/Android" >
        <solid Android:color="@color/your_colour" />
        <stroke
            Android:width="2dp"
            Android:color="@color/your_colour" />
        <corners Android:radius="10dp" />      
        </shape>
 <--width, color, radius should be as per your requirement-->

Finally in your layout.xml file write below line

 Android:background="@drawable/layout_background"
0
Bapusaheb Shinde
 <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" />
0
keval patel