学习笔记 - Android相机开发 -- 偏好设置

博客:Android相机开发(二): 给相机加上偏好设置
     https://www.polarxiong.com/archives/Android%E7%9B%B8%E6%9C%BA%E5%BC%80%E5%8F%91-%E4%BA%8C-%E7%BB%99%E7%9B%B8%E6%9C%BA%E5%8A%A0%E4%B8%8A%E5%81%8F%E5%A5%BD%E8%AE%BE%E7%BD%AE.html

概述:为相机APP添加偏好设置[分辨率、闪光灯、对焦]

设置菜单:PreferenceFragment [父类 Fragment]

自定义设置类:SettingsFragment
  # 初始代码
      import android.os.Bundle;
      import android.preference.PreferenceFragment;

      public class SettingFragment extends PreferenceFragment{
          @Override
          public void onCreate(Bundle savedInstanceState){
              super onCreate(savedInstanceState);
              addPreferencesFromResource(R.xml.preferences);//加载xml中的菜单条目
          }
      }

添加菜单条目
  # 过程:res下新建xml文件夹 --> xml文件夹内新建文件 preferences.xml
  # 代码
      <?xml version="1.0" encoding="utf-8"?>
      <PreferenceSceren xmlns:android="http://schemas.android.com/apk/res/android">
           <ListPreference 
               android:defaultValue = "100"
               android:entries = "@array/pref_jpegQuality"
               android:entryValues = "@array/pref_jpegQuality"
               android:key = "jpeg_quality"
               android:title = "照片品质" />

           <ListPreference .../>

           <ListPreference .../>
      </PreferenceSreen>

添加array值
  # 过程: res->values下新建文件arrays.xml
  # 代码
          <?xml version="1.0" encoding="utf-8"?>
          <resources>
              <string-array name = "pref_jpegQuality">
                  <item>100</item>
                  <item>90</item>
                  ....
                  <item>50</item>
              </string-array>
          </resources>

MainAtivty中添加按钮监听
  # 代码
        import android.app.Activity;
        import android.os.Bundle;

        public class MainActivity extends Activty{
            protected void onCreate(Bundle savedInstanceState){
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);

                /**/
                CameraPreview mPreview = new CameraPreview(this);
                FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
                preview.addView(mPreview);

                /*为按钮绑定点击监听
                 * 点击设置按钮时,显示设置菜单
                */
                Button buttonSetting = (Buntton) findViewById(R.id.button_settings);
                buttonSettings.setOnclickListener(new View.OnclickListener(){
                    @Override
                    public void onClick(View v){
                        getFragmentManager().beginTransaction().replace(R.id.camera_preview, new SettingsFragment()).addToBackStack(null).commit();
                    }
                });
            }
        }

相机获取
  # 原因:部分设置参数的数据集为相机支持的参数集,需要调用函数获取
           首先要打开相机
  # 代码
          /* 通过getParameters() 获取相机参数
           * 将相机参数保存到静态成员变量mParameters中
           */
          import android.hardware.Camera;

          static Camera mCamera;
          static Camera.Parameters mParameters;

          public static void passCamera(Camera amera){
              mCamera = camera;
              mParameters = camera.getParameters(); // 获取相机参数
          }

动态加载
  # 使用情况:preference.xml文件中 标签<ListPreference/>属性不全
              - 只有 android:key 和 android:title等常用选项
              - 没有 entries 和 entryValues [此处需要动态加载]
  # 代码
      /* 以 动态加载 预览分辨率 为例
       * 加载方法 ((ListPreference的实例名).setEntries(A) 和 ((ListPreference的实例名).setEntries(A)
       * 参数要求 A 为 字符序列 CharSequence[] 
       * 分辨率存储方式:List<Camera.Size>
       * 调用set方法以前需要对数据集做相应的类型转换
       */
       import android.preference.ListPreference;
       import java.util.ArrayList;
       import java.util.List;

       public static final String KEY_PREF_PREV_SIZE = "preview_size";

       private void loadSurpportedPreviewSize(){
           cameraSizeListToListPreference(mParameters.getSurpportedPreviewSizes(),"preview_size");
       }

       private void cameraSizeListToListPreference(List<Camera.Size> list, String key){
           List<String> stringList = new ArrayList<>();

           for(Camera.Size size : list){
               String stringSize = size.width + "X" + size.height;
               stringList.add(stringSize);
           }

        stringListToListPreference(stringList,key);           
       }

       private void stringListToListPreference(List<String> list, String key){
           final CharSequence[] charSeq = list.toArray(new CharSequence[list.size()]);

           ListPreference listPref = (ListPreerence)getPreferenceScreen().findPreference(key);
           listPref.setEntries(charSeq);
           listPref.setEntryValues(charSeq);
       }
  # 加载时间:设置菜单创建时加载
               在onCreate()中调用加载方法[loadSurpportedPreviewSize()...]

