上篇文章Android圆形图像的绘制(二)介绍了单人圆形头像的绘制,这篇文章也是圆形头像的最后一篇。多人头像存在的场景有很多,像一些社交软件,只要涉及到群聊的功能,基本上都会存在多人头像。下面介绍多人头像是怎样实现的,最多支持五人。

在进行多人头像绘制的过程中,CircleImageView自定义控件中应该有个列表保存多人头像的相关信息,每个人的信息应该封装为一个bean对象,上篇文章介绍圆形头像涉及到位图和随机图像的展示,所以我们bean对象包含的数据有位图、随机背景、文本,代码如下:

public class CircleImageViewBean {    /**     * 位图     */    private Bitmap bitmap;    /**     * 随机背景     */    private int randomBg;    /**     * 文本信息     */    private String text;    public CircleImageViewBean(Bitmap bitmap, int randomBg, String text) {        this.bitmap = bitmap;        this.randomBg = randomBg;        this.text = text;    }    public int getRandomBg() {        return randomBg;    }    public void setRandomBg(int randomBg) {        this.randomBg = randomBg;    }    public String getText() {        return text;    }    public void setText(String text) {        this.text = text;    }    public Bitmap getBitmap() {        return bitmap;    }    public void setBitmap(Bitmap bitmap) {        this.bitmap = bitmap;    }}
在定义好bean对象后,CircleImageView自定义控件应该为外面提供一个公用的方法,方法如下:

    /**     * 设置多人头像     * @param circleImageViewBeanList     */    public void setImageBitmaps(List circleImageViewBeanList) {        mCircleImageViewBeanList = circleImageViewBeanList;        invalidate();    }
