高仿QQ讨论组头像拼图

来源:互联网 发布:黑帽seo 编辑:程序博客网 时间:2024/04/30 21:45

讨论组如果没有头像,体验较差,我们会选择讨论组成员来拼成一个新图,最多五张。先贴上自定义View  CircularImageView核心代码:

public class CircularImageView extends View {    protected int viewWidth;    protected int viewHeight;    protected ArrayList<Bitmap> bmps;    public CircularImageView(Context context) {        super(context);    }    public CircularImageView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public CircularImageView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int width = getMeasuredWidth();        int height = getMeasuredHeight();        int dimen = Math.min(width, height);        setMeasuredDimension(dimen, dimen);    }    public void setImageBitmaps(ArrayList<Bitmap> bitmaps) {        if (bitmaps == null)            throw new IllegalArgumentException("bitmaps can not be Null");        if (bitmaps.size() > JoinLayout.max())            throw new IllegalArgumentException("bitmaps size can not be greater than "                    + JoinLayout.max());        this.bmps = bitmaps;        invalidate();    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        viewWidth = w;        viewHeight = h;        viewWidth = viewHeight = Math.min(w, h);    }    @Override    public void onDraw(Canvas canvas) {        if (viewWidth > 0 && viewHeight > 0) {            JoinBitmaps.join(canvas, viewWidth, bmps, 0.15f);        }    }}
这个View 主要要塞入一组比Bitmap ,然后重绘。这里用到了JoinBitmaps 这类,代买如下:

