PermissionDialog【权限申请提示对话框】
版权声明:本文为HaiyuKing原创文章,转载请注明出处!
前言
效果图
代码分析
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文件中的图标、按钮的背景颜色值;
混淆配置
无
参考资料
Android-使用 SetColorFilter 神奇地改变图片的颜色
项目demo下载地址
https://github.com/haiyuKing/PermissionDialog
PermissionDialog【权限申请提示对话框】的更多相关文章
- Android6.0动态权限申请步骤以及需要注意的一些坑
因为工作需要,简单研究了一下Android6.0权限申请,在Google提供的sample的基础上,写了一个简单的demo.算是自己的笔记吧,可能会比较混乱,主要是方便以后查看.后期有别的问题,随时更 ...
- Android6.0动态权限申请
goggle在Android6.0要求部分权限需要动态申请,直接下载AndroidManifest.xml中无效 6.0权限的基本知识,以下是需要单独申请的权限,共分为9组, 每组只要有一个权限申请成 ...
- Android 6.0 动态权限申请注意事项
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/uana_777/article/details/54136255 Part One 权限区分 And ...
- 自己主动更新--下载apk以及提示对话框的实现(3)
下载apk以及提示对话框的实现 一.步骤: 1. 确定有能够更新的版本号,对话框提醒用户是否进行更新. 2. 选择更新的话,显示下载对话框而且进行下载.否则关闭提示更新对话框. 3. Apk下载完毕后 ...
- 安卓权限申请处理框架Android-UsesPermission
安卓权限申请封装处理框架.测试支持4.0+.项目源于正式处理Android权限问题时,没找到简单.能满足被拒绝权限自动会到系统设置处理的框架,按自己的编程习惯造一个熟悉的轮子还是蛮好的.第一次使用An ...
- 动态权限<二>之淘宝、京东、网易新闻 权限申请交互设计对比分析
移动智能设备的快速普及,给生活带来巨大的精彩,但是智能设备上用户的信息数据很多,隐私数据也非常多,各种各样的app可能通过各种方式在悄悄的收集用户数据,而用户的隐私就变得耐人寻味了.比如之前的可以无限 ...
- Android 6.0动态权限申请教程
转载请标明出处: http://www.cnblogs.com/why168888/p/6580396.html 本文出自:[Edwin博客园] PermissionManage 介绍 如果设备运行的 ...
- Android6.0------权限申请管理(单个权限和多个权限申请)
Android开发时,到6.0系统上之后,有的权限就得申请才能用了. Android将权限分为正常权限 和 危险权限 Android系统权限分为几个保护级别.需要了解的两个最重要保护级别是 正常权限 ...
- Android 动态权限申请
package com.dragon.android.permissionrequest; import android.Manifest; import android.content.Dialog ...
随机推荐
- 传统业务上云:跨AZ容灾架构解析
本文由 网易云发布. 数字化转型浪潮之下,采用云计算服务提升业务敏捷性.降低运维成本,成为了传统企业的优选方案.网易云资深解决方案架构师张亮通过某物流企业客户的实际案例,分享了传统业务系统在云上的架 ...
- js生成带logo的二维码
作为一名java程序员,一直以来都是使用服务端生成二维码,最近接触前端的设计,感觉二维码这块如果放到前端去生成,一方面可以减轻服务端的压力,访问带宽,另一方面,前端页面控制比较顺畅 闲话少叙,说下我的 ...
- 建立CMenu菜单项,实现选中菜单项点击左键响应事件
这里我只是根据自己的项目做了一些总结,实现点击右键弹出菜单项,点左键选择菜单项: CMenu menu; VERIFY(menu.CreatePopupMenu());//新建一个cmenu菜单项 m ...
- 【bzoj2432】【NOI2011】兔农
题目描述 农夫栋栋近年收入不景气,正在他发愁如何能多赚点钱时,他听到隔壁的小 朋友在讨论兔子繁殖的问题. 问题是这样的:第一个月初有一对刚出生的小兔子,经过两个月长大后,这 对兔子从第三个月开始,每个 ...
- bzoj3534 [Sdoi2014]重建
变形的$Martix-Tree$定理 发现我们要求的是$\prod_{i \in E}{p_{i}} * \prod_{i \notin E}{(1-p_{i})}$ 然后呢? 矩阵树对重边也有效对吧 ...
- 【链表+启发式合并】Bzoj1483 [HNOI2009] 梦幻布丁
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第 ...
- BZOJ_2152_聪聪可可_点分治
BZOJ_2152_聪聪可可_点分治 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)…… ...
- Oracle系列-锁表与解锁解决方案(大招版)-解决问题才是王道
[Oracle系列-锁表与解锁解决方案(大招版)] --1查看被锁的表 select b.owner,b.object_name,a.session_id,a.locked_mode from v$l ...
- (5)STM32使用HAL库实现串口通讯——实战操作
功能需求: (1)对接收的字符串原样返回(每10个字符一次). (2)发送一个字符串完成后改变LED的状态. 1.创建工程 使用的是F407Discovery,4个LED对应PD12-PD14. (1 ...
- Java动态代理之JDK实现和CGlib实现
一:代理模式(静态代理) 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由 业务实现类.业务代理类 两部分组成.业务实现类 负责实现 ...