1、前言
在前一篇博客当中提到关于Drawable的一些常用的用法,和使用系统自身的提供Drawable子类,来实现一定的具有功能性的Drawable,那么在今天的博客当中,我们就去自己定义Drawable的子类去实现我们自己功能的Drawable,
2、正文
首先我们去自己考虑一下,自定义Drawable是什么,先不着急,我们思考一下Android系统为我们提供的Drawable的子类实现,我们明确是对我们原有的图片进行一定的封装,然后进行一定的处理,让它和原来的最根本的res资源Drawable有某一种小功能,比如我们的ClipDrawable,ScaleDrawable,RotateDrawable,第一个是对原有的res资源Drawable有裁剪的功能,第二ScaleDrawable,是对原有的的res下的根本Drawable有一定的缩放功能,而第三个RotateDrawable就是对原来最原始的Drawable有一定的旋转功能。我们自定义Drawable首先我们要明确我们自定义的Drawable去实现什么功能,在这里我们去实现一个百叶窗的动画效果,百叶窗效果:为了和原图作比较,我们把原图和百叶窗的效果一起展示出来,
首先来看我们的自定义Drawable,我们起名为ShuttersDrawable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.drawable.Drawable;
public class ShuttersDrawable extends Drawable{
private Bitmap mBitmap; private Bitmap[] mBitmaps; private int mWidth; private int mHeight; private int mCellWidth; private int mCount; private Paint mPaint; private float scale = 1f;
public ShuttersDrawable(Bitmap bitmap, int count){ this.mBitmap = bitmap; this.mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); this.mCount = count; initBitmap(); }
private void initBitmap() { this.mHeight = mBitmap.getHeight(); this.mWidth = mBitmap.getWidth(); mCellWidth = mWidth / mCount; mBitmaps = new Bitmap[mCount]; }
@Override public void draw(Canvas canvas) { canvas.save(); float width = (mCellWidth * scale) + 1; if(width >= mCellWidth){ width = mCellWidth; } for(int i = 0 ; i < mBitmaps.length; i++){ mBitmaps[i] = Bitmap.createBitmap(mBitmap, i * mCellWidth, 0,(int)width, mHeight); canvas.drawBitmap(mBitmaps[i], i * mCellWidth, 0, mPaint); } canvas.restore(); }
public void setScale(float mScale){ this.scale = mScale; invalidateSelf(); }
@Override public int getIntrinsicWidth() { return mBitmap.getWidth(); }
@Override public int getIntrinsicHeight() { return mBitmap.getHeight(); }
@Override public int getOpacity() { return PixelFormat.TRANSLUCENT; }
@Override public void setAlpha(int alpha) { mPaint.setAlpha(alpha); }
@Override public void setColorFilter(ColorFilter cf) { mPaint.setColorFilter(cf); } }
|
自定义Drawable我们首先需要继承Drawable,有几个方法我们是必须所要实现的那就是
- 1、draw(Canvas canvas):就是使用参数Canvas画布对象,给该Drawable画上内容的方法。
- getOpacity():
- setAlpha(int alpha):设置透明度
- setColorFilter(ColorFilter cf):设置颜色过滤。
其余我写的都比较简单,大家应该都能看懂是什么意思,我也就不献丑了。说一下具体的思路。就是我们把Bitmap分成一个个的叶片对象,然后对叶片对象进行绘制,然后通过sclae比例去控制绘制叶片的宽度,
activity_main.xml layout:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center_horizontal"> <ImageView android:layout_width="wrap_content" android:layout_height="0dip" android:layout_weight="1" android:background="#F00" android:src="@drawable/pressed"/>
<ImageView android:id="@+id/iv_imageView" android:layout_width="wrap_content" android:background="#0F0" android:layout_height="0dip" android:layout_weight="1"/>
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="click me start Animator" android:onClick="click"/>
</LinearLayout>
|
使用Button来控制开启动画,
再来我们就看看在Activity中的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
public class MainActivity extends Activity { private ShuttersDrawable mShuttersDrawable;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initImageView(); } private void initImageView() { ImageView iv = (ImageView) findViewById(R.id.iv_imageView); Bitmap decodeResource = BitmapFactory.decodeResource(getResources(), R.drawable.pressed); mShuttersDrawable = new ShuttersDrawable(decodeResource, 5); iv.setImageDrawable(mShuttersDrawable); }
@SuppressLint("NewApi") public void click(View view){ ValueAnimator mValueAnimation = ValueAnimator.ofFloat(0f, 1f). setDuration(10000); mValueAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @SuppressLint("NewApi") @Override public void onAnimationUpdate(ValueAnimator animation) { float animatedValue = (Float) animation.getAnimatedValue(); mShuttersDrawable.setScale(animatedValue); } }); mValueAnimation.start(); } }
|
效果呢就如开头那样所示。
上述就是如何通过自定义Drawable去实现百叶窗的效果,
2、通过自定义View去实现一些关于画图
接下来我们去探讨第二个问题,我们以前会去通过自定义View去实现一些关于画图的东西其实都可以通过自定义Drawable去实现,比如鸿洋大神可以通过自定义Drawable去实现圆角图片一样,这个时候我们想到的也许就是去自定义Imageview去实现,大家应该发现了,自定义Drawable就可以看做是自定义View的一种轻量级实现,下面我们看看一种效果,然后我们去自定义这种效果,这种效果叫什么呢,我也不知,总之我们看吧!
这种类似于专辑盒的Icon,在各大音乐平台多的是,相信大家也都做过,我们可以类似于这样的专辑盒去做一个自定义Drawable,好了废话少说,我们开始干活。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| package vadsdk.testdrawable.drawable;
import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.drawable.Drawable;
import vadsdk.testdrawable.R;
public class AlbumDrawable extends Drawable {
private Paint mPaint;
private Bitmap mLeftDrawable;
private Bitmap mBackgoundDrawable;
private Bitmap mContentBitmap;
private Context mContext;
public AlbumDrawable(Bitmap bitmap, Context context) { this.mContentBitmap = bitmap; this.mContext = context; init(); }
private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mLeftDrawable = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.album_chart_left); }
@Override public void draw(Canvas canvas) { onDrawLeftDrawable(canvas); onDrawLeftBitmap(canvas); onDrawDrawable(canvas); }
private void onDrawLeftDrawable(Canvas canvas) { canvas.save(); canvas.translate(mLeftDrawable.getWidth()/2f, mLeftDrawable.getWidth() * 3f/5f); Bitmap zoomBitmap = zoomBitmap(mContentBitmap, 1/6f); canvas.drawBitmap(zoomBitmap, 0, 0, mPaint); canvas.restore(); }
private void onDrawDrawable(Canvas canvas) { canvas.save(); canvas.translate(mLeftDrawable.getWidth(), 0); Bitmap zoomBitmap = zoomBitmap(mContentBitmap , mLeftDrawable.getHeight()-3); canvas.drawBitmap(zoomBitmap, 0, 0, mPaint); canvas.restore(); }
private void onDrawLeftBitmap(Canvas canvas) { canvas.save(); canvas.drawBitmap(mLeftDrawable, 0, 0, mPaint); canvas.restore(); }
private Bitmap zoomBitmap(Bitmap bitmap, int h){ int width = bitmap.getWidth(); int height = bitmap.getHeight();
float scaleHeight = ((float)h)/height;
Matrix matrix = new Matrix(); matrix.postScale(scaleHeight, scaleHeight); return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); }
private Bitmap zoomBitmap(Bitmap bitmap, float scale){ int width = bitmap.getWidth(); int height = bitmap.getHeight(); Matrix matrix = new Matrix(); matrix.postScale(scale, scale); return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); }
@Override public int getOpacity() { return PixelFormat.TRANSLUCENT; }
@Override public void setAlpha(int alpha) { mPaint.setAlpha(alpha); }
@Override public void setColorFilter(ColorFilter cf) { mPaint.setColorFilter(cf); } }
|
我们现在自己定义了一个Drawable,我说一下思路,大体的思路就是对Bitmap做一定的操作,然后根据宽高去摆放,使用Bitmap去缩放小的海报,然后使用左侧的图片去盖住右侧的图片,主要就是计算方面,博主写的计算方法也有偏差,可以自己明确计算规则写自己的逻辑。
下来在我们的Activity当中使用我们定义的Drawable
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class MainActivity extends AppCompatActivity {
private ImageView iv;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv_imageView); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.album); AlbumDrawable albumDrawable = new AlbumDrawable(bitmap, this); iv.setImageDrawable(albumDrawable); } }
|
效果如下:
以上就是自定义Drawable