Media Module之Camera(六) 设置

Camera中的设置选项,主要的是控制Camera的显示效果和动作的。下面简单从代码的角度分析一下Camera的设置。

6.1 简单介绍

此部分主要介绍的是如何快速地定位设置项的位置,找到对应key和value的值。
首先根据字符串找到相应的菜单的位置,一般都会在如图的两个文件里面,分别对应拍照和录像模式的菜单;

image.png

就拿取景模式举例:根据“取景模式”这四个字对应的name值,找到xml中的位置;

<string name="pref_camera_scenemode_title"
 msgid="5709932164781367066">"取景模式"</string>
<IconListPreference

            camera:key=*"pref_camera_scenemode_key"*

camera:defaultValue=*"@string/pref_camera_scenemode_default"*

            camera:title=*"@string/pref_camera_scenemode_title"*

            camera:icons
 =*"@array/camera_scenemode_icon"*

            camera:singleIcon=*"@drawable/ic_settings_scenemode"*

            camera:largeIcons
 =*"@array/camera_scenemode_icon"*

            camera:thumbnails=*"@array/scenemode_thumbnails"*

            camera:entries=*"@array/pref_camera_scenemode_entries"*

camera:entryValues=*"@array/pref_camera_scenemode_entryvalues"*/>

再根据其key值找到相应的value值。首先根据字符串找到在CameraSettings.java中的相应的位置,

public static final StringKEY_SCENE_MODE =
 "pref_camera_scenemode_key";

然后根据其变量KEY_SCENE_MODE在代码中查找所有相关的代码,查看相应的功能逻辑,根据相应的功能逻辑做处理;

6.2 xml文件的解析器

首先设置菜单的显示是通过xml文件布局实现的实现方式,以设置取景模式为例:

Camera界面资源文件在xml/camera_preferences.xml文件中:

<IconListPreference

            camera:key=*"pref_camera_scenemode_key"*

camera:defaultValue=*"@string/pref_camera_scenemode_default"*

            camera:title=*"@string/pref_camera_scenemode_title"*

            camera:icons
=*"@array/camera_scenemode_icon"*

            camera:singleIcon=*"@drawable/ic_settings_scenemode"*

            camera:largeIcons
=*"@array/camera_scenemode_icon"*

            camera:thumbnails=*"@array/scenemode_thumbnails"*

            camera:entries=*"@array/pref_camera_scenemode_entries"*

camera:entryValues=*"@array/pref_camera_scenemode_entryvalues"*/>

PreferenceInflater.java(src/com/android/camera/PreferenceInflater.java)是个解析器,用来解析xml中所有的设置项,包括照相机和摄像机的,具体看解析哪个xml文件,然后保存在自己的成员变量list中,list就是ArrayList类型。

inflate(mContext.getResources().getXml(resId))就是得到的就是XmlPullParser对象,这个就是该xml文件的解析器。

6.3 自定义属性的添加

declare-styleable是给自定义组件添加自定义属性用的,自定义属性在res/values/attrs.xml

<resources>

    <declare-styleable name=*"Theme.GalleryBase"*>

        <attr name=*"listPreferredItemHeightSmall"*
format=*"dimension"* />

        <attr name=*"switchStyle"*
format=*"reference"* />

    </declare-styleable>

    <!--
Camera resources below -->

    <declare-styleable name=*"CameraPreference"*>

        <attr name=*"title"*
format=*"string"* />

    </declare-styleable>

    <declare-styleable name=*"ListPreference"*>

        <attr name=*"key"* format=*"string"* />

        <attr name=*"defaultValue"* format=*"string|reference"*
/>

        <attr name=*"entryValues"* format=*"reference"*
/>

        <attr name=*"entries"*
format=*"reference"* />

        <attr name=*"labelList"*
format=*"reference"* />

    </declare-styleable>

    <declare-styleable name=*"IconIndicator"*>

        <attr name=*"icons"*
format=*"reference"* />

        <attr name=*"modes"*
format=*"reference"* />

    </declare-styleable>

    <declare-styleable name=*"IconListPreference"*>

        <!-- If a preference does not have individual icons for each entry, it
can has a single icon to represent it. -->

        <attr name=*"singleIcon"*
format=*"reference"* />

        <attr name=*"icons"*
/>

        <attr name=*"largeIcons"*
format=*"reference"* />

        <attr name=*"thumbnails"*
format=*"reference"* />

        <attr name=*"images"*
format=*"reference"* />

    </declare-styleable>

</resources>

6.4 自定义属性的使用

camera_preferences.xml及video_preferences.xml的菜单选项包括ListPreference和IconListPreference两种。ListPreference是列表型设置项,是负责存储数据的,它决定了显示什么数据,IconListPreference继承自ListPreference,是带图标的列表菜单。

下面看ListPreference如何使用自定义属性:

public  ListPreference(Context context, AttributeSet
attrs) {
        super (context,attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ListPreference,0, 0);
        mKey = CameraUtil.checkNotNull(a.getString(R.styleable.ListPreference_key));
        // We allow the defaultValue attribute to be a string or an array of
        // strings. The reason we need multiple default values is that some
        // of them may be unsupported on a specific platform (for example,
        // continuous auto-focus). In that case the first supported value
        // in the array will be used.

翻译如下:

我们允许“默认值”属性是一个字符串或数组串.
我们需要多个默认值的原因是:它们可能在特定平台上不受支持(例如,连续、自动对焦)。
在这种情况下,第一个支持的值将在数组中使用。

        int attrDefaultValue = R.styleable.ListPreference_defaultValue;
        TypedValue tv = a.peekValue(attrDefaultValue);
        if (tv != null && tv.type == TypedValue.TYPE_REFERENCE) {
            mDefaultValues = a.getTextArray(attrDefaultValue);
        } else {
            mDefaultValues = **new** CharSequence[1];
            mDefaultValues[0] = a.getString(attrDefaultValue);
        }
        setEntries(a.getTextArray(R.styleable.ListPreference_entries));
        setEntryValues(a.getTextArray(R.styleable.ListPreference_entryValues));
        setLabels(a.getTextArray(R.styleable.ListPreference_labelList));
        a.recycle();
}

在camera_preferences.xml菜单项里包含了下面信息:

packages/apps/Camera2/res/values/arrays.xml定义了菜单项成员及其键值

<!--
Camera Preferences Scene Mode dialog box entries -->

    <string-array name=*"pref_camera_scenemode_entries"* translatable=*"false"*>

        <item>@string/pref_camera_scenemode_entry_night</item>

        <item>@string/pref_camera_scenemode_entry_auto</item>

    </string-array>

 

    <string-array name=*"pref_camera_scenemode_labels"*>

        <item>@string/pref_camera_scenemode_label_night</item>

        <item>@string/pref_camera_scenemode_label_auto</item>

    </string-array>

 

    <array name=*"pref_camera_scenemode_icons"*>

        <item>@drawable/ic_sce_night</item>

        <item>@drawable/ic_sce_off</item>

    </array>

 

    <string-array name=*"pref_camera_scenemode_entryvalues"* translatable=*"false"*>

        <item>night</item>

        <item>auto</item>

    </string-array>

由这些定义,我们可以看出,Android的Camera应用程序支持几种情景模式。但是硬件并非都支持。所以最终的菜单中只会显示这几种当中底层硬件所支持的,如果硬件支持的与其中任何一种都不匹配,则不会显示出“取景模式”菜单。
注意:进入相机菜单丢失问题硬件不支持导致菜单不可见;

6.5 加载菜单项

Xml文件的内容以及解析都讲完了,下面看下是怎么把菜单项加载进去的。
Packages/apps/Camera2/src/com/android/camera/CameraSettings.java
CameraSettings是相机设置项的总的接口,里面定义了菜单设置项的KEY值,

public static final String *KEY_SCENE_MODE = "pref_camera_scenemode_key";

这些KEY值是跟camera_preferences.xml里的菜单项对应的,接着在private voidinitPreference(PreferenceGroupgroup)中添加

ListPreference sceneMode = group.findPreference(*KEY_SCENE_MODE*);

来获取键值为KEY_SCENE_MODE的菜单项,接着

if (sceneMode != null) {
    filterUnsupportedOptions(group, sceneMode, mParameters.getSupportedSceneModes());
}

函数mParameters.getSupportedSceneModes()将获取camera 硬件支持的SceneMode的项,其定义在文件Framework/base/core/java/android/hardware/camera.java中。

sceneMode相当于从camera_preferences.xml中获取的sceneMode的项,它俩之间需要做个匹配,如果camera硬件支持的项不存在或者只有一项,则就会从group中去掉sceneMode的菜单。

6.6 效果设置:

我们通过下面代码获取当前菜单项所选中的值,如果是改变值则是改变值,否则就是默认值:

mSceneMode= mPreferences.getString(CameraSettings.*KEY_SCENE_MODE*,              mActivity.getString(R.string.pref_camera_scenemode_default));

如果改变值把选中的值设置到底层:

if(CameraUtil.isSupported(mSceneMode,mParameters.getSupportedSceneModes())) {
      if (!mParameters.getSceneMode().equals(mSceneMode)) {
           mCameraDevice.setSceneDetectionCallback(null,null);
           mParameters.setSceneMode(mSceneMode);
           sceneChanged = true;
       }
}

因为KEY值都存放在SharedPreferences 里,保存Camera设置的所有值,每次启动Camera都会重新读取保存的值。

6.7 界面菜单Camera 切换模式功能:

CameraControls是相机界面下面的控制栏,在其xml文件里显示自定义view项

<com.android.camera.ui.ModuleSwitcher
           android:id="@+id/camera_switcher"
           style="@style/SwitcherButton"
           android:layout_gravity="bottom|left"
           android:layout_marginBottom="-11dip"
      android:contentDescription="@string/accessibility_mode_picker"
/>

Packages/apps/Camera2/src/com/android/camera/ui/ModuleSwitcher.java
此类定义了ModuleSwitchListener接口

public  interface  ModuleSwitchListener {
        public void onModuleSelected(int i);
        public void onShowSwitcherPopup();
    }

ModuleSwitchListener是模式改变监听器当模式改变时通知调用者。
initializeDrawables()初始化了所有模式的图片,只调用一次,主要是给

int[] drawids = new int[numDrawIds];
int[] moduleids = new int[numDrawIds];

两个变量赋值,这两个变量主要是用于模式图标的显示。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,426评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 3.1. 介绍 现在,您已经安装了Wireshark并有可能热衷于开始捕捉您的第一个数据包。在接下来的章节中,我们...
    wwyyzz阅读 1,373评论 0 1
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 引子 最近这两周的生活,非常忙乱。一个项目到了最后冲刺阶段,工作量大,时间紧急,同时需要复杂的思考而不是常规的经验...
    寂颜慕菲阅读 512评论 0 0