接下来看下onDraw方法的实现,代码如下:

    private static final int MAX = 5;

    protected void onDraw(Canvas canvas) {        //一定要注释掉,否则圆形图像没法生效//        super.onDraw(canvas);        if (mWidth > 0 && mHeight > 0) {//            Bitmap bitmap = createCircleBitmapForSRC_IN(canvas);//            if (bitmap != null) {//                canvas.drawBitmap(bitmap, 0, 0, new Paint());//            }            if (mCircleImageViewBeanList != null && mCircleImageViewBeanList.size() > 0) {                mCount = Math.min(mCircleImageViewBeanList.size(), MAX);                //绘制多人头像                createCircleBitmap(canvas);            }        }    }

 在绘制之前,需要获取当前多人头像为几人头像,最大值为5,状态用mCount变量保存。下面计算每个小圆相对于大圆的缩放比例,缩放比例的获取用到的是基本的三角函数的相关知识,代码如下:   

    public float getScale(int count) {        int angle = getAngle(count);        if (angle == 360) {            return 1f;        }        double cot = getCot(angle);        float scale = (float) (1f / (Math.sqrt(1 + Math.pow(cot, 2)) + 1));        return scale;    }
    private static final int[] sAngleArray = {360, 90, 60, 45, 36};    private int getAngle(int count) {        return count > 0 && count <= sAngleArray.length ? sAngleArray[count - 1] : null;    }
   private double getCot(int angle) {        double radian = Math.toRadians(angle);        double sin = Math.sin(radian);        double cos = Math.cos(radian);        return  cos / sin;    }
下面获取与大圆最顶部相切的小圆的左上角位置,主要是为了方便计算其他小圆的左上角的位置,因为找到这个小圆的对应的位置是在旋转角度为零的位置,如果想得到其他小圆的位置,只需要根据旋转角度,运用三角函数知识就可以得到。最上面小圆左上角位置获取的代码如下:
    public float[] getTopPosition(float radius, float scale) {        float x = radius * (1 - scale);        float y = 0;        return new float[] { x, y };    }

然后,我们获取每个小圆左上角的位置,这里需要知道大圆半径、旋转角度、缩放比例、最上面小圆左上角的位置,旋转角度决定的小头像的摆放位置,它的值定义了一个数据,代码如下:

    private static final float[][] sRotationArray = { new float[] { 360 }, new float[] { 45, -135 },            new float[] { 120, 0, -120 }, new float[] { 45, 135, -135, -45 },            new float[] { 144, 72, 0, -72, -144 }};    public float[] getRotation(int count) {        return count > 0 && count <= sRotationArray.length ? sRotationArray[count - 1] : null;    }  

小头像位置计算的代码如下:

  public float[] getTranslatePosition(float radius, float rotation, float scale, float topX, float topY) {        float smallRadius = radius * (1 - scale);        double radian = Math.toRadians(rotation);        double cos = Math.cos(radian);        double sin = Math.sin(radian);        float x = (float) (topX - smallRadius * sin);        float y = (float) (topY + smallRadius * (1 - cos));        return new float[] { x, y };    }

得到每个小圆左上角的位置后,需要对目标canvas进行相应的平移,为了能准备画出每个小圆展示在哪个位置,在进行变换之前,需要对目标canvas进行状态的保存,防止这里的变换操作,对其他小圆产生影响,代码如下:

    targetCanvas.save();    float[] radianPosition = mPresenter.getTranslatePosition(viewSize / 2, rotation[i], scale, topPosition[0], topPosition[1]);    targetCanvas.translate(radianPosition[0], radianPosition[1]);    targetCanvas.restore();

当canvas移动到具体的位置之后,我们需要获取位图,将其在canvas上绘制出来。先处理位图相关的绘制逻辑,因为位图的宽高,跟视图的宽高肯定是不一致的,此时需要对位图进行相应的缩放操作,这里涉及到两次缩放的逻辑,第一次是位图缩放到大圆的逻辑,第二次是大圆缩放到小圆的逻辑,代码如下:
    int width = bitmap.getWidth();    int height = bitmap.getHeight();    if (width > 0 && height > 0) {        //对位图进行缩放        float scaleX = (float) mWidth / width;        float scaleY = (float) mHeight / height;        Matrix bitmapMatrix = new Matrix();        bitmapMatrix.postScale(scaleX, scaleY);        bitmapMatrix.postConcat(matrix);        newBitmap = Bitmap.createBitmap(bitmap, 0, 0, width,                height, bitmapMatrix, true);    }
随机头像的绘制逻辑跟上篇文章的逻辑基本上是一样的,只是需要注意下,绘制的时候需要在小圆的基础上绘制,需要对字体的大小进行相应的缩放,代码如下:
    int size = (int) (viewSize * scale);    private Bitmap createRandomMaskBitmap(int size, float scale, String text) {        Bitmap output = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);        final Paint paint = new Paint();        paint.setAntiAlias(true);// 抗锯齿        paint.setFilterBitmap(true);        paint.setColor(mBackground);        int center = size / 2;//获取画布的中心位置        //创建canvas对象,绘制随机背景        Canvas canvas = new Canvas(output);        canvas.drawCircle(center, center, center, paint);        //绘制随机背景上的文字        setText(canvas, size, paint, scale, text);        return output;    }
    private void setText(Canvas canvas, int size, Paint paint, float scale, String text) {        Rect targetRect = new Rect(0, 0, size, size);        //设置绘制文本字体的颜色        paint.setColor(Color.WHITE);        //设置绘制文本的大小        paint.setTextSize(mTextSize * scale);        //获取文本展示的居中位置        Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();        int baseline = (targetRect.bottom + targetRect.top - fontMetrics.bottom - fontMetrics.top) / 2;        paint.setTextAlign(Paint.Align.CENTER);        canvas.drawText(text, targetRect.centerX(), baseline, paint);    }

到这里,多人头像已经基本是实现了,效果图如下:


单人头像的展示,跟上篇文章的效果图也是一样的,完整的代码如下:

CircleImageView.java

package com.dylan.circleimageview;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.Rect;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.widget.ImageView;import java.util.ArrayList;import java.util.List;/** * Description * author   Dylan.zhuang * Date:    16/6/30-下午2:43 */public class CircleImageView extends ImageView {    private static final String TAG = "CircleImageView";    private static final int MAX = 5;    private static final float DEFAULT_SCALE = 0.9f;    /**     * 绘制图片的位图     */    private Bitmap mBitmap;    /**     * 圆形图像边框宽度     */    private int mStrokeWidth;    /**     * 圆形图像边框颜色     */    private int mStrokeColor;    /**     * 随机背景文本大小     */    private int mTextSize;    /**     * 随机背景颜色     */    private int mBackground;    /**     * 随机背景要展示的文本     */    private String mText;    /**     * 视图宽度     */    private int mWidth;    /**     * 视图高度     */    private int mHeight;    /**     * 存放多人头像的列表     */    private List mCircleImageViewBeanList;    /**     * 逻辑层     */    private CircleImageViewPresenter mPresenter;    /**     * 记录头像的个数     */    private int mCount;    public CircleImageView(Context context) {        this(context, null);    }    public CircleImageView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        //#5AC3B2        int defaultColor = getResources().getColor(R.color.colorGreen);        //14sp        int defaultTextSize = getResources().getDimensionPixelSize(R.dimen.dimen_default_text_size);        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyleAttr, 0);        mStrokeWidth = typedArray.getDimensionPixelSize(R.styleable.CircleImageView_stroke_width, 0);        mStrokeColor = typedArray.getColor(R.styleable.CircleImageView_stroke_color, defaultColor);        mTextSize = typedArray.getDimensionPixelSize(R.styleable.CircleImageView_text_size, defaultTextSize);        mBackground = typedArray.getColor(R.styleable.CircleImageView_random_backgroud, defaultColor);        mText = typedArray.getString(R.styleable.CircleImageView_text);        //一定要记得回收        typedArray.recycle();        mPresenter = new CircleImageViewPresenter();    }    /**     * 设置边缘宽度     *     * @param width     */    public void setStrokeWidth(int width) {        mStrokeWidth = width;    }    /**     * 设置边缘颜色     *     * @param color     */    public void setStrokeColor(int color) {        mStrokeColor = color;    }    /**     * 设置文本大小     *     * @param textSize     */    public void setTextSize(int textSize) {        mTextSize = textSize;    }    /**     * 设置背景颜色     *     * @param background     */    public void setBackground(int background) {        mBackground = background;    }    /**     * 设置文本     *     * @param text     */    public void setText(String text) {        mText = text;    }    /**     * 绘制随机背景     */    public void drawRandomBackground() {        readyInvalidate(mBitmap, mBackground, mText);    }    /**     * 设置多人头像     * @param circleImageViewBeanList     */    public void setImageBitmaps(List circleImageViewBeanList) {        mCircleImageViewBeanList = circleImageViewBeanList;        invalidate();    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mWidth = w;        mHeight = h;    }    @Override    public void setImageResource(int resId) {        super.setImageResource(resId);        mBitmap = getBitmapFromDrawable(getDrawable());        readyInvalidate(mBitmap, mBackground, mText);    }    @Override    public void setImageDrawable(Drawable drawable) {        super.setImageDrawable(drawable);        mBitmap = getBitmapFromDrawable(drawable);        readyInvalidate(mBitmap, mBackground, mText);    }    @Override    public void setImageBitmap(Bitmap bm) {        super.setImageBitmap(bm);        mBitmap = bm;        readyInvalidate(mBitmap, mBackground, mText);    }    @Override    protected void onDraw(Canvas canvas) {        //一定要注释掉,否则圆形图像没法生效//        super.onDraw(canvas);        if (mWidth > 0 && mHeight > 0) {//            Bitmap bitmap = createCircleBitmapForSRC_IN(canvas);//            if (bitmap != null) {//                canvas.drawBitmap(bitmap, 0, 0, new Paint());//            }            if (mCircleImageViewBeanList != null && mCircleImageViewBeanList.size() > 0) {                mCount = Math.min(mCircleImageViewBeanList.size(), MAX);                //绘制多人头像                createCircleBitmap(canvas);            }        }    }    /**     * 为调用onDraw之前准备数据     * @param bitmap     * @param randomBg     * @param text     */    private void readyInvalidate(Bitmap bitmap, int randomBg, String text) {        if (mCircleImageViewBeanList == null) {            mCircleImageViewBeanList = new ArrayList();        }        mCircleImageViewBeanList.clear();        CircleImageViewBean bean = new CircleImageViewBean(bitmap, randomBg, text);        mCircleImageViewBeanList.add(bean);        invalidate();    }    /**     * 创建圆形位图     * @param targetCanvas     */    private void createCircleBitmap(Canvas targetCanvas) {        //初始化画笔        Paint paint = new Paint();        paint.setAntiAlias(true);        //获取缩放比例        float scale = mPresenter.getScale(mCount);        int viewSize = Math.min(mWidth, mHeight);        //获取与大圆最上面相切小圆的左上角位置,为了方便计算每个圆具体展示在哪个位置        float[] topPosition = mPresenter.getTopPosition(viewSize / 2, scale);        //获取旋转角度        float[] rotation = mPresenter.getRotation(mCount);        Matrix matrix = new Matrix();        matrix.postScale(scale, scale);        for (int i = 0; i < mCount; i++) {            CircleImageViewBean bean = mCircleImageViewBeanList.get(i);             //对canvas进行状态保存,防止被变换引起状态的改变            targetCanvas.save();            float[] radianPosition = mPresenter.getTranslatePosition(viewSize / 2, rotation[i], scale, topPosition[0], topPosition[1]);            targetCanvas.translate(radianPosition[0], radianPosition[1]);            Bitmap scaleBitmap = getScaleBitmap(bean, matrix, viewSize, scale);            if (scaleBitmap == null) {                return;            }            int newSize = Math.min(scaleBitmap.getWidth(), scaleBitmap.getHeight());            int center = newSize / 2;            //画边缘圈            boolean isDrawBorder = drawCircleBorder(targetCanvas, center, paint);            Bitmap circleBitmap = drawCircleBitmap(scaleBitmap, newSize, isDrawBorder);            paint.setStyle(Paint.Style.FILL);            targetCanvas.drawBitmap(circleBitmap, 0, 0, paint);            targetCanvas.restore();        }    }    /**     * 获取缩放后的位图     * @param bean     * @param matrix     * @param viewSize     * @param scale     * @return     */    private Bitmap getScaleBitmap(CircleImageViewBean bean, Matrix matrix, int viewSize, float scale) {        if (bean == null) {            return null;        }        Bitmap newBitmap = null;        Bitmap bitmap = bean.getBitmap();        String text = bean.getText();        if (bitmap != null) {            int width = bitmap.getWidth();            int height = bitmap.getHeight();            if (width > 0 && height > 0) {                //对位图进行缩放                float scaleX = (float) mWidth / width;                float scaleY = (float) mHeight / height;                Matrix bitmapMatrix = new Matrix();                bitmapMatrix.postScale(scaleX, scaleY);                bitmapMatrix.postConcat(matrix);                newBitmap = Bitmap.createBitmap(bitmap, 0, 0, width,                        height, bitmapMatrix, true);            }        } else {            int size = (int) (viewSize * scale);            newBitmap = createRandomMaskBitmap(size, scale, text);        }        return newBitmap;    }    /**     *     * @param newBitmap     * @param newSize     * @param isDrawBorder     * @return     */    private Bitmap drawCircleBitmap(Bitmap newBitmap, int newSize, boolean isDrawBorder) {        Bitmap bitmap = Bitmap.createBitmap(newSize, newSize, Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas(bitmap);        Paint paint = new Paint();        paint.setAntiAlias(true);        int center = newSize / 2;        if (isDrawBorder) {            canvas.scale(DEFAULT_SCALE, DEFAULT_SCALE, center, center);        }        //在矩阵中心画圆,与矩阵的四边相切        canvas.drawCircle(center, center, center, paint);        //设置Xfermode为SRC_IN        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));        //绘制图片        canvas.drawBitmap(newBitmap, 0, 0, paint);        return bitmap;    }    /**     * 创建圆形图像     *     * @param targetCanvas     * @return     */    private Bitmap createCircleBitmapForSRC_IN(Canvas targetCanvas) {        //创建一个和图片大小差不多的正方形矩阵        int size = Math.min(mWidth, mHeight);        Bitmap newBitmap = null;        if (mBitmap != null) {            int width = mBitmap.getWidth();            int height = mBitmap.getHeight();            // 对bitmap进行缩放,缩放到指定view的大小            Matrix matrix = new Matrix();            matrix.postScale((float) mWidth / width, (float) mHeight / height);            newBitmap = Bitmap.createBitmap(mBitmap, 0, 0, width,                    height, matrix, true);        } else {            newBitmap = createRandomMaskBitmap(size, 1.0f, mText);        }        if (newBitmap == null) {            return null;        }        int center = size / 2;        Paint paint = new Paint();        boolean isDrawBorder = drawCircleBorder(targetCanvas, center, paint);        Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas(bitmap);        if (isDrawBorder) {            paint.setColor(Color.WHITE);            paint.setStyle(Paint.Style.FILL);            canvas.scale(DEFAULT_SCALE, DEFAULT_SCALE, center, center);        }        //在矩阵中心画圆,与矩阵的四边相切        canvas.drawCircle(center, center, center, paint);        //设置Xfermode为SRC_IN        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));        //绘制图片        canvas.drawBitmap(newBitmap, 0, 0, paint);        return bitmap;    }    /**     * 获取bitmap     *     * @param drawable     * @return     */    private Bitmap getBitmapFromDrawable(Drawable drawable) {        if (drawable == null) {            return null;        }        if (drawable instanceof BitmapDrawable) {            return ((BitmapDrawable) drawable).getBitmap();        }        try {            Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);            Canvas canvas = new Canvas(bitmap);            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());            drawable.draw(canvas);            return bitmap;        } catch (OutOfMemoryError e) {            return null;        }    }    /**     * 绘制边界圆     *     * @param canvas     * @param size     * @param paint     * @return     */    private boolean drawCircleBorder(Canvas canvas, int size, Paint paint) {        if (mStrokeWidth > 0) {            paint.setAntiAlias(true);            paint.setColor(mStrokeColor);            paint.setStyle(Paint.Style.STROKE);            paint.setStrokeWidth(mStrokeWidth);            canvas.drawCircle(size, size, size - mStrokeWidth, paint);            return true;        }        return false;    }    /**     * 创建随机背景     *     * @param size     * @return     */    private Bitmap createRandomMaskBitmap(int size, float scale, String text) {        Bitmap output = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);        final Paint paint = new Paint();        paint.setAntiAlias(true);// 抗锯齿        paint.setFilterBitmap(true);        paint.setColor(mBackground);        int center = size / 2;//获取画布的中心位置        //创建canvas对象,绘制随机背景        Canvas canvas = new Canvas(output);        canvas.drawCircle(center, center, center, paint);        //绘制随机背景上的文字        setText(canvas, size, paint, scale, text);        return output;    }    /**     * 绘制文本     *     * @param canvas     * @param size     * @param paint     */    private void setText(Canvas canvas, int size, Paint paint, float scale, String text) {        Rect targetRect = new Rect(0, 0, size, size);        //设置绘制文本字体的颜色        paint.setColor(Color.WHITE);        //设置绘制文本的大小        paint.setTextSize(mTextSize * scale);        //获取文本展示的居中位置        Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();        int baseline = (targetRect.bottom + targetRect.top - fontMetrics.bottom - fontMetrics.top) / 2;        paint.setTextAlign(Paint.Align.CENTER);        canvas.drawText(text, targetRect.centerX(), baseline, paint);    }}
CircleImageViewPresenter.java

package com.dylan.circleimageview;/** * Description * author   Dylan.zhuang * Date:    16/7/7-下午2:51 */public class CircleImageViewPresenter {    /**     * 每种头像对应的旋转角度     */    private static final float[][] sRotationArray = { new float[] { 360 }, new float[] { 45, -135 },            new float[] { 120, 0, -120 }, new float[] { 45, 135, -135, -45 },            new float[] { 144, 72, 0, -72, -144 }};    /**     * 经过小圆圆心的两条直线ab,和经过大圆圆心的两条直线cd,a和c垂直,b和d垂直(对两个圆的条件不成立)     * 公式为360/(n*2),n代表小圆个数,分割策略如下     * 基数圆经过每个圆的圆心画直线,1个圆除外;     * 偶数圆经过每个圆的圆心画直线,并在公切线也画直线;     * 分割策略提到的直线都经过大圆圆心     */    private static final int[] sAngleArray = {360, 90, 60, 45, 36};    /**     * 获取旋转角度     * @param count     * @return     */    public float[] getRotation(int count) {        return count > 0 && count <= sRotationArray.length ? sRotationArray[count - 1] : null;    }    /**     * 获取缩放比例     * @param count     * @return     */    public float getScale(int count) {        int angle = getAngle(count);        if (angle == 360) {            return 1f;        }        double cot = getCot(angle);        float scale = (float) (1f / (Math.sqrt(1 + Math.pow(cot, 2)) + 1));        return scale;    }    /**     * 获取最上面圆的左上角的值,方便计算每个圆的位置     * @param radius     * @param scale     * @return     */    public float[] getTopPosition(float radius, float scale) {        float x = radius * (1 - scale);        float y = 0;        return new float[] { x, y };    }    /**     * 获取每个小头像应该平移的距离,找圆心     * @param radius     * @param rotation     * @param scale     * @param topX     * @param topY     * @return     */    public float[] getTranslatePosition(float radius, float rotation, float scale, float topX, float topY) {        float smallRadius = radius * (1 - scale);        double radian = Math.toRadians(rotation);        double cos = Math.cos(radian);        double sin = Math.sin(radian);        float x = (float) (topX - smallRadius * sin);        float y = (float) (topY + smallRadius * (1 - cos));        return new float[] { x, y };    }    /**     * 获取角度     * @param count     * @return     */    private int getAngle(int count) {        return count > 0 && count <= sAngleArray.length ? sAngleArray[count - 1] : null;    }    /**     * 获取cot值     * @param angle     * @return     */    private double getCot(int angle) {        double radian = Math.toRadians(angle);        double sin = Math.sin(radian);        double cos = Math.cos(radian);        return  cos / sin;    }}
MainActivity.java

package com.dylan.circleimageview;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        CircleImageView circleImageView = (CircleImageView) findViewById(R.id.random_icon);        circleImageView.drawRandomBackground();        CircleImageView circleImageView1 = (CircleImageView) findViewById(R.id.random_icon1);        circleImageView1.drawRandomBackground();        List list2 = new ArrayList<>();        List list3 = new ArrayList<>();        List list4 = new ArrayList<>();        List list5 = new ArrayList<>();        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);        CircleImageViewBean bean1 = new CircleImageViewBean(bitmap, -1, "");        CircleImageViewBean bean2 = new CircleImageViewBean(null, R.color.colorGreen, "A");        CircleImageViewBean bean3 = new CircleImageViewBean(bitmap, R.color.colorGreen, "A");        CircleImageViewBean bean4 = new CircleImageViewBean(null, R.color.colorAccent, "B");        CircleImageViewBean bean5 = new CircleImageViewBean(bitmap, R.color.colorGreen, "A");        list2.add(bean1);        list2.add(bean2);        CircleImageView circleImageView2 = (CircleImageView) findViewById(R.id.icon_two);        circleImageView2.setImageBitmaps(list2);        list3.add(bean3);        list3.addAll(list2);        CircleImageView circleImageView3 = (CircleImageView) findViewById(R.id.icon_three);        circleImageView3.setImageBitmaps(list3);        list4.add(bean4);        list4.addAll(list3);        CircleImageView circleImageView4 = (CircleImageView) findViewById(R.id.icon_four);        circleImageView4.setImageBitmaps(list4);        list5.add(bean5);        list5.addAll(list4);        CircleImageView circleImageView5 = (CircleImageView) findViewById(R.id.icon_five);        circleImageView5.setImageBitmaps(list5);    }}
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>                                                                                                
github地址

更多相关文章

  1. Android(安卓)九宫格解锁Demo--Android(安卓)进阶之路
  2. Android(安卓)View的绘制之 从源码了解measure的过程。
  3. android中Bitmap导致的内存溢出
  4. Android(安卓)贝塞尔曲线实现QQ拖拽清除效果
  5. Android(安卓)仪表进度条 自定义View
  6. Android开发-----03-使用Canvas绘制虚线……
  7. Android(安卓)自定义View(三):重写View实现全新控件
  8. 【iOS-cocos2d-X 游戏开发之十六】配置你的Cocos2dx项目编译后的
  9. 乐博Android客户端发布

随机推荐

  1. Toolbar+TabLayout+ViewPager达成Android
  2. android 目录下三种尺寸的 drawable 文件
  3. 仿QQ下拉菜单列表 自定义Spinner
  4. android:Adapter中设置textview字体颜色
  5. Android第三方FloatingActionButton:伴随L
  6. Android(安卓)设置秒开全屏启动屏
  7. 完美解决Error:Execution failed for tas
  8. android事件处理的四种写法--电话拨号为
  9. Android中使用字体文件
  10. android的sqlite数据库中单引号的诡异作