Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 圆形图像视图拉伸_Java_Android - Fatal编程技术网

Java 圆形图像视图拉伸

Java 圆形图像视图拉伸,java,android,Java,Android,我使用以下代码在项目中创建圆形图像视图 public class CircularImageView extends ImageView { // Border & Selector configuration variables private boolean hasBorder; private boolean hasSelector; private boolean isSelected; private int borderWidth;

我使用以下代码在项目中创建圆形图像视图

public class CircularImageView extends ImageView {
    // Border & Selector configuration variables
    private boolean hasBorder;
    private boolean hasSelector;
    private boolean isSelected;
    private int borderWidth;
    private int canvasSize;
    private int selectorStrokeWidth;

    // Objects used for the actual drawing
    private BitmapShader shader;
    private Bitmap image;
    private Paint paint;
    private Paint paintBorder;
    private Paint paintSelectorBorder;
    private ColorFilter selectorFilter;

    public CircularImageView(Context context) {
        this(context, null);
    }

    public CircularImageView(Context context, AttributeSet attrs)
    {
        this(context, attrs, R.attr.circularImageViewStyle);
    }

    public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    /**
     * Initializes paint objects and sets desired attributes.
     *
     * @param context
     * @param attrs
     * @param defStyle
     */
    private void init(Context context, AttributeSet attrs, int defStyle) {
        // Initialize paint objects
        paint = new Paint();
        paint.setAntiAlias(true);
        paintBorder = new Paint();
        paintBorder.setAntiAlias(true);
        paintSelectorBorder = new Paint();
        paintSelectorBorder.setAntiAlias(true);

        // load the styled attributes and set their properties
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyle, 0);

        // Check if border and/or border is enabled
        hasBorder = attributes.getBoolean(R.styleable.CircularImageView_border, false);
        hasSelector = attributes.getBoolean(R.styleable.CircularImageView_selector, false);

        // Set border properties if enabled
        if(hasBorder) {
            int defaultBorderSize = (int) (2 * context.getResources().getDisplayMetrics().density + 0.5f);
            setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_border_width, defaultBorderSize));
            setBorderColor(attributes.getColor(R.styleable.CircularImageView_border_color, Color.WHITE));
        }

        // Set selector properties if enabled
        if(hasSelector) {
            int defaultSelectorSize = (int) (2 * context.getResources().getDisplayMetrics().density + 0.5f);
            setSelectorColor(attributes.getColor(
                R.styleable.CircularImageView_selector_color, Color.TRANSPARENT));
            setSelectorStrokeWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_selector_stroke_width, defaultSelectorSize));
            setSelectorStrokeColor(attributes.getColor(R.styleable.CircularImageView_selector_stroke_color, Color.BLUE));
        }

        // Add shadow if enabled
        if(attributes.getBoolean(R.styleable.CircularImageView_shadow, false))
            addShadow();

        // We no longer need our attributes TypedArray, give it back to cache
        attributes.recycle();
    }

    /**
     * Sets the CircularImageView's border width in pixels.
     *
     * @param borderWidth
     */
    public void setBorderWidth(int borderWidth) {
        this.borderWidth = borderWidth;
        this.requestLayout();
        this.invalidate();
    }

    /**
     * Sets the CircularImageView's basic border color.
     *
     * @param borderColor
     */
    public void setBorderColor(int borderColor) {
        if (paintBorder != null)
            paintBorder.setColor(borderColor);
        this.invalidate();
    }

    /**
     * Sets the color of the selector to be draw over the
     * CircularImageView. Be sure to provide some opacity.
     *
     * @param selectorColor
     */
    public void setSelectorColor(int selectorColor) {
        this.selectorFilter = new PorterDuffColorFilter(selectorColor, PorterDuff.Mode.SRC_ATOP);
        this.invalidate();
    }

    /**
     * Sets the stroke width to be drawn around the CircularImageView
     * during click events when the selector is enabled.
     *
     * @param selectorStrokeWidth
     */
    public void setSelectorStrokeWidth(int selectorStrokeWidth) {
        this.selectorStrokeWidth = selectorStrokeWidth;
        this.requestLayout();
        this.invalidate();
    }

    /**
     * Sets the stroke color to be drawn around the CircularImageView
     * during click events when the selector is enabled.
     *
     * @param selectorStrokeColor
     */
    public void setSelectorStrokeColor(int selectorStrokeColor) {
        if (paintSelectorBorder != null)
            paintSelectorBorder.setColor(selectorStrokeColor);
        this.invalidate();
    }

    /**
     * Adds a dark shadow to this CircularImageView.
     */
    public void addShadow() {
        setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
        paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
    }


    @Override
    public void onDraw(Canvas canvas) {
        // Don't draw anything without an image
        if(image == null)
            return;

        // Nothing to draw (Empty bounds)
        if(image.getHeight() == 0 || image.getWidth() == 0)
            return;

        // Compare canvas sizes
        int oldCanvasSize = canvasSize;

        canvasSize = canvas.getWidth();
        if(canvas.getHeight() < canvasSize)
            canvasSize = canvas.getHeight();

        // Reinitialize shader, if necessary
        if(oldCanvasSize != canvasSize)
            refreshBitmapShader();

        // Apply shader to paint
        paint.setShader(shader);

        // Keep track of selectorStroke/border width
        int outerWidth = 0;

        // Get the exact X/Y axis of the view
        int center = canvasSize / 2;


        if(hasSelector && isSelected) { // Draw the selector stroke & apply the selector filter, if applicable
            outerWidth = selectorStrokeWidth;
            center = (canvasSize - (outerWidth * 2)) / 2;

            paint.setColorFilter(selectorFilter);
            canvas.drawCircle(center + outerWidth, center + outerWidth, ((canvasSize - (outerWidth * 2)) / 2) + outerWidth - 4.0f, paintSelectorBorder);
        }
        else if(hasBorder) { // If no selector was drawn, draw a border and clear the filter instead... if enabled
            outerWidth = borderWidth;
            center = (canvasSize - (outerWidth * 2)) / 2;

            paint.setColorFilter(null);
            canvas.drawCircle(center + outerWidth, center + outerWidth, ((canvasSize - (outerWidth * 2)) / 2) + outerWidth - 4.0f, paintBorder);
        }
        else // Clear the color filter if no selector nor border were drawn
            paint.setColorFilter(null);

        // Draw the circular image itself
        canvas.drawCircle(center + outerWidth, center + outerWidth, ((canvasSize - (outerWidth * 2)) / 2) - 4.0f, paint);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        // Check for clickable state and do nothing if disabled
        if(!this.isClickable()) {
            this.isSelected = false;
            return super.onTouchEvent(event);
        }

        // Set selected state based on Motion Event
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                this.isSelected = true;
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_SCROLL:
            case MotionEvent.ACTION_OUTSIDE:
            case MotionEvent.ACTION_CANCEL:
                this.isSelected = false;
                break;
        }

        // Redraw image and return super type
        this.invalidate();
        return super.dispatchTouchEvent(event);
    }

    public void invalidate(Rect dirty) {
        super.invalidate(dirty);
        image = drawableToBitmap(getDrawable());
        if(shader != null || canvasSize > 0)
            refreshBitmapShader();
    }

    public void invalidate(int l, int t, int r, int b) {
        super.invalidate(l, t, r, b);
        image = drawableToBitmap(getDrawable());
        if(shader != null || canvasSize > 0)
            refreshBitmapShader();
    }

    @Override
    public void invalidate() {
        super.invalidate();
        image = drawableToBitmap(getDrawable());
        if(shader != null || canvasSize > 0)
            refreshBitmapShader();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    private int measureWidth(int measureSpec) {
        int result;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            // The parent has determined an exact size for the child.
            result = specSize;
        }
        else if (specMode == MeasureSpec.AT_MOST) {
            // The child can be as large as it wants up to the specified size.
            result = specSize;
        }
        else {
            // The parent has not imposed any constraint on the child.
            result = canvasSize;
        }

        return result;
    }

    private int measureHeight(int measureSpecHeight) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpecHeight);
        int specSize = MeasureSpec.getSize(measureSpecHeight);

        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            // The child can be as large as it wants up to the specified size.
            result = specSize;
        } else {
            // Measure the text (beware: ascent is a negative number)
            result = canvasSize;
        }

        return (result + 2);
    }

    /**
     * Convert a drawable object into a Bitmap
     *
     * @param drawable
     * @return
     */
    public Bitmap drawableToBitmap(Drawable drawable) {
        if (drawable == null) { // Don't do anything without a proper drawable
            return null;
        }
        else if (drawable instanceof BitmapDrawable) { // Use the getBitmap() method instead if BitmapDrawable
            return ((BitmapDrawable) drawable).getBitmap();
        }

        // Create Bitmap object out of the drawable
        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;
    }

    /**
     * Reinitializes the shader texture used to fill in
     * the Circle upon drawing.
     */
    public void refreshBitmapShader() {
        shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvasSize, canvasSize, false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    }

    /**
     * Returns whether or not this view is currently
     * in its selected state.
     */
    public boolean isSelected() {
        return this.isSelected;
    }
}
公共类CircularImageView扩展了ImageView{
//边界和选择器配置变量
私有边界;
私人选民;
私人选举;
私有int边界宽度;
私人int画布尺寸;
私有int选择器行程宽度;
//用于实际图形的对象
私有位图着色器;
私有位图图像;
私人油漆;
私人油漆厂;
私人油漆工订单;
专用彩色滤光片选择器滤光片;
公共CircularImageView(上下文){
这个(上下文,空);
}
公共CircularImageView(上下文、属性集属性)
{
这(上下文、属性、R.attr.circularImageViewStyle);
}
公共CircularImageView(上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
init(上下文、属性、定义样式);
}
/**
*初始化绘制对象并设置所需的属性。
*
*@param上下文
*@param attrs
*@param defStyle
*/
私有void init(上下文上下文、属性集attrs、int-defStyle){
//初始化绘制对象
油漆=新油漆();
paint.setAntiAlias(真);
paintBorder=新绘制();
paintBorder.setAntiAlias(true);
paintSelectorOrder=新油漆();
paintSelectorOrder.setAntiAlias(true);
//加载已设置样式的属性并设置其属性
TypedArray attributes=context.ActainStyledAttributes(attrs,R.styleable.CircularImageView,defStyle,0);
//检查是否启用了边框和/或边框
hasBorder=attributes.getBoolean(R.styleable.CircularImageView\u border,false);
hasSelector=attributes.getBoolean(R.styleable.CircularImageView_选择器,false);
//设置边框属性(如果启用)
if(hasBorder){
int defaultBorderSize=(int)(2*context.getResources().getDisplayMetrics().density+0.5f);
setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_border_width,defaultBorderSize));
setBorderColor(attributes.getColor(R.styleable.CircularImageView_border_color,color.WHITE));
}
//设置选择器属性(如果启用)
如果(选举人){
int defaultSelectorSize=(int)(2*context.getResources().getDisplayMetrics().density+0.5f);
设置选择器颜色(attributes.getColor(
R.styleable.CircularImageView_选择器_颜色,color.TRANSPARENT));
setSelectorStrokeWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_selector_stroke_width,defaultSelectorSize));
setSelectorStrokeColor(attributes.getColor(R.styleable.CircularImageView_selector_stroke_color,color.BLUE));
}
//如果启用,则添加阴影
if(attributes.getBoolean(R.styleable.CircularImageView_shadow,false))
addShadow();
//我们不再需要我们的属性类型Darray,把它还给缓存
attributes.recycle();
}
/**
*以像素为单位设置CircularImageView的边框宽度。
*
*@param-borderWidth
*/
公共边框宽度(整型边框宽度){
this.borderWidth=borderWidth;
这个.requestLayout();
这个。使无效();
}
/**
*设置CircularImageView的基本边框颜色。
*
*@param borderColor
*/
公共颜色(整型边框颜色){
if(paintBorder!=null)
paintBorder.setColor(borderColor);
这个。使无效();
}
/**
*设置要绘制的选择器的颜色
*CircularImageView。请确保提供一些不透明度。
*
*@param selectorColor
*/
公共无效设置选择器颜色(int选择器颜色){
this.selectorFilter=新的PorterDuffColor过滤器(selectorColor,PorterDuff.Mode.SRC_);
这个。使无效();
}
/**
*设置围绕CircularImageView绘制的笔划宽度
*在启用选择器的单击事件期间。
*
*@param选择器行程宽度
*/
公共void设置选择器行程宽度(int选择器行程宽度){
this.selectorStrokeWidth=selectorStrokeWidth;
这个.requestLayout();
这个。使无效();
}
/**
*设置要围绕CircularImageView绘制的笔划颜色
*在启用选择器的单击事件期间。
*
*@param selectorStrokeColor
*/
public void setSelectorStrokeColor(int-selectorStrokeColor){
if(paintSelectorOrder!=null)
paintSelectorOrder.setColor(selectorStrokeColor);
这个。使无效();
}
/**
*向此CircularImageView添加一个暗影。
*/
公共void addShadow(){
setLayerType(LAYER_TYPE_软件,paintBorder);
paintBorder.setShadowLayer(4.0f、0.0f、2.0f,彩色。黑色);
}
@凌驾
公共空白onDraw(画布){
//不要画没有图像的东西
if(image==null)
返回;
//无需绘制(空边界)
if(image.getHeight()==0 | | image.getWidth()==0)
返回;
//比较画布大小
int oldCanvasSize=画布大小;
canvasSize=canvas.getWidth();
if(canvas.getHeight()public void refreshBitmapShader() {        
    int left = 0; y = 0; w = image.getWidth(), h = image.getHeight(); 
    // decide whether we have to crop the sizes or the top and bottom:
    if(w > h)  // width is greater than height
    {
        x = (w - h) >> 1;   // crop sides, half on each side
        w = h;
    }
    else
    {
        y = (h - w) >> 1;   // crop top and bottom
        h = w;
    }
    Matrix m = new Matrix();
    float scale = (float)canvasSize / (float)w;
    m.preScale(scale, scale);   // scale to canvas size
    shader = new BitmapShader(Bitmap.createBitmap(image, x, y, w, h, m, false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
}