添加相机 [in MainActivity]
  # 添加前调整:修改CameraPreview的相机实例获取方法。返回正在使用的相机
    public Camera getCameraInstance(){
        if(mCamera == null){
            try{
                mCamera = Camera.open();
            }catch(Exception e){
                Log.d(TAG,"camera is not avaliable");
            }
        }
        return mCamera;
    }

  #在MainActivity 中按钮监听添加之间 插入代码 获取相机
    SettingsFragment.passCamera(mpreview.getCameraInstance()); 

GPS权限声明 in AndroidManifest.xml
  # 代码:
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

默认值添加 - 静态
  # 加载方法:PreferenceManager.setDefaultValues(this,R.xml.preferences,false)
    - 方法意义:xml文件中有的ListPreference的android:defaultValue属性设置的有效值
               这种情况下依然需要java代码进行加载工作
    - 参数:false表示 如果key已有value值则不会进行任何操作
            否则设置value为xml文件中的指定值
    - 代码调用位置 : MainActivity的onCreate()适当位置添加

默认值添加 - 动态
  # 方案:SettingFragment中创建方法 setDefault()达到效果 最后再Activty中调用即可
  # 原则:首先找到“相机预览分辨率”的value值,如果值为空则指定默认值,否则返回
  # 代码
      Public static void setDefalut(SharedPreferences sharedPref){
          String valPreviewSize = sharedPrefs.getString(KEY_PREF_PREV_SIZE, null);
          if(valPreviewSize == null){
              SharedPreferences.Editor editor = sharedPrefs.edit();
              editor.putString(KEY_PREF_PREV_SIZE, getDefaultPreviewSize());
              ...// 相机其他参数的默认值设置
              editor.apply();
          }
      }
      /* 相机本身是有默认值的
       * 只是我们的偏好设置中还没有设置这个默认值
       * 因此我们可以获取到相机的默认值,然后构造成为偏好设置中的格式
       * 将这个值指定为value就可以了。
       */
      private static String getDefaultPreviewSize(){
          Camera.Size previewSize = mParameters.getPreviewSize();
          return previewSize.width + "x" + previewSize.height;
      }
    ... //其他参数的getDefalutXXX()方法

APP启动时自动加载偏好
  # 方案:在SettingsFragment中创建init()方法,负责设置相机;
           在MainActivity的onCreate()中,在设置完静态和动态默认值后调用init()方法,完成相机设置。

  # SettingFragment 代码添加
    import android.content.SharePreferences;

    public static void init(SharePreferences sharedPref){
        setPreviewSize(sharedPref.getString(KEY_PREF_PREV_SIZE,""));
        ...//其他的setXXX()方法
        mCamera.stopPerview();//停止预览
        mCamera.setParameters(mOarameters);//应用修改
        mCamera.startPreview();//开始预览
    }

    private static void setPreviewSize(String value){
        String[] split = value.split("X");
        mParameters.setPreviewSize(Integer.parseInt(split[0]),Integer.parseInt(split[1]));
    }

    ...//其他的setXXX()方法
  
  # MainActivity 调用
    SettingsFragment.init(PreferenceManager.getDefaultSharedPreferences(this)); 

条目值变化后的立即应用设置
  # 方案:监听条目value的变化 [监听Preference变化]
           1.SettingFragment 添加监听接口
           2.SettingFragment 添加监听事件

  # 添加监听接口:
        public class SettingsFragment extends PreferenceFragment 
          implements SharedPreferences.OnSharedPreferenceChangeListener

  # 添加监听事件
          /* 书写监听事件的回调函数 onSharedPreferenceChanged
           * 在 onResume() 和 onPause() 进行相应调用 实现对应功能
           */
          public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key){
              switch(key){
                  case KEY_PREF_PREV_SIZE:
                      setPreviewSize(sharedPreferences.getString(key, ""));
                      break;
                  case ...
                  ...
              }
              /*预览更新*/
              mCamera.stopPreview();
              mCamera.setParameters(mParameters);
              mCamera.startPreview();
          }

        @Override
        public void onResume() {
            super.onResume();
            getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
        }

        @Override
        public void onPause() {
            super.onPause();
            getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
        }

设置菜单中显示ListPreference当前值
  # 方案:为summary赋值
           1. 在settingFragment中添加对应方法
           2. 在合适位置进行方法调用 [onCreate()  或者 onSharedPreferenceChanged()中]
  
  # 方法添加
    private static void initSummary(Preference pref) {
        if (pref instanceof PreferenceGroup) {
            PreferenceGroup prefGroup = (PreferenceGroup) pref;
            for (int i = 0; i < prefGroup.getPreferenceCount(); i++) {
                initSummary(prefGroup.getPreference(i));
            }
        } else {
                updatePrefSummary(pref);
        }
    }

    private static void updatePrefSummary(Preference pref) {
        if (pref instanceof ListPreference) {
            // 为summary赋值
            pref.setSummary(((ListPreference) pref).getEntry());
        }
    }
  
  # 方法调用 SettingFragment
    ~ 在Oncreate()中添加 : 最后添加 initSummary(getPreferenceScreen());
    ~ 在onSharedPreferenceChanged()中 : 最开始添加updatePrefSummary(findPreference(key));

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值