可拉的是什么?
-
<李>一种可以在画布上进行绘制的抽象的概念李>
<李>颜色,图片等都可以是一个可拉的李>
<李>可拉的可以通过XML定义,或者通过代码创建李>
<李> Android中可提取是一个抽象类,每个具体的可拉的都是其子类李>
可拉的的优点
-
<李>使用简单,比自定义观点成本低李>
<李>非图片类的可拉的所占空间小,能减小apk大小李>
在实际的开发工程中,不免想有一个中间是空洞的可拉的,也就是中间是透明的,而其他区域正常显示的可拉的。
-
<李>主要用到的技术是PorterDuffXfermode的PorterDuff.Mode.XOR模式李>
<李>核心思想是先正常绘制出整个可拉的,然后将指定的区域混合成透明色李>
<强>看下主要代码代码强>
公共空画(@NonNull帆布画布){//将绘制操作保存到新的图层,因为图像合成是很昂贵的操作,将用到硬件加速,这里将图像合成的处理放到离屏缓存中进行 int saveCount=画布。saveLayer (0, 0, canvas.getWidth (), canvas.getHeight (), srcPaint, Canvas.ALL_SAVE_FLAG);//dst绘制目标图层 innerDrawable.draw(画布);//设置混合模式 srcPaint。setXfermode(新PorterDuffXfermode (PorterDuff.Mode.CLEAR));//src绘制源图 画布。drawPath (srcPath srcPaint);//清除混合模式 srcPaint.setXfermode(空);//还原画布 canvas.restoreToCount (saveCount); }
在上面的代码中,有的人可能认为需要关闭硬件加速,即
setLayerType(视图。LAYER_TYPE_SOFTWARE, null);
但在实际的操作中,采用锁定画布的方式能有效的避免硬件加速同步所造成的不正常显示,而且锁定的帆布能在缓存中进行正常计算,在释放锁后进行渲染,所以请不要关闭硬件加速功能。
上图的布局文件是
& lt; FrameLayout android: layout_width=" match_parent " android: layout_height=癿atch_parent”比; & lt; ImageView android: layout_width=" match_parent " android: layout_height=" match_parent " android:背景=癅drawable/crop_image_bg”/比; & lt; com.jian.cropimage.CoverView android: layout_width=" match_parent " android: layout_height=" match_parent " android:背景=癅color/crop_image_cover_view_bg”比; & lt; !,根据这个子视图所在的位置,计算出透明矩形的位置,开发时的所见即所得——比; & lt; ImageView android: id=癅 + id/crop_image_cover_view_hole” android: layout_width=" 250 dp” android: layout_height=" 250 dp” android: layout_gravity="中心"/比; & lt;/com.jian.cropimage.CoverView> & lt;/FrameLayout>
进口android.graphics.Canvas; 进口android.graphics.ColorFilter; 进口android.graphics.Paint; 进口android.graphics.Path; 进口android.graphics.PorterDuff; 进口android.graphics.PorterDuffXfermode; 进口android.support.annotation.NonNull; 进口android.support.annotation.Nullable;/* * *说明:支持中间出现透明区域的可拉的& lt; br/比; *通过{@link # setSrcPath(路径)}设定透明区域的形状& lt; br/比; *杨健 *时间:2017/9/4。 */公开课HoleDrawable延伸可拉的{ 私人油漆srcPaint; 私人路径srcPath=new路径(); 私人可拉的innerDrawable; 公共HoleDrawable(可拉的innerDrawable) { 这一点。innerDrawable=innerDrawable; srcPath。addRect (100、100、200、200、Path.Direction.CW); srcPaint=new油漆(Paint.ANTI_ALIAS_FLAG); srcPaint.setColor (0 xffffffff); }/* * *设置内部透明的部分 * * @param srcPath */公共空间setSrcPath(路径srcPath) { 这一点。srcPath=srcPath; } @Override 公共空画(@NonNull帆布画布){ innerDrawable.setBounds (getBounds ()); 如果(srcPath==null | | srcPath.isEmpty ()) { innerDrawable.draw(画布); 其他}{//将绘制操作保存到新的图层,因为图像合成是很昂贵的操作,将用到硬件加速,这里将图像合成的处理放到离屏缓存中进行 int saveCount=画布。saveLayer (0, 0, canvas.getWidth (), canvas.getHeight (), srcPaint, Canvas.ALL_SAVE_FLAG);//dst绘制目标图 innerDrawable.draw(画布);//设置混合模式 srcPaint。setXfermode(新PorterDuffXfermode (PorterDuff.Mode.CLEAR));//src绘制源图 画布。drawPath (srcPath srcPaint);//清除混合模式 srcPaint.setXfermode(空);//还原画布 canvas.restoreToCount (saveCount); } } @Override 公共空间setAlpha (intα){ innerDrawable.setAlpha(α); } @Override 公共空间setColorFilter (@Nullable ColorFilter ColorFilter) { innerDrawable.setColorFilter (colorFilter); } @Override 公共int getOpacity () { 返回innerDrawable.getOpacity (); } }Android自定义可拉的之在可拉的中部指定透明区域方法示例