【Android 界面效果44】Android之圆头像实例

在很多应用中,我们看到,个人主页里面的头像一般都是圆的,设计成圆的会使整个界 面布 局变的优雅漂亮。那么,怎么使头像变圆呢?有的人说可以在上面加一个中间为透明圆形的png图,用它来遮盖住头像不就行了嘛,但是png四周始终始终是不 透明的,怎么做也达不到如下的效果图的。

下面我们讲讲怎么做成的吧。

首先创建一个继承ImageView的抽象类MaskedImage。让他重写onDraw方法。代码如下

    public abstract class MaskedImage extends ImageView {
        private static final Xfermode MASK_XFERMODE;
        private Bitmap mask;
        private Paint paint;  

        static {
            PorterDuff.Mode localMode = PorterDuff.Mode.DST_IN;
            MASK_XFERMODE = new PorterDuffXfermode(localMode);
        }  

        public MaskedImage(Context paramContext) {
            super(paramContext);
        }  

        public MaskedImage(Context paramContext, AttributeSet paramAttributeSet) {
            super(paramContext, paramAttributeSet);
        }  

        public MaskedImage(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {
            super(paramContext, paramAttributeSet, paramInt);
        }  

        public abstract Bitmap createMask();  

        protected void onDraw(Canvas paramCanvas) {
            Drawable localDrawable = getDrawable();
            if (localDrawable == null)
                return;
            try {
                if (this.paint == null) {
                    Paint localPaint1 = new Paint();
                    this.paint = localPaint1;
                    this.paint.setFilterBitmap(false);
                    Paint localPaint2 = this.paint;
                    Xfermode localXfermode1 = MASK_XFERMODE;
                    @SuppressWarnings("unused")
                    Xfermode localXfermode2 = localPaint2.setXfermode(localXfermode1);
                }
                float f1 = getWidth();
                float f2 = getHeight();
                int i = paramCanvas.saveLayer(0.0F, 0.0F, f1, f2, null, 31);
                int j = getWidth();
                int k = getHeight();
                localDrawable.setBounds(0, 0, j, k);
                localDrawable.draw(paramCanvas);
                if ((this.mask == null) || (this.mask.isRecycled())) {
                    Bitmap localBitmap1 = createMask();
                    this.mask = localBitmap1;
                }
                Bitmap localBitmap2 = this.mask;
                Paint localPaint3 = this.paint;
                paramCanvas.drawBitmap(localBitmap2, 0.0F, 0.0F, localPaint3);
                paramCanvas.restoreToCount(i);
                return;
            } catch (Exception localException) {
                StringBuilder localStringBuilder = new StringBuilder()
                        .append("Attempting to draw with recycled bitmap. View ID = ");
                System.out.println("localStringBuilder=="+localStringBuilder);
            }
        }
    }  
    public abstract class MaskedImage extends ImageView {
        private static final Xfermode MASK_XFERMODE;
        private Bitmap mask;
        private Paint paint;  

        static {
            PorterDuff.Mode localMode = PorterDuff.Mode.DST_IN;
            MASK_XFERMODE = new PorterDuffXfermode(localMode);
        }  

        public MaskedImage(Context paramContext) {
            super(paramContext);
        }  

        public MaskedImage(Context paramContext, AttributeSet paramAttributeSet) {
            super(paramContext, paramAttributeSet);
        }  

        public MaskedImage(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {
            super(paramContext, paramAttributeSet, paramInt);
        }  

        public abstract Bitmap createMask();  

        protected void onDraw(Canvas paramCanvas) {
            Drawable localDrawable = getDrawable();
            if (localDrawable == null)
                return;
            try {
                if (this.paint == null) {
                    Paint localPaint1 = new Paint();
                    this.paint = localPaint1;
                    this.paint.setFilterBitmap(false);
                    Paint localPaint2 = this.paint;
                    Xfermode localXfermode1 = MASK_XFERMODE;
                    @SuppressWarnings("unused")
                    Xfermode localXfermode2 = localPaint2.setXfermode(localXfermode1);
                }
                float f1 = getWidth();
                float f2 = getHeight();
                int i = paramCanvas.saveLayer(0.0F, 0.0F, f1, f2, null, 31);
                int j = getWidth();
                int k = getHeight();
                localDrawable.setBounds(0, 0, j, k);
                localDrawable.draw(paramCanvas);
                if ((this.mask == null) || (this.mask.isRecycled())) {
                    Bitmap localBitmap1 = createMask();
                    this.mask = localBitmap1;
                }
                Bitmap localBitmap2 = this.mask;
                Paint localPaint3 = this.paint;
                paramCanvas.drawBitmap(localBitmap2, 0.0F, 0.0F, localPaint3);
                paramCanvas.restoreToCount(i);
                return;
            } catch (Exception localException) {
                StringBuilder localStringBuilder = new StringBuilder()
                        .append("Attempting to draw with recycled bitmap. View ID = ");
                System.out.println("localStringBuilder=="+localStringBuilder);
            }
        }
    }  

然后新建一个类CircularImage继承MaskedImage。代码如下:

public class CircularImage extends MaskedImage {
    public CircularImage(Context paramContext) {
        super(paramContext);
    }  

    public CircularImage(Context paramContext, AttributeSet paramAttributeSet) {
        super(paramContext, paramAttributeSet);
    }  

    public CircularImage(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {
        super(paramContext, paramAttributeSet, paramInt);
    }  

    public Bitmap createMask() {
        int i = getWidth();
        int j = getHeight();
        Bitmap.Config localConfig = Bitmap.Config.ARGB_8888;
        Bitmap localBitmap = Bitmap.createBitmap(i, j, localConfig);
        Canvas localCanvas = new Canvas(localBitmap);
        Paint localPaint = new Paint(1);
        localPaint.setColor(-16777216);
        float f1 = getWidth();
        float f2 = getHeight();
        RectF localRectF = new RectF(0.0F, 0.0F, f1, f2);
        localCanvas.drawOval(localRectF, localPaint);
        return localBitmap;
    }
}
public class CircularImage extends MaskedImage {
    public CircularImage(Context paramContext) {
        super(paramContext);
    }  

    public CircularImage(Context paramContext, AttributeSet paramAttributeSet) {
        super(paramContext, paramAttributeSet);
    }  

    public CircularImage(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {
        super(paramContext, paramAttributeSet, paramInt);
    }  

    public Bitmap createMask() {
        int i = getWidth();
        int j = getHeight();
        Bitmap.Config localConfig = Bitmap.Config.ARGB_8888;
        Bitmap localBitmap = Bitmap.createBitmap(i, j, localConfig);
        Canvas localCanvas = new Canvas(localBitmap);
        Paint localPaint = new Paint(1);
        localPaint.setColor(-16777216);
        float f1 = getWidth();
        float f2 = getHeight();
        RectF localRectF = new RectF(0.0F, 0.0F, f1, f2);
        localCanvas.drawOval(localRectF, localPaint);
        return localBitmap;
    }
}

新建一个MainActivity,代码如下:

    public class MainActivity extends Activity {  

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);  

            CircularImage cover_user_photo = (CircularImage) findViewById(R.id.cover_user_photo);
            cover_user_photo.setImageResource(R.drawable.face);
        }
    }  
    public class MainActivity extends Activity {  

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);  

            CircularImage cover_user_photo = (CircularImage) findViewById(R.id.cover_user_photo);
            cover_user_photo.setImageResource(R.drawable.face);
        }
    }  

