为什么不设置Android的支持V4图书馆公共CircleImageView? [英] Why don't set CircleImageView of android support v4 library public?

查看:667
本文介绍了为什么不设置Android的支持V4图书馆公共CircleImageView?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到 android.support.v4.widget.CircleImageView 长。每次我想使用的ImageView 的圆形, CircleImageView 将出现在我的脑海里。我曾尝试使用它很多次,但每一次,我失败了。因为 android.support.v4.widget.CircleImageView 访问权限的默认,这意味着在相同的只有类包 CircleImageView ,即 android.support.v4.widget ,都能够访问它。

I have noticed android.support.v4.widget.CircleImageView for long. Every time I want to use an ImageView in a round shape, CircleImageView would appear in my mind. I have tried to use it for many times, but every time, I failed. Because the access permission of android.support.v4.widget.CircleImageView is default which means only classes in the same package with CircleImageView, namely, android.support.v4.widget, are able to access it.

我现在不能明白,圆的ImageView 的共通之处,为何不使用不 CircleImageView 来公共使开发人员不必重写一个的ImageView 成圆形的ImageView?是不是,谷歌Android团队迫使我们的重塑车轮

I can't understand now that round ImageView is used in common, why don't set CircleImageView to public so that developers don't have to override an ImageView into a Round ImageView? Isn't it that Google Android team force us to reinvent wheels?

或者说,不知道这个 CircleImageView 吗?

Or, don't I know this CircleImageView well?

任何提示将AP preciated。先谢谢了。

Any tips will be appreciated. Thanks in advance.

推荐答案

我试图复制和粘贴源$ C ​​$ CS android.support.v4.widget.CircleImageView 把它公开,就像这样:

I tried to copy and paste source codes of android.support.v4.widget.CircleImageView to make it public just like this:

package me.danielpan.youtubelike.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.support.v4.view.ViewCompat;
import android.view.animation.Animation;
import android.widget.ImageView;

/**
 * Private class created to work around issues with AnimationListeners being
 * called before the animation is actually complete and support shadows on older
 * platforms.
 *
 * @hide
 */
public class CircleImageView extends ImageView {

    private static final int KEY_SHADOW_COLOR = 0x1E000000;
    private static final int FILL_SHADOW_COLOR = 0x3D000000;
    // PX
    private static final float X_OFFSET = 0f;
    private static final float Y_OFFSET = 1.75f;
    private static final float SHADOW_RADIUS = 3.5f;
    private static final int SHADOW_ELEVATION = 4;

    private Animation.AnimationListener mListener;
    private int mShadowRadius;

    public CircleImageView(Context context, int color, final float radius) {
        super(context);
        final float density = getContext().getResources().getDisplayMetrics().density;
        final int diameter = (int) (radius * density * 2);
        final int shadowYOffset = (int) (density * Y_OFFSET);
        final int shadowXOffset = (int) (density * X_OFFSET);

        mShadowRadius = (int) (density * SHADOW_RADIUS);

        ShapeDrawable circle;
        if (elevationSupported()) {
            circle = new ShapeDrawable(new OvalShape());
            ViewCompat.setElevation(this, SHADOW_ELEVATION * density);
        } else {
            OvalShape oval = new OvalShadow(mShadowRadius, diameter);
            circle = new ShapeDrawable(oval);
            ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, circle.getPaint());
            circle.getPaint().setShadowLayer(mShadowRadius, shadowXOffset, shadowYOffset,
                    KEY_SHADOW_COLOR);
            final int padding = mShadowRadius;
            // set padding so the inner image sits correctly within the shadow.
            setPadding(padding, padding, padding, padding);
        }
        circle.getPaint().setColor(color);
        setBackgroundDrawable(circle);
    }

    private boolean elevationSupported() {
        return android.os.Build.VERSION.SDK_INT >= 21;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (!elevationSupported()) {
            setMeasuredDimension(getMeasuredWidth() + mShadowRadius*2, getMeasuredHeight()
                    + mShadowRadius*2);
        }
    }

    public void setAnimationListener(Animation.AnimationListener listener) {
        mListener = listener;
    }

    @Override
    public void onAnimationStart() {
        super.onAnimationStart();
        if (mListener != null) {
            mListener.onAnimationStart(getAnimation());
        }
    }

    @Override
    public void onAnimationEnd() {
        super.onAnimationEnd();
        if (mListener != null) {
            mListener.onAnimationEnd(getAnimation());
        }
    }

    /**
     * Update the background color of the circle image view.
     *
     * @param colorRes Id of a color resource.
     */
    public void setBackgroundColorRes(int colorRes) {
        setBackgroundColor(getContext().getResources().getColor(colorRes));
    }

    @Override
    public void setBackgroundColor(int color) {
        if (getBackground() instanceof ShapeDrawable) {
            ((ShapeDrawable) getBackground()).getPaint().setColor(color);
        }
    }

    private class OvalShadow extends OvalShape {
        private RadialGradient mRadialGradient;
        private Paint mShadowPaint;
        private int mCircleDiameter;

        public OvalShadow(int shadowRadius, int circleDiameter) {
            super();
            mShadowPaint = new Paint();
            mShadowRadius = shadowRadius;
            mCircleDiameter = circleDiameter;
            mRadialGradient = new RadialGradient(mCircleDiameter / 2, mCircleDiameter / 2,
                    mShadowRadius, new int[] {
                    FILL_SHADOW_COLOR, Color.TRANSPARENT
            }, null, Shader.TileMode.CLAMP);
            mShadowPaint.setShader(mRadialGradient);
        }

        @Override
        public void draw(Canvas canvas, Paint paint) {
            final int viewWidth = CircleImageView.this.getWidth();
            final int viewHeight = CircleImageView.this.getHeight();
            canvas.drawCircle(viewWidth / 2, viewHeight / 2, (mCircleDiameter / 2 + mShadowRadius),
                    mShadowPaint);
            canvas.drawCircle(viewWidth / 2, viewHeight / 2, (mCircleDiameter / 2), paint);
        }
    }
}

这看起来不错,对吧?它没有自定义属性,似乎能够被用来作为一个正常的的ImageView

但是,如果你已经尝试过了,你会发现, NoSuchMethodException 被抛出。此异常意味着必要的构造函数没有被重载。所以,你甚至不能实例化它作为一个正常的查看

But if you have tried it, you will find out that NoSuchMethodException is thrown. This exception implies that necessary constructors are not overridden. So that you can't even instantiate it as a normal View.

阅读这些源$ C ​​$ CS之后,我认识到, CircleImageView 只增加了阴影背后的ImageView ,其结果是不是 RoundCornerImageView RoundImageView 。所以,如果我想要一个 RoundImageView ,我必须忘掉这个类,并通过覆盖的ImageView 实现这种效果。

After reading these source codes, I realize that CircleImageView only adds shadow behind ImageView, whose result is not a RoundCornerImageView or RoundImageView. So if I want a RoundImageView, I have to forget this class and implement this effect by overriding an ImageView.

最后,有文件注释,它指出了使用 android.support.v4.widget.CircleImageView

At last, there is the file comment, which points out the use of android.support.v4.widget.CircleImageView:

创建私有类来解决与AnimationListeners问题
  被称为前的动画是实际完成和支持
  在旧平台上的阴影。

Private class created to work around issues with AnimationListeners being called before the animation is actually complete and support shadows on older platforms.

和我希望没有人再会问这样一个愚蠢的问题,让它在这里结束,^ _ ^,哈哈〜

And I hope no one will ask such a stupid question again and let it end here, ^_^, Haha~

这篇关于为什么不设置Android的支持V4图书馆公共CircleImageView?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