安卓照相机源码分析2——PreviewFrameLayout类

来源:互联网 发布:淘宝客ev是什么 编辑:程序博客网 时间:2024/06/05 21:59

    PreviewFrameLayout类主要是实现预览纵横比的改变,默认是4:3。

   主要xml类:res/layout/camera.xml video_camera.xml

   继承于ViewGroup类,定义了接口OnSizeChangedListener(),监听尺寸是否改变。

private final DisplayMetrics mMetrics = new DisplayMetrics();    public PreviewFrameLayout(Context context, AttributeSet attrs) {        super(context, attrs);        ((Activity) context).getWindowManager()                    .getDefaultDisplay().getMetrics(mMetrics);    }
  这里mMetrics获得了屏幕的尺寸,但下面并没有进行处理。

  设置frame纵横比

public void setAspectRatio(double ratio) {        if (ratio <= 0.0) throw new IllegalArgumentException();        if (mAspectRatio != ratio) {            mAspectRatio = ratio;            requestLayout();        }    }
  当调用requestLayout()后,会执行onLayout()方法:

 protected void onLayout(boolean changed, int l, int t, int r, int b) {        int frameWidth = getWidth();        int frameHeight = getHeight();        FrameLayout f = mFrame;        int horizontalPadding = f.getPaddingLeft() + f.getPaddingRight();        int verticalPadding = f.getPaddingBottom() + f.getPaddingTop();        int previewHeight = frameHeight - verticalPadding;        int previewWidth = frameWidth - horizontalPadding;        // resize frame and preview for aspect ratio        if (previewWidth > previewHeight * mAspectRatio) {            previewWidth = (int) (previewHeight * mAspectRatio + .5);        } else {            previewHeight = (int) (previewWidth / mAspectRatio + .5);        }                         frameWidth = previewWidth + horizontalPadding;        frameHeight = previewHeight + verticalPadding;        int hSpace = ((r - l) - frameWidth) / 2;        int vSpace = ((b - t) - frameHeight) / 2;        mFrame.measure(                MeasureSpec.makeMeasureSpec(frameWidth, MeasureSpec.EXACTLY),                MeasureSpec.makeMeasureSpec(frameHeight, MeasureSpec.EXACTLY));        mFrame.layout(l + hSpace, t + vSpace, r - hSpace, b - vSpace);        if (mSizeListener != null) {            mSizeListener.onSizeChanged();        }    }
其中l,t,r,b为PreviewFrameLayout的大小,方法里面有对mFrame尺寸的设置;

主要是学习measure方法的使用,一个MeasureSpec封装了父布局传递给子布局的布局要求,主要有三种模式:UNSPECIFIED,EXACTLY,AT_MOST。其中EXACTLY表示父元素完全确定子元素的大小。layout方法设置了mFrame的大小。

还有一个方法是继承自父类的onFinishInflate()方法:

protected void onFinishInflate() {        mFrame = (FrameLayout) findViewById(R.id.frame);        if (mFrame == null) {            throw new IllegalStateException(                    "must provide child with id as \"frame\"");        }    }
这个主要是此view的子类必须要有id为frame的FrameLayout控件,否则会抛出异常。


0 0
原创粉丝点击