其XML布局文件为:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center" >  

        <ImageView
            android:layout_width="82.0dip"
            android:layout_height="82.0dip"
            android:layout_centerInParent="true"
            android:contentDescription="@null"
            android:src="@drawable/me_head_bg" />  

        <com.doublefi123.diary.widget.CircularImage
            android:id="@+id/cover_user_photo"
            android:layout_width="74.0dip"
            android:layout_height="74.0dip"
            android:layout_centerInParent="true" />  

    </RelativeLayout>  
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center" >  

        <ImageView
            android:layout_width="82.0dip"
            android:layout_height="82.0dip"
            android:layout_centerInParent="true"
            android:contentDescription="@null"
            android:src="@drawable/me_head_bg" />  

        <com.doublefi123.diary.widget.CircularImage
            android:id="@+id/cover_user_photo"
            android:layout_width="74.0dip"
            android:layout_height="74.0dip"
            android:layout_centerInParent="true" />  

    </RelativeLayout>  

这样就OK啦。哈哈

源码在此:http://download.csdn.net/detail/doublefi123/5252186

时间: 2024-11-03 09:13:27

【Android 界面效果44】Android之圆头像实例的相关文章

【Android 界面效果47】RecyclerView详解

RecylerView作为 support-library发布出来,这对开发者来说绝对是个好消息.因为可以在更低的Android版本上使用这个新视图.下面我们看如何获取 RecylerView.首先打开Android SDK Manager,然后更新Extras->Android Support Library即可. 然后在本地../sdk/extras/android/support/v7中找到recyclerview.我已经将下载好的Recyclerview整理成一个Eclipse可编译的L

