• PermissionDialog【权限申请提示对话框】


    版权声明:本文为HaiyuKing原创文章,转载请注明出处!

    前言

      随着Android6.0的普及,权限申请也变成了我们开发中必写的一段代码。比如sd卡权限、定位权限、拍照权限,这些几乎都是每个app必备的。而一般情况下我们都会在需要权限之前申请,然后各种判断。那既然是一些必备的是权限,我们为何不在我们一次打开app的时候就把这个全部都申请了呢?可是一下申请那么多权限对用户来说显然不是很友好,所以我们不妨在申请权限之前告诉一下用户,好让用户有个心理准备。于是借鉴了饿了么的权限申请界面,封装了一个对话框。
     
      这个对话框只是用来展现应用当中需要用到的权限列表,不具备申请权限的功能,申请权限请搭配相关第三方库,比如《Android6.0运行时权限(基于RxPermission开源库)》;另外,考虑到这个对话框一般在APP首次使用的时候才会弹出来,所以搭配《PreferencesUtils【SharedPreferences操作工具类】》实现保存状态值,用于判断是否需要显示这个对话框。

    效果图

    代码分析

    PermissionDialog:对话框界面,继承AlertDialog

    使用步骤

    一、项目组织结构图

    注意事项:

    1、  导入类文件后需要change包名以及重新import R文件路径

    2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

    二、导入步骤

    1、将PermissionDialog.java文件复制到项目中

    package com.why.project.permissiondialog.dialog;
    
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.content.Context;
    import android.graphics.Color;
    import android.graphics.ColorMatrixColorFilter;
    import android.os.Bundle;
    import android.support.v4.content.ContextCompat;
    import android.util.DisplayMetrics;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.ScrollView;
    import android.widget.TextView;
    
    import com.why.project.permissiondialog.R;
    
    /**
     * Created by HaiyuKing
     * Used 权限申请对话框
     */
    public class PermissionDialog extends AlertDialog {
    
        //上下文
        private Context mContext;
    
        //内容的父节点,用于内容较多时可以滚动
        private ScrollView mListScroll;
        //内容
        private LinearLayout mListLayout;
        //确认按钮
        private TextView mConfirmBtn;
    
        public PermissionDialog(Context context) {
            //设置对话框样式
            super(context, R.style.style_permission_dialog);
    
            //设置为false,按对话框以外的地方不起作用
            setCanceledOnTouchOutside(false);
            //设置为false,按返回键不能退出
            setCancelable(false);
    
            this.mContext = context;
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.permission_dialog_layout);
    
            initViews();
            initDatas();
            initEvents();
        }
    
        /**初始化view*/
        private void initViews() {
            mListScroll = findViewById(R.id.permission_dialog_list_scroll);
            mListLayout = findViewById(R.id.layout_list);
            mConfirmBtn = findViewById(R.id.dialog_confirm_btn);
        }
    
        /**初始化数据*/
        private void initDatas() {
    
            //获取图标的颜色值
            int mFilterColor = ContextCompat.getColor(mContext,R.color.permission_dialog_img_color);
            int blue = Color.blue(mFilterColor);
            int green = Color.green(mFilterColor);
            int red = Color.red(mFilterColor);
            float[] cm = new float[]{
                    1, 0, 0, 0, red,// 红色值
                    0, 1, 0, 0, green,// 绿色值
                    0, 0, 1, 0, blue,// 蓝色值
                    0, 0, 0, 1, 1 // 透明度
            };
            ColorMatrixColorFilter filter = new ColorMatrixColorFilter(cm);
    
            //初始化权限列表区域
            int[] permissionImgIds = mContext.getResources().getIntArray(R.array.permission_icon);
            String[] permissionTitles = mContext.getResources().getStringArray(R.array.permission_title);
            String[] permissionInfos = mContext.getResources().getStringArray(R.array.permission_info);
    
            for(int i = 0; i < permissionImgIds.length; i++){
                String title = permissionTitles[i];
                String info = permissionInfos[i];
    
                View itemView = View.inflate(mContext,R.layout.permission_list_item,null);
                ((ImageView)itemView.findViewById(R.id.item_img)).setImageResource(mContext.getResources().obtainTypedArray(R.array.permission_icon).getResourceId(i, 0));
                ((ImageView)itemView.findViewById(R.id.item_img)).setColorFilter(filter);//设置图标的颜色
                ((TextView)itemView.findViewById(R.id.item_title)).setText(title);
                ((TextView)itemView.findViewById(R.id.item_info)).setText(info);
    
                mListLayout.addView(itemView);
            }
    
            //设置内容区域的父节点的高度和内容文本大小
            final DisplayMetrics display = new DisplayMetrics();
            ((Activity)this.mContext).getWindowManager().getDefaultDisplay().getMetrics(display);
            final int screenHeight = display.heightPixels;
            //先设置宽度,然后再调整高度
            mListScroll.setLayoutParams(new LinearLayout.LayoutParams(display.widthPixels - mContext.getResources().getDimensionPixelOffset(R.dimen.permission_dialog_margin) * 2,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
    
            //runnable中的方法会在View的measure、layout等事件后触发
            mListScroll.post(new Runnable() {
                @Override
                public void run() {
                    if (mListScroll.getMeasuredHeight() > screenHeight / 2) {
                        mListScroll.setLayoutParams(new LinearLayout.LayoutParams(display.widthPixels - mContext.getResources().getDimensionPixelOffset(R.dimen.permission_dialog_margin) * 2,
                                screenHeight / 2));
                    }else{
                        //屏幕宽度减去外边距*2
                        mListScroll.setLayoutParams(new LinearLayout.LayoutParams(display.widthPixels - mContext.getResources().getDimensionPixelOffset(R.dimen.permission_dialog_margin) * 2,
                                ViewGroup.LayoutParams.WRAP_CONTENT));
                    }
                }
            });
    
        }
    
        /**初始化监听事件*/
        private void initEvents() {
            mConfirmBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if(mOnCertainButtonClickListener != null){
                        mOnCertainButtonClickListener.onCertainButtonClick();
                    }
                    dismiss();
                }
            });
        }
    
        @Override
        public void dismiss() {
            super.dismiss();
        }
    
        public static abstract interface OnCertainButtonClickListener
        {
            //确认按钮的点击事件接口
            public abstract void onCertainButtonClick();
        }
    
        private OnCertainButtonClickListener mOnCertainButtonClickListener;
    
        public void setOnCertainButtonClickListener(OnCertainButtonClickListener mOnCertainButtonClickListener)
        {
            this.mOnCertainButtonClickListener = mOnCertainButtonClickListener;
        }
    
    }
    PermissionDialog.java

    2、将permission_dialog_bg.xml、permission_dialog_one_btn_bg.xml复制到drawable目录下

    3、将图片资源复制到drawable-xxhdpi目录下

    4、将permission_dialog_layout.xml、permission_list_item.xml布局文件复制到项目中

    5、在arrays.xml中添加以下代码【根据实际情况,通过注释控制图标的个数,标题、说明数组需要和图标数组一一对应

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        
        <!-- 权限图标【可根据实际情况修改】 -->
        <integer-array name="permission_icon">
            <item>@drawable/permission_ic_storage</item>
            <item>@drawable/permission_ic_camera</item>
            <item>@drawable/permission_ic_location</item>
            <item>@drawable/permission_ic_phone</item>
            <item>@drawable/permission_ic_micro_phone</item>
            <item>@drawable/permission_ic_calendar</item>
            <item>@drawable/permission_ic_contacts</item>
            <item>@drawable/permission_ic_sms</item>
            <item>@drawable/permission_ic_sensors</item>
        </integer-array>
    
        <!-- 权限标题【可根据实际情况修改】 -->
        <string-array name="permission_title">
            <item>文件存储</item>
            <item>相机相册</item>
            <item>位置信息</item>
            <item>电话状态</item>
            <item>录制声音</item>
            <item>日程信息</item>
            <item>通讯录</item>
            <item>短信信息</item>
            <item>传感器</item>
        </string-array>
    
        <!-- 权限说明(这里应该是根据项目的实际情况,简要说明下该权限主要用于什么场景或者功能)【可根据实际情况修改】 -->
        <string-array name="permission_info">
            <item>允许应用读取、写入外部存储</item>
            <item>允许应用访问摄像头进行拍照</item>
            <item>允许应用获取定位信息</item>
            <item>允许应用访问电话状态</item>
            <item>允许应用通过手机或耳机的麦克录制声音</item>
            <item>允许应用读取用户的日程信息</item>
            <item>允许应用访问联系人通讯录信息</item>
            <item>允许应用获取短信信息</item>
            <item>允许应用获取传感器信息</item>
        </string-array>
        
    </resources>

     6、在colors.xml中添加以下代码【根据实际情况设置图标和按钮的背景颜色值

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <color name="colorPrimary">#008577</color>
        <color name="colorPrimaryDark">#00574B</color>
        <color name="colorAccent">#D81B60</color>
    
        <!-- ==================权限申请对话框(alertdialog)================== -->
        <!-- 对话框的填充颜色 -->
        <color name="permission_dialog_solid_color">#ffffffff</color>
        <!-- 对话框的标题颜色 -->
        <color name="permission_dialog_title_color">#000000</color>
        <!-- 对话框的描述颜色 -->
        <color name="permission_dialog_message_color">#87000000</color>
        <!-- 对话框的图标颜色【可根据实际情况修改】 -->
        <color name="permission_dialog_img_color">#000000</color>
        <!-- 对话框的按钮背景颜色【可根据实际情况修改】 -->
        <color name="permission_dialog_btn_bg_color">#07b4a2</color>
        <!-- 对话框的按钮文字颜色 -->
        <color name="permission_dialog_btn_text_color">#FFFFFF</color>
    
    </resources>

     7、在dimens.xml中添加以下代码

    <resources>
        <!-- Default screen margins, per the Android Design guidelines. -->
        <dimen name="activity_horizontal_margin">16dp</dimen>
        <dimen name="activity_vertical_margin">16dp</dimen>
    
        <!-- ==================权限申请对话框(alertdialog)================== -->
        <!-- 对话框的圆角角度 -->
        <dimen name="permission_dialog_corners">8dp</dimen>
        <!-- 对话框的整体外边距 -->
        <dimen name="permission_dialog_margin">30dp</dimen>
        <!-- 对话框的标题内边距 -->
        <dimen name="permission_dialog_title_padding">15dp</dimen>
        <!-- 对话框的标题文本大小 -->
        <dimen name="permission_dialog_title_text_size">22sp</dimen>
        <!-- 对话框的描述文本大小 -->
        <dimen name="permission_dialog_message_text_size">16sp</dimen>
        <!-- 对话框的按钮内边距 -->
        <dimen name="permission_dialog_btn_padding">8dp</dimen>
        <!-- 对话框的按钮大小 -->
        <dimen name="permission_dialog_btn_text_size">16sp</dimen>
    
    </resources>

    8、在strings.xml中添加以下代码

    <resources>
        <string name="app_name">PermissionDialog</string>
    
        <!-- ==================权限申请对话框(alertdialog)================== -->
        <string name="permission_dialog_title">权限申请</string>
        <string name="permission_dialog_message">为了您能正常使用,需要以下权限</string>
    </resources>

    9、在styles.xml中添加以下代码

    <resources>
    
        <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
        </style>
    
        <!-- ==================权限申请对话框(alertdialog)================== -->
        <style name="style_permission_dialog">
            <!-- Dialog的windowFrame框为无 -->
            <item name="android:windowFrame">@null</item>
            <!-- 是否显示title -->
            <item name="android:windowNoTitle">false</item>
            <!-- 是否浮现在activity之上 -->
            <item name="android:windowIsFloating">true</item>
            <!-- 半透明 -->
            <item name="android:windowIsTranslucent">true</item>
            <!-- 设置dialog的背景:#00000000透明色 -->
            <item name="android:windowBackground">@android:color/transparent</item>
            <!-- 背景变灰:整个屏幕变灰,配合setCanceledOnTouchOutside(false) -->
            <item name="android:backgroundDimEnabled">true</item>
        </style>
    
    </resources>

    三、使用方法

    在代码中调用如下:

    package com.why.project.permissiondialog;
    
    import android.os.Build;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    
    import com.why.project.permissiondialog.dialog.PermissionDialog;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            findViewById(R.id.btn_showdialog).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    boolean hasShow = PreferencesUtils.getBoolean(MainActivity.this,PreferencesUtils.HAS_SHOW_PREMISSION_DIALOG,false);
                    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ! hasShow){
                        PermissionDialog permissionDialog = new PermissionDialog(MainActivity.this);
                        permissionDialog.setOnCertainButtonClickListener(new PermissionDialog.OnCertainButtonClickListener() {
                            @Override
                            public void onCertainButtonClick() {
                                //搭配SharedPreferences 将状态值记录下来,实现APP首次打开的时候才会弹出这个对话框
                                PreferencesUtils.putBoolean(MainActivity.this,PreferencesUtils.HAS_SHOW_PREMISSION_DIALOG,true);
                                //调用运行时权限申请框架
                            }
                        });
                        permissionDialog.show();
                    }else{
                        //调用运行时权限申请框架
                    }
                }
            });
        }
    }

     注意:

    实际项目中,需要手动调整arrays.xml文件中的权限数组个数,不显示的注释掉,保证三个数组的一一对应;

    根据项目的主题颜色,调整colors.xml文件中的图标、按钮的背景颜色值;

    混淆配置

    参考资料

    一行代码搞定漂亮的Android6.0权限申请界面

    Android-使用 SetColorFilter 神奇地改变图片的颜色

    项目demo下载地址

    https://github.com/haiyuKing/PermissionDialog

  • 相关阅读:
    微软开源全新的文档生成工具DocFX
    .NET平台微服务项目汇集
    谷歌发布的首款基于HTTP/2和protobuf的RPC框架:GRPC
    Microsoft开源跨平台的序列化库——Bond
    Oracle job procedure
    Windows10
    移动端Reactive Native轮播组件
    PHP完整环境搭建
    Webpack 入门
    git 提交
  • 原文地址:https://www.cnblogs.com/whycxb/p/9742385.html
Copyright © 2020-2023  润新知