在上篇博客一起来说说那些你不知道的Drawable中,我们介绍了各类的Drawable对象,对各个属性也进行了介绍。当然还有一些疑惑点还没解释,我们暂且搁置一边,先来根据各个属性做个练习。Let’s go!!
算作一个小系列吧!
在这里给大家推荐一个在线查看shape效果的网站:
http://angrytools.com/android/button/
案例一、带边框的圆角背景图
分析:
- 边框线:边框线的绘制我们需要使用stroke标签
- 圆角:使用corners标签
即我们的shape文件的配置如下:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<padding android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp" />
<corners android:radius="8dp"/>
<stroke android:width="1dp" android:color="#646464"/>
</shape>
是不是很简单,在也不用可怜巴巴的找美工的切图了。
案例二、实现下划线背景
在实际开发中,我们经常可以看到布局中间充斥着一些线条,有些同学使用一个view进行模拟。
<View
android:layout_height="0.5dp"
android:layout_width="match_parent"
android:backgroud="#808080"/>
这样是不是很low,而且还在布局文件中防止了大量的控件,降低了布局的解析速度,降低了效率。熟练使用各类drawable,即可帮助我们解决这个问题。
分析:既然实现下划线背景,说明我们还是要描边,即需要stroke标签,但是仔细想想,系统给我们提供的描边,是对四个边都进行描边,那我们怎么实现只有下划线的描边呢?这里我们可以换种思路,即利用layer-list,通过图层的叠盖,达到效果。
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle">
<stroke android:color="#606060" android:width="1dp"/>
</shape>
</item>
<item android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="#FFFFFF"/>
</shape>
</item>
</layer-list>
在第一个图层item中,我们实现了边框。在第二个图层item中,我们通过设置paddingBottom属性达到覆盖效果。
相应的,我们通过修改left,right,top可以实现上下左右边框线的效果。
案例三、实现灰色背景效果
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true">
<shape android:shape="rectangle">
<stroke android:width="0.5dp" android:color="#909090"/>
<solid android:color="#606060"/>
<corners android:radius="2dp"/>
</shape>
</item>
<item android:state_pressed="false">
<shape android:shape="rectangle">
<stroke android:width="0.5dp" android:color="#909090"/>
<solid android:color="#FFFFFF"/>
<corners android:radius="2dp"/>
</shape>
</item>
</selector>
效果图:
案例四、实现圆形图片
在许久以前,刚写博客的时候,写了一个自定义圆形控件,Android自定义控件之圆形头像在这篇文章中采用了重写ImageView方法进行。这次我们采用自定义Drawable来达到我们的效果。
根据一起来说说那些你不知道的Drawable文章,我们知道系统给我们重写Drawable而得来的几个子类,它们也是通过继承Drawable而来,所以我们同样也可以。查看Drawable源码,我们需要明白以下几个方法:
- public abstract void draw(Canvas canvas);用来在drawable的bounds内进行绘制。
- public void setBounds(int left, int top, int right, int bottom),用来设定drawable的范围
- public void setDither(boolean dither),是否放置抖动
- public void setFilterBitmap(boolean filter),当绘制bitmap时使用,如果不涉及可以忽略,典型针对BitmapDrawable
- public abstract void setAlpha(int alpha),设置透明度,范围0——255
- public abstract void setColorFilter(ColorFilter cf);设置颜色过滤器
- public abstract int getOpacity(),返回这个drawable是否透明,PixelFormat.UNKNOWN、PixelFormat.TRANSLUCENT(半透明)、PixelFormat.TRANSPARENT(透明)、PixelFormat.OPAQUE(不透明)
- public int getIntrinsicWidth():drawable的宽度
- public int getIntrinsicHeight():drawable的高度
public class CircleDrawable extends Drawable {
private Paint mPaint;
private int cx,cy,radius;
private int mWidth;
private Bitmap mBitmap ;
public CircleDrawable(Bitmap bitmap){
mBitmap = bitmap ;
mPaint = new Paint();
mPaint.setShader(new BitmapShader(bitmap,TileMode.CLAMP,TileMode.CLAMP));
mPaint.setAntiAlias(true);
mWidth = Math.min(mBitmap.getWidth(), mBitmap.getHeight());
}
@Override
public void setBounds(int left, int top, int right, int bottom) {
super.setBounds(left, top, right, bottom);
cx = (left + right)/2;
cy =(top + bottom)/2;
radius = Math.abs(right - left) /2 - Math.abs(bottom - top) /2 > 0 ? Math.abs(bottom - top) /2:Math.abs(right - left) /2;
}
@Override
public void draw(Canvas canvas) {
canvas.drawCircle(cx, cy, radius, mPaint);
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public int getIntrinsicWidth() {
return mWidth;
}
@Override
public int getIntrinsicHeight() {
return mWidth;
}
}
这里,我们自定义,所以就没有办法在xml中进行使用,就得用代码了,通过设置drawable:
btn_btn.setBackgroundDrawable(new CircleDrawable(bitmap));
iv.setImageDrawable(circleDrawable);
大家可以注意到,ImageView的展示还是蛮正常的,但是Button的背景就不正常了,这是为什么呢?大家查看源码思考下。
暂时想到这么多,其实只要基础的原理会了,自然写起来就方便。后面想起来在补吧!如果大家有比较好的案例,欢迎推荐。