**0.0
东西到这里差不多到一段落了,整体效果还算比较成功的,好像就焦点释放有些问题,当然还有很多瑕疵,这个完全可以根据自己需求去修改啦,我有空也会改改的。
**
先放图:
上篇文章投稿“程序员”的时候被驳回了,原因是因为图片不雅观,所以这次就换了几张图。····
下面讲讲主要更新的几个地方:
(一)图层的缩放?
图层的缩放需要计算双指最开始Down下的距离与Move过程中的距离的比值。
而所得出的scale比例都必须在上次scale的前提下进行,多指触控的代码我就不放出来了,大家可以去去看demo
图片缩放的代码如下,这里采用的是Matrix的缩放:
/**
* 缩放图层
*
* @param toSacle
*/
protected void scaleLayer(float toSacle) {
scale = scale * toSacle;
if (scale >= max_scale)
scale = max_scale;
if (scale <= min_scale)
scale = min_scale;
Bitmap scaleLayer;
if (filterLayer != null) {
scaleLayer = BitmapUtils.scaleBitmap(filterLayer, scale);
} else {
scaleLayer = BitmapUtils.scaleBitmap(layer, scale);
}
BitmapUtils.destroyBitmap(drawLayer);
drawLayer = scaleLayer;
// 更新Layer的坐标
setLayerX(x - (drawLayer.getWidth() - width) / 2);
setLayerY(y - (drawLayer.getHeight() - height) / 2);
width = drawLayer.getWidth();
height = drawLayer.getHeight();
}
(二)如何替换图片顺序?
先来分析下替换图层顺序的是一个什么样情景:
1.手指选中一张图层进行拖拽
2.拖拽过程中,坐标超出图层范围(这里并不只针对layer的范围,还有一个平移的最大边境)
3.拖拽至其他非选中layer范围当中,在松手的同时,切换相对应的图层。
这里感觉困难的地方主要还是在情景状态的判断,与ui变化,真要文字描述起来还挺烦人的,所以小伙伴们还是去看代码吧,这里就不写啦···
(三)如何设置图片滤镜?
滤镜使用的是之前在Matrix(三)自己封装的ColorFilter类。
在绘制的时候新增了一个的图片对象,当判断滤镜图片不为空的时候,所进行的图片缩放使用不在是原图,而是滤镜图片,代码如下:
/**
* 设置滤镜图片
*
* @param filterLayer
*/
public void setFilterLayer(Bitmap filterLayer) {
this.filterLayer = filterLayer;
//因为当前绘制的图片使用的是原图(或者滤镜图)缩放过后的图,
//所以当有滤镜图存在的同时需要将滤镜图进行缩放
scaleLayer(1);
}
/**
* 去除滤镜图
![Upload filter.gif failed. Please try again.]
*/
public void clearFilter() {
BitmapUtils.destroyBitmap(filterLayer);//方法里有致空操作
filterLayer = null;
scaleLayer(1);
}
这个挺简单的,如果当你们的滤镜比较耗时时,处理完成之后将图片设置回来即可,当然我还没有做图层内部的刷新,所以在设置完图片滤镜之后需要刷新modelview。
(四)如何在图层上面进行弹窗?
我将重新封装了一层PosterView继承RelativeLayout,将modelview和菜单的view都添加在里面,主要代码:
private void viewInit() {
modelView = new ModelView(getContext());
modelParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
addView(modelView, modelParams);
}
/**
* 滤镜菜单初始化,并设置宽高
*
* @param menu
* @param menuWidth
*/
public void addMenuInit(View menu, int menuWidth, int menuHeight) {
this.menu = menu;
menuParams = new LayoutParams(menuWidth, menuHeight);
addView(menu, menuParams);
menu.setVisibility(GONE);
}
public void dissMenu() {
if (null != menu)
menu.setVisibility(GONE);
}
public void showMenu(Layer layer) {
Layer.MenuPoint menuPoint = layer.getFrontMenuPoint(getHeight(), menuParams.height);
PointF pointf = menuPoint.point;
if (pointf.x + menuParams.width >= width) {
pointf.x = width - menuParams.width;
}
if (menuPoint.direction == 1) {
pointf.y = pointf.y - menuParams.height;
}
menuParams.setMargins((int) pointf.x, (int) pointf.y, 0, 0);
menu.setLayoutParams(menuParams);
if (null != menu)
menu.setVisibility(VISIBLE);
}
上面代码中的 Layer.MenuPoint 乃是我在layer中计算出合适的菜单弹出的位置
/**
* 计算出菜单弹出的最优点
*
* @return
*/
public MenuPoint getFrontMenuPoint(int height, int menuHeight) {
PointF point = new PointF();
MenuPoint menuPoint = null;
if (height - MaxMenuPadding < layerRectF.bottom + menuHeight) {
point.set(layerRectF.left, layerRectF.top);
menuPoint = new MenuPoint(1, point);
} else {
point.set(layerRectF.left, layerRectF.bottom);
menuPoint = new MenuPoint(0, point);
}
return menuPoint;
}
/**
* 定义菜单坐标对象,
* direction对应方向,0代表上,1代表下
*/
public static class MenuPoint {
int direction;
PointF point;
public MenuPoint(int direction, PointF point) {
this.direction = direction;
this.point = point;
}
}
(五)如何保存结果?
要想获取结果Bitmap的写法有很多,我这里生成了一张Bitmap,再获取它的Canvas对象重新进行绘制。如下:
public Bitmap getResult() {
model.releaseAllFocus();//去除所有焦点,并刷新视图
this.invalidate();
result = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
this.draw(canvas);
return result;
}
你也可以直接在FirstDraw的时候生成一张等高宽的图片,使用图片的canva进行绘图,再绘制bitmap。
你更可以直接使用view截图的方式进行获取,但是需要注意的就是,在生成图片之前必须释放所有焦点,并刷新组件,不然 结果中会绘制边框或者其他的东西。