**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截圖的方式進行獲取,但是需要注意的就是,在生成圖片之前必須釋放所有焦點,并刷新組件,不然 結果中會繪制邊框或者其他的東西。