public class JoinBitmaps {    public static final void join(Canvas canvas, int dimension, List<Bitmap> bitmaps) {        if (bitmaps == null)            return;        int count = Math.min(bitmaps.size(), JoinLayout.max());        float[] size = JoinLayout.size(count);        join(canvas, dimension, bitmaps, count, size);    }    public static final void join(Canvas canvas, int dimension, List<Bitmap> bitmaps, int count,            float[] size) {        join(canvas, dimension, bitmaps, count, size, 0.15f);    }    public static final void join(Canvas canvas, int dimension, List<Bitmap> bitmaps,            float gapSize) {        if (bitmaps == null)            return;        int count = Math.min(bitmaps.size(), JoinLayout.max());        float[] size = JoinLayout.size(count);        join(canvas, dimension, bitmaps, count, size, gapSize);    }    public static final void join(Canvas canvas, int dimension, List<Bitmap> bitmaps, int count,            float[] size, float gapSize) {        if (bitmaps == null)            return;        // 旋转角度        float[] rotation = JoinLayout.rotation(count);        // paint        Paint paint = new Paint();        paint.setAntiAlias(true);        Matrix matrixJoin = new Matrix();        // scale as join size        matrixJoin.postScale(size[0], size[0]);        canvas.save();        // canvas.drawColor(Color.RED);        for (int index = 0; index < bitmaps.size(); index++) {            Bitmap bitmap = bitmaps.get(index);            // MATRIX            Matrix matrix = new Matrix();            // scale as destination            matrix.postScale((float) dimension / bitmap.getWidth(),                    (float) dimension / bitmap.getHeight());            canvas.save();            matrix.postConcat(matrixJoin);            float[] offset = JoinLayout.offset(count, index, dimension, size);            canvas.translate(offset[0], offset[1]);            // 缩放            Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),                    bitmap.getHeight(), matrix, true);            // 裁剪            Bitmap bitmapOk = createMaskBitmap(newBitmap, newBitmap.getWidth(),                    newBitmap.getHeight(), (int) rotation[index], gapSize);            canvas.drawBitmap(bitmapOk, 0, 0, paint);            canvas.restore();        }        canvas.restore();    }    public static final Bitmap createMaskBitmap(Bitmap bitmap, int viewBoxW, int viewBoxH,            int rotation, float gapSize) {        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),                Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas(output);        final Paint paint = new Paint();        paint.setAntiAlias(true);// 抗锯�?        paint.setFilterBitmap(true);        int center = Math.round(viewBoxW / 2f);        canvas.drawCircle(center, center, center, paint);        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));        canvas.drawBitmap(bitmap, 0, 0, paint);        if (rotation != 360) {            Matrix matrix = new Matrix();            // 根据原图的中心位置旋�?            matrix.setRotate(rotation, viewBoxW / 2, viewBoxH / 2);            canvas.setMatrix(matrix);            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));            canvas.drawCircle(viewBoxW * (1.5f - gapSize), center, center, paint);        }        return output;    }    public static final Bitmap createBitmap(int width, int height, List<Bitmap> bitmaps) {        int count = Math.min(bitmaps.size(), JoinLayout.max());        float[] size = JoinLayout.size(count);        return createBitmap(width, height, bitmaps, count, size, 0.15f);    }    public static final Bitmap createBitmap(int width, int height, List<Bitmap> bitmaps,            int count, float[] size) {        return createBitmap(width, height, bitmaps, count, size, 0.15f);    }    public static final Bitmap createBitmap(int width, int height, List<Bitmap> bitmaps,            int count, float[] size, float gapSize) {        Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas(output);        int dimen = Math.min(width, height);        join(canvas, dimen, bitmaps, count, size, gapSize);        return output;    }}
和JoinLayout这类,代码如下:
public class JoinLayout {    public static final String TAG = JoinLayout.class.getSimpleName();    public static int max() {        return 5;    }    private static final float[][] rotations = { new float[] { 360 }, new float[] { 45, 360 },            new float[] { 120, 0, -120 }, new float[] { 90, 180, -90, 0 },            new float[] { 144, 72, 0, -72, -144 }, };    public static float[] rotation(int count) {        return count > 0 && count <= rotations.length ? rotations[count - 1] : null;    }    private static final float[][] sizes = { new float[] { 0.9f, 0.9f },            new float[] { 0.5f, 0.65f }, new float[] { 0.45f, 0.8f },            new float[] { 0.45f, 0.91f }, new float[] { 0.38f, 0.80f } };    public static float[] size(int count) {        return count > 0 && count <= sizes.length ? sizes[count - 1] : null;    }    public static float[] offset(int count, int index, float dimension, float[] size) {        switch (count) {            case 1:                return offset1(index, dimension, size);            case 2:                return offset2(index, dimension, size);            case 3:                return offset3(index, dimension, size);            case 4:                return offset4(index, dimension, size);            case 5:                return offset5(index, dimension, size);            default:                break;        }        return new float[] { 0f, 0f };    }    /**     * 5个头�?     *      * @param index     *            下标     * @param width     *            画布边长(正方形�?     * @param size     *            size[0]缩放 size[1]边距     * @return 下标index X,Y轴坐�?     */    private static float[] offset5(int index, float dimension, float[] size) {        // 圆的直径        float cd = (float) dimension * size[0];        // 边距        float s1 = -cd * size[1];        float x1 = 0;        float y1 = s1;        float x2 = (float) (s1 * Math.cos(19 * Math.PI / 180));        float y2 = (float) (s1 * Math.sin(18 * Math.PI / 180));        float x3 = (float) (s1 * Math.cos(54 * Math.PI / 180));        float y3 = (float) (-s1 * Math.sin(54 * Math.PI / 180));        float x4 = (float) (-s1 * Math.cos(54 * Math.PI / 180));        float y4 = (float) (-s1 * Math.sin(54 * Math.PI / 180));        float x5 = (float) (-s1 * Math.cos(19 * Math.PI / 180));        float y5 = (float) (s1 * Math.sin(18 * Math.PI / 180));        // Log.d(TAG, "x1:" + x1 + "/y1:" + y1);        // Log.d(TAG, "x2:" + x2 + "/y2:" + y2);        // Log.d(TAG, "x3:" + x3 + "/y3:" + y3);        // Log.d(TAG, "x4:" + x4 + "/y4:" + y4);        // Log.d(TAG, "x5:" + x5 + "/y5:" + y5);        // 居中 Y轴偏移量        float xx1 = (dimension - cd - y3 - s1) / 2;        // 居中 X轴偏移量        float xxc1 = (dimension - cd) / 2;        // xx1 = xxc1 = -s1;        // xx1 = xxc1 = 0;        switch (index) {            case 0:                // return new float[] { s1 + xxc1, xx1 };                return new float[] { x1 + xxc1, y1 + xx1 };            case 1:                return new float[] { x2 + xxc1, y2 + xx1 };            case 2:                return new float[] { x3 + xxc1, y3 + xx1 };            case 3:                return new float[] { x4 + xxc1, y4 + xx1 };            case 4:                return new float[] { x5 + xxc1, y5 + xx1 };            default:                break;        }        return new float[] { 0f, 0f };    }    /**     * 4个头�?     *      * @param index     *            下标     * @param width     *            画布边长(正方形�?     * @param size     *            size[0]缩放 size[1]边距     * @return 下标index X,Y轴坐�?     */    private static float[] offset4(int index, float dimension, float[] size) {        // 圆的直径        float cd = (float) dimension * size[0];        // 边距        float s1 = cd * size[1];        float x1 = 0;        float y1 = 0;        float x2 = s1;        float y2 = y1;        float x3 = s1;        float y3 = s1;        float x4 = x1;        float y4 = y3;        // Log.d(TAG, "x1:" + x1 + "/y1:" + y1);        // Log.d(TAG, "x2:" + x2 + "/y2:" + y2);        // Log.d(TAG, "x3:" + x3 + "/y3:" + y3);        // Log.d(TAG, "x4:" + x4 + "/y4:" + y4);        // 居中 X轴偏移量        float xx1 = (dimension - cd - s1) / 2;        switch (index) {            case 0:                return new float[] { x1 + xx1, y1 + xx1 };            case 1:                return new float[] { x2 + xx1, y2 + xx1 };            case 2:                return new float[] { x3 + xx1, y3 + xx1 };            case 3:                return new float[] { x4 + xx1, y4 + xx1 };            default:                break;        }        return new float[] { 0f, 0f };    }    /**     * 3个头�?     *      * @param index     *            下标     * @param width     *            画布边长(正方形�?     * @param size     *            size[0]缩放 size[1]边距     * @return 下标index X,Y轴坐�?     */    private static float[] offset3(int index, float dimension, float[] size) {        // 圆的直径        float cd = (float) dimension * size[0];        // 边距        float s1 = cd * size[1];        // 第二个圆�? Y坐标        float y2 = s1 * (3 / 2);        // 第二个圆�? X坐标        float x2 = s1 - y2 / 1.73205f;        // 第三个圆�? X坐标        float x3 = s1 * 2 - x2;        // 居中 Y轴偏移量        float xx1 = (dimension - cd - y2) / 2;        // 居中 X轴偏移量        float xxc1 = (dimension - cd) / 2 - s1;        // xx1 = xxc1 = 0;        switch (index) {            case 0:                return new float[] { s1 + xxc1, xx1 };            case 1:                return new float[] { x2 + xxc1, y2 + xx1 };            case 2:                return new float[] { x3 + xxc1, y2 + xx1 };            default:                break;        }        return new float[] { 0f, 0f };    }    /**     * 2个头�?     *      * @param index     *            下标     * @param width     *            画布边长(正方形�?     * @param size     *            size[0]缩放 size[1]边距     * @return 下标index X,Y轴坐�?     */    private static float[] offset2(int index, float dimension, float[] size) {        // 圆的直径        float cd = (float) dimension * size[0];        // 边距        float s1 = cd * size[1];        float x1 = 0;        float y1 = 0;        float x2 = s1;        float y2 = s1;        // Log.d(TAG, "x1:" + x1 + "/y1:" + y1);        // Log.d(TAG, "x2:" + x2 + "/y2:" + y2);        // 居中 X轴偏移量        float xx1 = (dimension - cd - s1) / 2;        switch (index) {            case 0:                return new float[] { x1 + xx1, y1 + xx1 };            case 1:                return new float[] { x2 + xx1, y2 + xx1 };            default:                break;        }        return new float[] { 0f, 0f };    }    /**     * 1个头�?     *      * @param index     *            下标     * @param width     *            画布边长(正方形�?     * @param size     *            size[0]缩放 size[1]边距     * @return 下标index X,Y轴坐�?     */    private static float[] offset1(int index, float dimension, float[] size) {        // 圆的直径        float cd = (float) dimension * size[0];        float offset = (dimension - cd) / 2;        return new float[] { offset, offset };    }}
核心代码已经贴出来了,剩下就是界面,Activity,adapter ,Item ,我一起给,如下:

public class Item {private String name;private String age;public ArrayList<Bitmap> bitmapList ;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}Item(String name, String age , ArrayList<Bitmap> bitmapList) {this.name = name;this.age = age;this.bitmapList = bitmapList ;}}

public class ItemAdapter  extends BaseAdapter{private List<Item> itemList = new ArrayList<Item>();private LayoutInflater inflater;private ArrayList<Bitmap> GroupHeaderText = new ArrayList<Bitmap>();private Bitmap imgBitmap = null ;public ItemAdapter(Context c,List<Item> itemList) {// TODO Auto-generated constructor stubinflater = LayoutInflater.from(c);this.itemList = itemList ; imgBitmap = BitmapFactory.decodeResource(c.getResources(), R.drawable.header); GroupHeaderText.add(imgBitmap);}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn itemList.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic long getItemId(int arg0) {// TODO Auto-generated method stubreturn 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubViewHolder holder;if (convertView == null) {holder = new ViewHolder();convertView = inflater.inflate(R.layout.item, null);holder.name = (TextView) convertView.findViewById(R.id.id_treenode_label);holder.age = (TextView) convertView.findViewById(R.id.id_treenode_online);holder.mImageView1 = (CircularImageView) convertView.findViewById(R.id.circularImageView);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}holder.name.setSelected(true);holder.name.setText(itemList.get(position).getName());if(!TextUtils.isEmpty(itemList.get(position).getAge())){holder.age.setVisibility(View.VISIBLE);holder.age.setText(itemList.get(position).getAge());}else{holder.age.setVisibility(View.GONE);}if(itemList.get(position).bitmapList != null){holder.mImageView1.setImageBitmaps(itemList.get(position).bitmapList);}else{holder.mImageView1.setImageBitmaps(GroupHeaderText);}return convertView;}class ViewHolder {CircularImageView mImageView1;TextView name;// TextView department;TextView age;TextView header;// View divider;}}

public class MainActivity extends ActionBarActivity {private List<Item> itemList = new ArrayList<Item>();private ListView list;private ItemAdapter itemAdapter;private Bitmap imgBitmap;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initId();initData();itemAdapter = new ItemAdapter(getApplicationContext(), itemList);list.setAdapter(itemAdapter);}public void initId() {list = (ListView) findViewById(R.id.list);imgBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.header);}public void initData() {ArrayList<Bitmap> bitmap = new ArrayList<Bitmap>();bitmap.add(imgBitmap);bitmap.add(imgBitmap);itemList.add(new Item("A", "1", bitmap));ArrayList<Bitmap> bitmap2 = new ArrayList<Bitmap>();bitmap2.add(imgBitmap);bitmap2.add(imgBitmap);bitmap2.add(imgBitmap);itemList.add(new Item("A", "1", bitmap2));ArrayList<Bitmap> bitmap3 = new ArrayList<Bitmap>();bitmap3.add(imgBitmap);bitmap3.add(imgBitmap);bitmap3.add(imgBitmap);itemList.add(new Item("A", "1", bitmap3));ArrayList<Bitmap> bitmap4 = new ArrayList<Bitmap>();bitmap4.add(imgBitmap);bitmap4.add(imgBitmap);bitmap4.add(imgBitmap);bitmap4.add(imgBitmap);itemList.add(new Item("A", "1", bitmap4));ArrayList<Bitmap> bitmap5 = new ArrayList<Bitmap>();bitmap5.add(imgBitmap);bitmap5.add(imgBitmap);bitmap5.add(imgBitmap);bitmap5.add(imgBitmap);bitmap5.add(imgBitmap);itemList.add(new Item("A", "1", bitmap5));itemList.add(new Item("A", "1", null));itemList.add(new Item("AKJfhakdjfklas;jfklasdfjalskjfsdakfjlkasjdjfk;asdjfkasdjf","1", null));itemList.add(new Item("A", "1", null));}}
ok了,布局文件自己写吧,懒得写了。

0 0
原创粉丝点击