xml 圆角布局,圆角为特定角

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了xml 圆角布局,圆角为特定角相关的知识,希望对你有一定的参考价值。

package com.abdelmeged.ahmed.roundedlayout;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;

import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;

public class MainActivity extends AppCompatActivity {

    ImageView image;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        image = findViewById(R.id.image_view);

        GlideApp.with(this)
                .load(url)
                .into(image);
    }
}
To make a rounded corner layout or image there is plenty of ways and libraries for this
even you can use the `CardView` attributes to create that

So what is the problem :D . what if you want to make the layout rounded in specific corner
or all corners expect one for example . actually there are familiar solution for this
to make a `XML` file like this

```xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#fff" />
    <corners
        android:bottomLeftRadius="0dp"
        android:bottomRightRadius="0dp"
        android:topLeftRadius="12dp"
        android:topRightRadius="12dp" />
</shape>
```

and make it background to this layout and you are done. this solution  will work for the most cases
but what if you try to use **Glide** or **Picasso** to upload the image in imageView in that layout.
the rounded corner is gone because the image override the background  so know you have to solutions

1- To make a custom transformation and pass the image to it but this solution if your images are have different sizes the rounded corner won't be equal in each view.

2-You can make a custom view as wrapper around your views and give it the exactly corners you want to round . the only problem with that solutions that your memory will increase a little bit.

So that is the code for the custom view that I created you can customize it in other way depend on your use case. you can specify the corner radius for specific corner in xml and in runtime

1- Declare a `styleable` in your `attrs.xml` file and it's name match the view name

2- Decalre the custom view as the code snippet

3- Decalre your xml file

5- but the drawable file also as backgroud also

4- load the images into the view

This the result of snippet code
![Sample](https://i.stack.imgur.com/cvZcD.jpg)

I hope that will be helpfully :D
package com.abdelmeged.ahmed.roundedlayout;

/**
 * Created by ahmed on 9/17/2017.
 */

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;

/**
 * Custom wrapper view to get round corner round view
 */
public class RoundedView extends FrameLayout {

    /**
     * The corners than can be changed
     */
    private float topLeftCornerRadius;
    private float topRightCornerRadius;
    private float bottomLeftCornerRadius;
    private float bottomRightCornerRadius;

    public RoundedView(@NonNull Context context) {
        super(context);
        init(context, null, 0);
    }

    public RoundedView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public RoundedView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs,
                R.styleable.RoundedView, 0, 0);

        //get the default value form the attrs
        topLeftCornerRadius = typedArray.getDimension(R.styleable.
                RoundedView_topLeftCornerRadius, 0);
        topRightCornerRadius = typedArray.getDimension(R.styleable.
                RoundedView_topRightCornerRadius, 0);
        bottomLeftCornerRadius = typedArray.getDimension(R.styleable.
                RoundedView_bottomLeftCornerRadius, 0);
        bottomRightCornerRadius = typedArray.getDimension(R.styleable.
                RoundedView_bottomRightCornerRadius, 0);

        typedArray.recycle();
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        int count = canvas.save();

        final Path path = new Path();

        float[] cornerDimensions = {
                topLeftCornerRadius, topLeftCornerRadius,
                topRightCornerRadius, topRightCornerRadius,
                bottomRightCornerRadius, bottomRightCornerRadius,
                bottomLeftCornerRadius, bottomLeftCornerRadius};

        path.addRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight())
                , cornerDimensions, Path.Direction.CW);

        canvas.clipPath(path, Region.Op.REPLACE);
        canvas.clipPath(path);

        super.dispatchDraw(canvas);
        canvas.restoreToCount(count);
    }

    public void setTopLeftCornerRadius(float topLeftCornerRadius) {
        this.topLeftCornerRadius = topLeftCornerRadius;
        invalidate();
    }

    public void setTopRightCornerRadius(float topRightCornerRadius) {
        this.topRightCornerRadius = topRightCornerRadius;
        invalidate();
    }

    public void setBottomLeftCornerRadius(float bottomLeftCornerRadius) {
        this.bottomLeftCornerRadius = bottomLeftCornerRadius;
        invalidate();
    }

    public void setBottomRightCornerRadius(float bottomRightCornerRadius) {
        this.bottomRightCornerRadius = bottomRightCornerRadius;
        invalidate();
    }
}
<com.abdelmeged.ahmed.roundedlayout.RoundedView 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="wrap_content"
    app:topLeftCornerRadius="12dp"
    app:topRightCornerRadius="12dp"
    android:background="@drawable/up"
    tools:context="com.abdelmeged.ahmed.roundedlayout.MainActivity">

    <ImageView
        android:layout_width="match_parent"
        android:id="@+id/image_view"
        android:layout_gravity="center"
        android:scaleType="centerCrop"
        android:layout_height="wrap_content" />

</com.abdelmeged.ahmed.roundedlayout.RoundedView>
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RoundedView">
        <attr name="topLeftCornerRadius" format="dimension" />
        <attr name="topRightCornerRadius" format="dimension" />
        <attr name="bottomLeftCornerRadius" format="dimension" />
        <attr name="bottomRightCornerRadius" format="dimension" />
    </declare-styleable>
</resources>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#59dfff" />
    <corners
        android:bottomLeftRadius="0dp"
        android:bottomRightRadius="0dp"
        android:topLeftRadius="12dp"
        android:topRightRadius="12dp" />
</shape>

以上是关于xml 圆角布局,圆角为特定角的主要内容,如果未能解决你的问题,请参考以下文章

将形状设置为 ImageView 背景以获得圆角

如何在iOS上仅在具有清晰颜色的模糊视图底部获得圆角?

Android studio圆角矩形的布局如何设计?

如何在android中使用XML布局为图像视图中的图像制作圆角

android中对Bitmap图片设置任意角为圆角

Android 实现圆角方式