【Android 界面效果49】RecyclerView高度随Item自适应

编写RecyclerView.ItemDecoration时,在onDraw方法中,Drawable的高度等于RecyclerView的高度减去RecyclerView的上下padding. @Override public void onDraw(Canvas c, RecyclerView parent, State state) { int top = parent.getPaddingTop(); int bottom = parent.getHeight() - parent.getP

【Android 界面效果45】ViewPager源码分析

ViewPager概述: Layout manager that allows the user to flip left and right through pages of data. You supply an implementation of a PagerAdapter to generate the pages that the view shows. Note this class is currently under early design and development.

【Android 界面效果43】Android LayoutInflater的inflate方法中attachToRoot的作用

我们在ListView的Adapter的getView方法里面经常会调用两个参数的inflate方法, mInflater.inflate(R.layout.adv_viewpager, null); 我们可能会发现layout外层的layout_width  layout_height属性都没起作用,全都变成wrap_content的值了. 这个问题就是因为我们使用了错误的参数照成的, 系统在inflate layout的时候 如果传入的root为空的话 就会忽略LayoutParams. 所

【Android 界面效果46】自定义view常处理的回调方法

onFinishInflate() 当View中所有的子控件均被映射成xml后触发 onMeasure(int, int) 确定所有子元素的大小 onLayout(boolean, int, int, int, int) 当View分配所有的子元素的大小和位置时触发 onSizeChanged(int, int, int, int) 当view的大小发生变化时触发 onDraw(Canvas) view渲染内容的细节 onKeyDown(int, KeyEvent) 有按键按下后触发 onKey

【Android 界面效果48】Android-RecyclerView-Item点击事件设置

在上一篇博客Android-RecylerView初识中提到,RecyclerView不再负责Item视图的布局及显示,所以RecyclerView也没有为Item开放OnItemClick等点击事件,这就需要开发者自己实现.博客最下面有Demo程序运行动画. 奉上Demo的Github链接. 在调研过程中,发现有同学修改RecyclerView源码来实现Item的点击监听,但认为这不是一个优雅的解决方案,最终决定在RecyclerView.ViewHolder上做文章. 思 路是:因为View

【Android界面实现】使用ScrollingTabsView实现有滑动标签的ViewPager效果

转载自:http://blog.csdn.net/zhaokaiqiang1992/article/details/40378285 在前面的文章中,我们使用支持包里面的PagerTabStrip实现了有滑动标签的viewPager效果,今天,再给大家介绍另外一种开源项目,来实现类似的效果. 在这篇文章中,我们将使用第三方开源项目ViewPagerExtensions实现. 先看效果 ViewPagerExtensions的github地址:https://github.com/astuetz/

我收集了多个android界面UI效果,深感大哥们的分享啊

初到oschina,看到很多大哥们分享了很好好的代码,近段时间,我收集了多个android界面UI效果,深感大哥们的分享啊.后来我将这些界面效果整合拢来,形成一个大的特效集合,一来为了查看方便,二来也为拷贝复制便捷.今日,将其共享出来,也算是为资源共享出一分力嘛. 直接上效果图: 可以看到上图中几个效果图,最上面九宫格图.左边一个是图书翻页效果图,都是比较经典的UI效果,当然还有很多,这些都是来源于oschina上的分享. 不过想说明一下,有部分地方小弟私自改动了,还请原作者原谅.例如,水波纹的

Android界面转换效果模板之scale与routate_scale使用

现在先来说一下scale(缩放比例)的使用: 调用方法:overridePendingTransition(R.anim.scale_in, R.anim.scale_out); R.anim.scale_in表示要进入的Activity界面的xml文件,R.anim.scale_out表示离开的Activity界面的xml文件,在xml文件中可配置相关属性,即可实现相关的动画效果. 下面来举例并说明其配置的相关含义: R.anim.scale_in: <?xml version="1.0