平行四边形的效果实现

要实现的效果图如下:

平行四边形的效果实现_第1张图片


实现此效果的第一思路是使用Path 和canvas实现,path来规定平行四边形。

实现如下

布局文件



    


TestView类实现

package com.whuthm.imageshape;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

public class TestView extends ImageView {

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

	public TestView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

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

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		int width = getWidth();
		int height = getHeight();

		Drawable d = getResources().getDrawable(R.drawable.image1);
		d.setBounds(0, 0, width, height);

		canvas.save();
		//一个平行四边形
		Path path = new Path();
		path.moveTo(100, 0);
		path.lineTo(0, height);
		path.lineTo(width - 100, height);
		path.lineTo(width, 0);
		canvas.clipPath(path);
		//将图像画在canvas上
		d.draw(canvas);
		canvas.restore();

	}

}
效果实现,但是一个很严重的问题是锯齿很严重,而且对paint,bitmapshader,或者canvas使用抗锯齿也无效。效果图如下:

平行四边形的效果实现_第2张图片


另一种解决方法是,使用ShapeDrawable

方法:根据ImageView的drawable创建一个shapedrawable,并设置shapedrawable的shape, 然后在ondraw方法中设置位图渲染,设置区域,然后将shapedrawable画在canvas上。

布局文件



    

    


关键类ShapeImageView
package com.whuthm.imageshape;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Bitmap.Config;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.Shape;
import android.util.AttributeSet;
import android.widget.ImageView;

public class ShapeImageView extends ImageView {

	public static final String TAG = "ShapeImageView";

	private ShapeDrawable mShapeDrawable;

	private Shape mShape;

	private boolean mIsShape;

	private boolean mRebuildShape;

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

	public ShapeImageView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

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

	//设置shape
	public void setShap(Shape shape) {
		mShape = shape;
		mIsShape = true;
		mRebuildShape = true;
	}

	@SuppressLint("DrawAllocation")
	@Override
	protected void onDraw(Canvas canvas) {

		if (mIsShape) {
			//获取ImageView的drawble,当调用过setShape方法时,走下面的流程
			Drawable oldDrawable = getDrawable();
			if (oldDrawable == null || mShape == null) {
				return;
			}

			Rect bounds = oldDrawable.getBounds();

			if (bounds == null || bounds.width() == 0 || bounds.height() == 0) {
				return;
			}
			if (mShapeDrawable == null) {
				mShapeDrawable = new ShapeDrawable();
			}
			//设置shapedrawable的bounds
			mShapeDrawable.setBounds(bounds);

			if (mRebuildShape) {
				mRebuildShape = false;
				//获取bitmap
				Bitmap bm = drawableToBitmap(oldDrawable);
				if (bm == null) {
					return;
				}
				//创建一个bitmapshader,shapedrawable设置这个位图渲染
				BitmapShader bitmapShader = new BitmapShader(bm,
						TileMode.CLAMP, TileMode.CLAMP);
				mShapeDrawable.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
				mShapeDrawable.getPaint().setStyle(Paint.Style.FILL);
				mShapeDrawable.getPaint().setShader(bitmapShader);
				mShapeDrawable.setShape(mShape);
			}

			//当时平行四边形时设置Shape的所在区域
			if (mShape instanceof ParallelogramShape) {
				((ParallelogramShape) mShape).setRect(bounds);
			}

			int paddingTop = getPaddingTop();
			int paddingLeft = getPaddingLeft();
			// int paddingRight = getPaddingRight();
			// int paddingBottom = getPaddingBottom();
			// Matrix imageMatrix = getImageMatrix();
			// int left = getLeft();
			// int top = getTop();
			// int right = getRight();
			// int bottom = getBottom();

			//将mShapeDrawable画在canvas
			if (paddingTop == 0 && paddingLeft == 0) {
				mShapeDrawable.draw(canvas);
			} else {
				int saveCount = canvas.getSaveCount();
				canvas.save();

				canvas.translate(paddingLeft, paddingTop);
				mShapeDrawable.draw(canvas);
				canvas.restoreToCount(saveCount);
			}
		} else {
			super.onDraw(canvas);
		}

	}

	//此方法用于创建一个bitmap
	public static Bitmap drawableToBitmap(Drawable drawable) {
		if (drawable == null || drawable.getBounds() == null) {
			return null;
		}

		// if (drawable instanceof BitmapDrawable) {
		// return ((BitmapDrawable) drawable).getBitmap();
		// }

		Bitmap bitmap;
		int width = drawable.getBounds().width();
		int height = drawable.getBounds().height();
		try {
			bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
			Canvas canvas = new Canvas(bitmap);
			drawable.draw(canvas);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			bitmap = null;
		}
		return bitmap;
	}

}

平行四边形shape :ParallelogramShape

package com.whuthm.imageshape;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.shapes.Shape;

public class ParallelogramShape extends Shape {

    Path path;

    Rect rect;
    int offset;

    float scale = -1f;

    ParallelogramShape() {
        path = new Path();
    }

    public void setRect(Rect rect) {
        this.rect = rect;
    }

    public void setOffset(int offset) {
        this.offset = offset;
    }

    public void setScale(float scale) {
        this.scale = scale;
    }

    //此方法设置path,path为平行四边形
    @Override
    public void draw(Canvas canvas, Paint paint) {
        if (rect == null || rect.width() <= 0 || rect.height() <= 0) {
            return;
        }
        if (scale > 0.0f && scale < 1.0f) {
            offset = (int) (scale * rect.width());
        }
        path.reset();
        path.moveTo(offset, rect.left);
        path.lineTo(rect.left, rect.bottom);
        path.lineTo(rect.right - offset, rect.bottom);
        path.lineTo(rect.right, 0);
        canvas.drawPath(path, paint);
    }

}

activity如下:

package com.whuthm.imageshape;

import android.os.Bundle;
import android.app.Activity;

public class MainActivity extends Activity {

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

        //创建一个平行四边形的shape
        ParallelogramShape shape = new ParallelogramShape();
        shape.setScale(0.2f);
        ((ShapeImageView) findViewById(R.id.image1)).setShap(shape);

    }

}

效果图如下:

平行四边形的效果实现_第3张图片



代码链接

你可能感兴趣的:(android,launcher)