Android R上展讯平台CameraAPP上zoom图标的逻辑

展讯平台MMX客户要求Camera预览界面的zoom图标不要一直显示,只在用户通过手势操作zoom才显示。需要看着不难理解,但是我没有看过zoom这块的逻辑,还是得从头看起。
首先通过工具定位到zoom图标是一个自定义view,VerticalZoomBar,打开这个文件,1100多行,这样的自定义view显然逻辑就是比较复杂的。
图标具体样式如下:
在这里插入图片描述
一个白色圆环外框,里面一个深色的实心半透明的圆,中间是一个文字。
既然是自定义view,那它所有的东西就都是在onDraw方法中绘制的,直接看onDraw

@Override
    protected void onDraw(Canvas canvas) {
        calculateCurrentOrientationDegree();
//        drawBG(canvas);
        if (mDrawBackgroundProgress) {
            drawProgressBar(canvas);
            drawProgressBarTip(canvas);
            drawIndicator(canvas);
        }
        if (mDrawTipCircle) {
            if (mZoomType != ZOOM_TYPE.TYPE_SINGLE)
                drawLittleCircle(canvas);
            drawTipCircle(canvas, getWidth() / 2, getHeight() / 2);
        }
    }

内容倒是不多,分为两个部分,mDrawBackgroundProgress 和 mDrawTipCircle控制的两部分,这里看到progressBar,但是我们看zoom图标是一个圆形啊,没有进度条相关的内容。因此我们先来关注下面的drawTipCircle方法

private void drawTipCircle(Canvas canvas, float center_x, float center_y) {
        canvas.save();
        canvas.drawCircle(center_x, center_y, mCenterTipCircleradius + 2, mCenterTipBgCirclePaint);
        canvas.drawCircle(center_x, center_y, mCenterTipCircleradius, mCenterTipCirclePaint);
        canvas.rotate(-mCurrentDegree, center_x, center_y);
        canvas.drawText(getTipString(isShowByOutSideValue?mCurrentOutSideValue:getTipValue(TIP_SHOW_SCALE)), center_x, center_y - (mScaleTextBottom + mScaleTextTop) / 2, mCircleTipTextPaint);
        canvas.rotate(mCurrentDegree, center_x, center_y);
        canvas.restore();
    }

这个方法里面绘制了两个圆和一个text,并且两个圆的Radius也是相差2, 跟我们看到的zoom图标比较接近了,在进一步查看两个圆的Paint参数,颜色也符合,因此确认就是这个方法里面在绘制zoom图标了。
在回到onDraw中,就是mDrawBackgroundProgress 和 mDrawTipCircle两个boolean值在控制onDraw真正的绘制内容。
查找文件中修改这两个值的地方,发现了两个成对出现的方法:startDispearAnimationMotion,startShowAnimationMotion。

case TYPE_DOUBLE:
case TYPE_TRIPLE:
    mDrawTipCircle = true;
    mDrawBackgroundProgress = false;
    break;

这里在交叉设置两个boolean变量,circle与progress是互斥显示的,在追是谁在掉用startShowAnimationMotion,跟到了onTouch方法,那就可能是还有触摸事件,我点了下zoom图标,发现果然由原本的circle样式变成了progress。
原来zoom图标是有两种样式的
并且在通过progressBar设置zoom后,手指松开后,过一小会图标消失

case MotionEvent.ACTION_UP:
postDelayed(dispearAnimaRunnable, 500);

通过dispearAnimationRunnable将progress隐藏掉,回到circle状态。
上述是zoom图标绘制的流程,现在来关注下zoom值,我们在预览界面通过手指放大、缩小,最后会在zoom图标中显示出具体的放大倍数值,这是哪个逻辑控制的呢?
前面我们说过,有个drawTipCircle方法是来绘制circle的zoom图标的

canvas.drawText(getTipString(isShowByOutSideValue?mCurrentOutSideValue:getTipValue(TIP_SHOW_SCALE)), center_x, center_y - (mScaleTextBottom + mScaleTextTop) / 2, mCircleTipTextPaint);

mCurrentOutSideValue 就是最终显示的text,追踪mCurrentOutSideValue的赋值,是在setInitValue方法中得到的,在setInitValue通过打印调用堆栈看到:

02-23 17:09:18.002: D/cyy(8668): setInitValue  min = 1.0 ,max = 4.0, currentvalue = 1.8876218 mProgress = 7067  java.lang.Throwable
02-23 17:09:18.002: D/cyy(8668): 	at com.dream.camera.ui.VerticalZoomBar.setInitValue(VerticalZoomBar.java:345)
02-23 17:09:18.002: D/cyy(8668): 	at com.dream.camera.ui.VerticalZoomBar.updateZoomValue(VerticalZoomBar.java:365)
02-23 17:09:18.002: D/cyy(8668): 	at com.dream.camera.ZoomPanel.updateZoomLevel(ZoomPanel.java:75)
02-23 17:09:18.002: D/cyy(8668): 	at com.android.camera.ui.PreviewOverlay$ZoomProcessor.onScale(PreviewOverlay.java:543)
02-23 17:09:18.002: D/cyy(8668): 	at android.view.ScaleGestureDetector.onTouchEvent(ScaleGestureDetector.java:374)
02-23 17:09:18.002: D/cyy(8668): 	at com.android.camera.ui.PreviewOverlay$ZoomGestureDetector.onTouchEvent(PreviewOverlay.java:355)
02-23 17:09:18.002: D/cyy(8668): 	at com.android.camera.ui.PreviewOverlay.onTouchEvent(PreviewOverlay.java:263)
02-23 17:09:18.002: D/cyy(8668): 	at android.view.View.dispatchTouchEvent(View.java:14399)
02-23 17:09:18.002: D/cyy(8668): 	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3201)
02-23 17:09:18.002: D/cyy(8668): 	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2814)
02-23 17:09:18.002: D/cyy(8668): 	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3201)
02-23 17:09:18.002: D/cyy(8668): 	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2814)
02-23 17:09:18.002: D/cyy(8668): 	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3201)
02-23 17:09:18.002: D/cyy(8668): 	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2814)
02-23 17:09:18.002: D/cyy(8668): 	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3201)
02-23 17:09:18.002: D/cyy(8668): 	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2814)
02-23 17:09:18.002: D/cyy(8668): 	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3201)
02-23 17:09:18.002: D/cyy(8668): 	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2814)
02-23 17:09:18.002: D/cyy(8668): 	at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:491)
02-23 17:09:18.002: D/cyy(8668): 	at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1871)
02-23 17:09:18.002: D/cyy(8668): 	at android.app.Activity.dispatchTouchEvent(Activity.java:4188)
02-23 17:09:18.002: D/cyy(8668): 	at com.android.camera.CameraActivity.dispatchTouchEvent(CameraActivity.java:1960)
02-23 17:09:18.002: D/cyy(8668): 	at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:449)

在预览上的手势是通过PreviewOverlay传递过来的。

public void setInitValue(float minValue, float maxValue, float currentValue)

至此VerticalZoomBar这个自定义view的流程基本看完了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值