• Android实现圆形图片


    一.概述

    圆形图片现在越来越多应用于Android应用中, 但是用的最多的地方当属于, 头像的显示. 比如QQ, 新浪微博,微信中很多地方都是用了圆形头像,所以有必要深究一下.

    二.圆形图片的实现方式

    1.使用自定义控件

    2.使用第三方库

    下面先说第1种, 自定义控件

    package com.example.kun.widget;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.Config;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.PorterDuff;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.RectF;
    import android.util.AttributeSet;
    import android.widget.ImageView;
    
    import com.example.kun.R;
    
    /**
     * 自定义圆形图片
     */
    public class RoundAngleImageView extends ImageView {
        //定义2个画笔
        private Paint paint;
        private Paint paint2;
        private int roundWidth = 5;
        private int roundHeight = 5;
        //以下是必须实现的构造方法
        public RoundAngleImageView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(context, attrs);
        }
    
        public RoundAngleImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context, attrs);
        }
    
        public RoundAngleImageView(Context context) {
            super(context);
            init(context, null);
        }
    
        private void init(Context context, AttributeSet attrs) {
            if (attrs != null) {
                TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundAngleImageView);
                //根据像素赋值
                roundWidth = a.getDimensionPixelSize(R.styleable.RoundAngleImageView_roundWidth, roundWidth);
                roundHeight = a.getDimensionPixelSize(R.styleable.RoundAngleImageView_roundHeight, roundHeight);
            } else {
                //根据设备密度计算
                float density = context.getResources().getDisplayMetrics().density;
                roundWidth = (int) (roundWidth * density);
                roundHeight = (int) (roundHeight * density);
            }
    
            paint = new Paint();
            paint.setColor(Color.WHITE);
            paint.setAntiAlias(true);//设置图片抗锯齿,就是设置图片边缘锯齿感 不明显
            //设置2张图片相交的模式, 圆形覆盖 方形
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
    
            paint2 = new Paint();
            paint2.setXfermode(null);
        }
    
        @Override
        public void draw(Canvas canvas) {
            Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
            Canvas canvas2 = new Canvas(bitmap);
            super.draw(canvas2);
            drawLiftUp(canvas2);
            drawRightUp(canvas2);
            drawLiftDown(canvas2);
            drawRightDown(canvas2);
            canvas.drawBitmap(bitmap, 0, 0, paint2);
            bitmap.recycle();
        }
    
        private void drawLiftUp(Canvas canvas) {
            Path path = new Path();
            path.moveTo(0, roundHeight);
            path.lineTo(0, 0);
            path.lineTo(roundWidth, 0);
            path.arcTo(new RectF(
                            0,
                            0,
                            roundWidth * 2,
                            roundHeight * 2),
                    -90,
                    -90);
            path.close();
            canvas.drawPath(path, paint);
        }
    
        private void drawLiftDown(Canvas canvas) {
            Path path = new Path();
            path.moveTo(0, getHeight() - roundHeight);
            path.lineTo(0, getHeight());
            path.lineTo(roundWidth, getHeight());
            path.arcTo(new RectF(
                            0,
                            getHeight() - roundHeight * 2,
                            0 + roundWidth * 2,
                            getHeight()),
                    90,
                    90);
            path.close();
            canvas.drawPath(path, paint);
        }
    
        private void drawRightDown(Canvas canvas) {
            Path path = new Path();
            path.moveTo(getWidth() - roundWidth, getHeight());
            path.lineTo(getWidth(), getHeight());
            path.lineTo(getWidth(), getHeight() - roundHeight);
            path.arcTo(new RectF(
                    getWidth() - roundWidth * 2,
                    getHeight() - roundHeight * 2,
                    getWidth(),
                    getHeight()), 0, 90);
            path.close();
            canvas.drawPath(path, paint);
        }
    
        private void drawRightUp(Canvas canvas) {
            Path path = new Path();
            path.moveTo(getWidth(), roundHeight);
            path.lineTo(getWidth(), 0);
            path.lineTo(getWidth() - roundWidth, 0);
            path.arcTo(new RectF(
                            getWidth() - roundWidth * 2,
                            0,
                            getWidth(),
                            0 + roundHeight * 2),
                    -90,
                    90);
            path.close();
            canvas.drawPath(path, paint);
        }
    }

    对应的attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="RoundAngleImageView">
            <attr name="roundWidth" format="dimension" />
            <attr name="roundHeight" format="dimension" />
        </declare-styleable>
    </resources>

    布局文件:

    <com.example.kun.widget.RoundAngleImageView
            android:id="@+id/photoView"
            android:src="@mipmap/temp"
            app:roundHeight="100dp"
            app:roundWidth="100dp"
            android:scaleType="fitXY"
            android:layout_width="200dp"
            android:layout_height="200dp" />

    布局需要注意: 自定义属性必须要有,并且宽高必须为 layout_width和layout_height的一半

    还有一点注意:

    android:scaleType="fitXY"这个属性必须要有,否则不会实现图片圆形

    java代码如下:

    public class MainActivity extends AppCompatActivity {
        private RoundAngleImageView photoView;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initialize();
        }
    
        private void initialize() {
            photoView = (RoundAngleImageView) findViewById(R.id.photoView);
        }
    }

    运行效果图:

    以上的自定义控件多少还是有些麻烦的 ,下面搞一个稍微简单点的工具类

    public class CircleTransform extends BitmapTransformation {
        public CircleTransform(Context context) {
            super(context);
        }
    
        @Override
        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
            return circleCrop(pool, toTransform);
        }
    
        private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
            if (source == null) return null;
    
            int size = Math.min(source.getWidth(), source.getHeight());
            int x = (source.getWidth() - size) / 2;
            int y = (source.getHeight() - size) / 2;
    
            Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
    
            Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
            if (result == null) {
                result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
            }
    
            Canvas canvas = new Canvas(result);
            Paint paint = new Paint();
            paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
            paint.setAntiAlias(true);
            float r = size / 2f;
            canvas.drawCircle(r, r, r, paint);
            return result;
        }
    
        @Override
        public String getId() {
            return getClass().getName();
        }
    }

    布局如下:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:gravity="center"
        android:layout_height="match_parent">
    
        <ImageView
            android:scaleType="fitXY"
            android:id="@+id/photoView"
            android:layout_width="100dp"
            android:layout_height="100dp" />
    </LinearLayout>

    java代码:

    public class MainActivity extends AppCompatActivity {
        private ImageView photoView;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initialize();
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Glide.with(MainActivity.this).load(Uri.parse("http://pic13.nipic.com/20110415/1347158_132411659346_2.jpg"))
                            .transform(new CircleTransform(MainActivity.this))
                            .placeholder(R.mipmap.ic_launcher)
                            .error(R.mipmap.ic_launcher)
                            .into(photoView);
                }
            });
        }
        private void initialize() {
            photoView = (ImageView) findViewById(R.id.photoView);
        }
    }

    以上代码使用GLide加载图片,需要引入glide库

    运行截图:

    分割线---------------------------------------------------------------------------------------------------------------------

    以上方式虽然能实现图片圆形化,但是都是比较麻烦的,下面介绍一种我最常用的,也是最简单的一个方法

    CircleImageView 

    github:https://github.com/hdodenhof/CircleImageView

    直接上代码

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:gravity="center"
        android:layout_height="match_parent">
    
        <!--加入了边框宽度和颜色-->
        <de.hdodenhof.circleimageview.CircleImageView
            app:civ_border_width="2dp"
            app:civ_border_color="#FFFFFF"
            android:id="@+id/photoView"
            android:src="@mipmap/ic_launcher"
            android:layout_width="100dp"
            android:layout_height="100dp" />
    </LinearLayout>
    public class MainActivity extends AppCompatActivity {
        private CircleImageView photoView;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initialize();
            Picasso.with(this).load(R.mipmap.temp).into(photoView);
        }
    
        private void initialize() {
            photoView = (CircleImageView) findViewById(R.id.photoView);
        }
    }

    引入的库文件

    compile 'de.hdodenhof:circleimageview:2.0.0'
    compile 'com.squareup.picasso:picasso:2.5.2'
    运行截图:最外层带有一个白色边框

    
    
  • 相关阅读:
    C# 复制文件夹,移动文件夹
    让Base64适合在URL中使用
    修复FIREBIRD数据库
    Image.FromFile 锁文件的解决办法
    Powerbuilder 12.5 下载地址
    C# 给程序添加许可
    WIN FORM 多线程更新UI(界面控件)
    .Net WinForm 拖动控件
    SQL Server 自动增长清零
    C# 一次生成多个相同的字符
  • 原文地址:https://www.cnblogs.com/android-zcq/p/5138462.html
Copyright © 2020-2023  润新知