Android启动页用户相关政策弹框的实现代码

现在Android上架各大平台都要求App首页添加一个弹框,显示用户协议以及一些隐私政策,不然上架各大平台,现在就来简单的实现一下这个对话框

既然是一个对话框,那我们就先来简单的封装一个对话框,这样方便后续的一些修改:
widget_user_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:background="@drawable/bg_sprint_border"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content">
 <androidx.appcompat.widget.LinearLayoutCompat
  android:background="@drawable/bg_sprint_border"
  android:orientation="vertical"
  android:layout_marginLeft="25dp"
  android:layout_marginRight="25dp"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content">
  <androidx.appcompat.widget.AppCompatTextView
   android:id="@+id/tv_sprint_title"
   android:text="Sprint"
   android:padding="12dp"
   android:layout_gravity="center_horizontal"
   android:textSize="18sp"
   android:textColor="@color/colorBlack"
   android:textStyle="bold"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>
  <androidx.appcompat.widget.AppCompatTextView
   android:id="@+id/tv_sprint_content"
   android:text="我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容"
   android:layout_gravity="center_horizontal"
   android:padding="8dp"
   android:textSize="14sp"
   android:textColor="@color/colorBlack"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>
  <View
   android:layout_width="match_parent"
   android:layout_height="0.5dp"
   android:background="@color/colorLightGrey_1" />
  <LinearLayout
   android:layout_width="match_parent"
   android:layout_height="40dp"
   android:layout_marginBottom="0.1dp"
   android:layout_marginLeft="0.1dp"
   android:layout_marginRight="0.1dp"
   android:orientation="horizontal">
   <TextView
    android:id="@+id/tv_dialog_no"
    android:layout_width="0dp"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:background="@drawable/bg_sprint_cancle"
    android:gravity="center_horizontal|center_vertical"
    android:text="取消"
    android:textSize="15sp"
    android:textColor="@color/colorBlack"/>
   <View
    android:layout_width="0.5dp"
    android:layout_height="match_parent"
    android:background="@color/colorLightGrey_1" />
   <!--android:background="@drawable/message_dialog_bottom_right"-->
   <TextView
    android:id="@+id/tv_dialog_ok"
    android:layout_width="0dp"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:gravity="center_horizontal|center_vertical"
    android:text="确定"
    android:textSize="15sp"
    android:background="@drawable/bg_sprint_agreen_commit"
    android:textColor="@color/colorFont_0098FA" />
  </LinearLayout>
 </androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>

drawable文件这里就不放出来了,不懂得可以问问度娘,主要就是设置个圆角,然后还有颜色
AgreementDialog.java
这里就是封装的对话框,包括标题、确定、取消等一些控件的封装,主要我们用SpannableString 这个来实现内容的编辑,可以设置指定内容的演示颜色、大小以及样式等等,需求有需要的话大家可以自己扩展一下

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.view.Window;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.huantek.module.sprint.R;
public class AgreementDialog extends Dialog {
 private Context context;
 private TextView tv_tittle;
 private TextView tv_content;
 private TextView tv_dialog_ok;
 private TextView tv_dialog_no;
 private String title;
 private SpannableString str;
 private View.OnClickListener mClickListener;
 private String btnName;
 private String no;
 private String strContent;
 public AgreementDialog(@NonNull Context context) {
  super(context);
 }
 //构造方法
 public AgreementDialog(Context context, SpannableString content, String strContent, String title) {
  super(context, R.style.MyDialog);
  this.context = context;
  this.str = content;
  this.strContent = strContent;
  this.title = title;
 }
 public AgreementDialog setOnClickListener(View.OnClickListener onClick) {
  this.mClickListener = onClick;
  return this;
 }
 public AgreementDialog setBtName(String yes, String no) {
  this.btnName = yes;
  this.no = no;
  return this;
 }
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  requestWindowFeature(Window.FEATURE_NO_TITLE);
  setContentView(R.layout.widget_sprint_user_dialog);
  initView();
 }
 private void initView() {
  tv_dialog_ok = (TextView) findViewById(R.id.tv_dialog_ok);
  tv_tittle = (TextView) findViewById(R.id.tv_sprint_title);
  tv_content = (TextView) findViewById(R.id.tv_sprint_content);
  tv_dialog_no = (TextView) findViewById(R.id.tv_dialog_no);
  tv_content.setMovementMethod(LinkMovementMethod.getInstance());
  if (!TextUtils.isEmpty(btnName)) {
   tv_dialog_ok.setText(btnName);
  }
  if (!TextUtils.isEmpty(no)) {
   tv_dialog_no.setText(no);
  }
  //设置点击对话框外部不可取消
  this.setCanceledOnTouchOutside(false);
  this.setCancelable(true);
  tv_dialog_ok.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View arg0) {
    AgreementDialog.this.dismiss();
    if (mClickListener != null) {
     mClickListener.onClick(tv_dialog_ok);
    }
   }
  });
  tv_dialog_no.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View arg0) {
    AgreementDialog.this.dismiss();
    if (mClickListener != null) {
     mClickListener.onClick(tv_dialog_no);
    }
   }
  });
  if (TextUtils.isEmpty(strContent)) {
   tv_content.setText(str);
  } else {
   tv_content.setText(strContent);
  }
  tv_tittle.setText(title);
 }
}

对于这种对话框,并不是每次都需要弹出来,只有用户在第一次安装的时候才会弹出,后面启动的话就无需在弹出来了,所以我们要进行一个判断,判断用户是不是第一次使用
先定义一个boolean的值,用于判断用户是不是第一次使用

//是否是第一次使用
 private boolean isFirstUse;

这里可以用SharedPreferences来进行保存这个值是false还是true

SharedPreferences preferences = getSharedPreferences("isFirstUse", MODE_PRIVATE);
  //默认设置为true
  isFirstUse = preferences.getBoolean("isFirstUse", true);

如果是第一次使用,那我们就设置对应的标题、内容等相关值,如果不是就不做操作

 new AgreementDialog(context, generateSp("感谢您信任并使用" + AppUtils.getAppName(this)+"XXXXXX《"+ AppUtils.getAppName(this) + "用户协议》" +
     "和《"+ AppUtils.getAppName(this) + "隐私政策》" +
     "XXXXX"),null,"温馨提示").setBtName("同意", "不同意")
     .setOnClickListener(new View.OnClickListener() {

      @Override
      public void onClick(View v) {
       switch (v.getId()){
        case R.id.tv_dialog_ok:
         //实例化Editor对象
         SharedPreferences.Editor editor = preferences.edit();
         //存入数据
         editor.putBoolean("isFirstUse", false);
         //提交修改
         editor.commit();
         //这里是一开始的申请权限,不懂可以看我之前的博客
         requirePermission();

         break;
        case R.id.tv_dialog_no:
         finish();
         break;
       }

      }
     }).show();
  } else {
  }

记得一定要.show(),不然对话框不会弹出来,这里面的重点部分在于generateSp()这个方法,这里就是为了设置“用户协议”这几个字体的颜色

 private SpannableString generateSp(String text) {
 //定义需要操作的内容
  String high_light_1 = "《用户协议》";
  String high_light_2 = "《隐私政策》";

  SpannableString spannableString = new SpannableString(text);
  //初始位置
  int start = 0;
  //结束位置
  int end;
  int index;
  //indexOf(String str, int fromIndex): 返回从 fromIndex 位置开始查找指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
  //简单来说,(index = text.indexOf(high_light_1, start)) > -1这部分代码就是为了查找你的内容里面有没有high_light_1这个值的内容,并确定它的起始位置
  while ((index = text.indexOf(high_light_1, start)) > -1) {
   //结束的位置
   end = index + high_light_1.length();
   spannableString.setSpan(new QMUITouchableSpan(this.getResources().getColor(R.color.colorFont_0098FA), this.getResources().getColor(R.color.colorFont_0098FA),
     this.getResources().getColor(R.color.colorWhite), this.getResources().getColor(R.color.colorWhite)) {
    @Override
    public void onSpanClick(View widget) {

     // 点击用户协议的相关操作,可以使用WebView来加载一个网页
    }
   }, index, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
   start = end;
  }

  start = 0;
  while ((index = text.indexOf(high_light_2, start)) > -1) {
   end = index + high_light_2.length();
   spannableString.setSpan(new QMUITouchableSpan(this.getResources().getColor(R.color.colorFont_0098FA), this.getResources().getColor(R.color.colorFont_0098FA),
     this.getResources().getColor(R.color.colorWhite), this.getResources().getColor(R.color.colorWhite)) {
    @Override
    public void onSpanClick(View widget) {
      // 点击隐私政策的相关操作,可以使用WebView来加载一个网页

    }
   }, index, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
   start = end;
  }
  //最后返回SpannableString
  return spannableString;
 }

最后就是QMUITouchableSpan.java
用来触发用户点击时的相关操作

/**
 * Created by Sammi on 2020/2/27.
 * /**
 * 可 Touch 的 Span,在 {@link #setPressed(boolean)} 后根据是否 pressed 来触发不同的UI状态
 * <p>
 * 提供设置 span 的文字颜色和背景颜色的功能, 在构造时传入
 * </p>
 */

public abstract class QMUITouchableSpan extends ClickableSpan {
 private boolean mIsPressed;
 @ColorInt private int mNormalBackgroundColor;
 @ColorInt private int mPressedBackgroundColor;
 @ColorInt private int mNormalTextColor;
 @ColorInt private int mPressedTextColor;

 private boolean mIsNeedUnderline = false;

 public abstract void onSpanClick(View widget);

 @Override
 public final void onClick(View widget) {

  if (ViewCompat.isAttachedToWindow(widget)) {
   onSpanClick(widget);

  }
 }

 public QMUITouchableSpan(@ColorInt int normalTextColor,
        @ColorInt int pressedTextColor,
        @ColorInt int normalBackgroundColor,
        @ColorInt int pressedBackgroundColor) {
  mNormalTextColor = normalTextColor;
  mPressedTextColor = pressedTextColor;
  mNormalBackgroundColor = normalBackgroundColor;
  mPressedBackgroundColor = pressedBackgroundColor;
 }

 public int getNormalBackgroundColor() {
  return mNormalBackgroundColor;
 }

 public void setNormalTextColor(int normalTextColor) {
  mNormalTextColor = normalTextColor;
 }

 public void setPressedTextColor(int pressedTextColor) {
  mPressedTextColor = pressedTextColor;
 }

 public int getNormalTextColor() {
  return mNormalTextColor;
 }

 public int getPressedBackgroundColor() {
  return mPressedBackgroundColor;
 }

 public int getPressedTextColor() {
  return mPressedTextColor;
 }

 public void setPressed(boolean isSelected) {
  mIsPressed = isSelected;
 }

 public boolean isPressed() {
  return mIsPressed;
 }

 public void setIsNeedUnderline(boolean isNeedUnderline) {
  mIsNeedUnderline = isNeedUnderline;
 }

 @Override
 public void updateDrawState(TextPaint ds) {
  ds.setColor(mIsPressed ? mPressedTextColor : mNormalTextColor);
  ds.bgColor = mIsPressed ? mPressedBackgroundColor
    : mNormalBackgroundColor;
  ds.setUnderlineText(mIsNeedUnderline);
 }
}

附上效果图

总结

到此这篇关于Android启动页用户相关政策弹框的实现的文章就介绍到这了,更多相关Android启动页用户相关政策弹框的实现内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android优化之启动页去黑屏实现秒启动

    前言 还记得之前我们写了一篇文章,基于RxJava实现酷炫启动页,然而当我们点击桌面图标启动APP时,有时会闪一下黑色背景,有时黑色背景时间还比较长,哎呀,难看死了,这个怎么办捏,别方,我们今天就来看看启动页的优化. 一.消除启动时的黑屏 点击桌面launcher图标启动APP,闪现的黑色背景其实是出现在我们看到界面第一帧之前.那我们就要想办法让这个黑色的背景变成用户喜欢看到的画面或者让它透明化.有了思路方法也就粗现了,我们有下面两种方案: 自定义WelcomActivity的Theme 说白了

  • Android填坑系列:在小米系列等机型上放开定位权限后的定位请求弹框示例

    背景 近期因实际项目需要,在特定操作下触发定位请求,取到用户位置及附近位置. 问题: 经初步选型,最终决定接入百度定位,按照百度定位SDK Android文档,接入过程相对顺利. 但随后发现,在小米系列等部分机型上,进入app后会出现"正在尝试 通过网络或者卫星对您的手机进行定位". 很影响用户体验. 解决过程: 1.Flurry的小坑 项目中引入了数个第三方SDK,主要包括Flurry,友盟,个推,百度定位SDK等.在App启动初始化及进入到首页的执行流中,主要涉及到Flurry,友

  • Android简单实现自定义弹框(PopupWindow)

    一:一般都是先上效果图 二:实现步骤: 1.xml布局实现 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height=&quo

  • 浅析Android中常见三种弹框在项目中的应用

    一丶概述 弹框在Android项目中经常出现,常见的实现方法有三种:Dialog 弹框,Window弹框,Activity伪弹框.本文就说一说三种弹框的实现及在项目中的运用. 二丶演示图         图一为常见的三种弹框(文末上链接),图二为项目中用到的Activity伪弹框 三丶正文 1.Dialog弹框 先看一篇一篇文章: android 8种对话框(Dialog)使用方法汇总 Dialog是系统自带的弹框,然而常常因为UI不好看而遭嫌弃,常需要自定义 public class MyDi

  • Android启动页面定时跳转的三种方法

    从我所做的项目来看,几乎都少不了开始页面,启动页面的作用能够打广告.发公告.做缓存处理.更新数据等等!Android实现开始页面的跳转,就是打开一个Android手机APP的欢迎界面后跳转到指定界面,下面就让我简单介绍下比较常用的开始页面的跳转方法吧. 一.在onCreate里设置个Timer,然后建立Intent指向你要调用的Activity.设置Timer 任意秒后执行startActivity即可!(Timer是一种定时器工具,用来在一个后台线程计划执行指定任务,它可以计划执行一个任务一次

  • Android启动页出现白屏、黑屏的解决方案

    历史原因 当系统启动一个APP时,zygote进程会首先创建一个新的进程去运行这个APP,但是进程的创建是需要时间的,在创建完成之前,界面是呈现假死状态的,这就很尴尬了,因为用户会以为没有点到APP而再次点击,这极大的降低用户体验,Android需要及时做出反馈去避免这段迷之尴尬.于是系统根据你的manifest文件设置的主题颜色的不同来展示一个白屏或者黑屏.而这个黑(白)屏正式的称呼应该是Preview Window,即预览窗口. 好了,现在我们明白了,Preview Window其实是为了提

  • Android启动页解决方案(推荐)

    启动页几乎成为了每个app的标配,有些商家在启动页中增加了开屏广告以此带来更多的收入.目前启动页的广告都有倒计时的功能,那么我们在倒计时的过程中能做些什么呢? 这篇文章主要包括以下两方面内容 集成腾讯广告联盟的SDK 启动页加载过程中,后台初始化数据 我们在设计启动页时的常规做法是建立一个Activity来加载开屏图片或者广告,作为程序的入口,那么在这个三到五秒时间内如果进行数据下载,当用户点击了跳过按钮或者计时结束了数据还没初始化完成,已经进入了主页面,而主界面刚好需要那些基础数据该如何? 因

  • Android启动页广告(腾讯广告联盟)解决方法及源码下载

    Android启动页广告(腾讯广告联盟) 启动页几乎成为了每个app的标配,有些商家在启动页中增加了开屏广告以此带来更多的收入.目前启动页的广告都有倒计时的功能,那么我们在倒计时的过程中能做些什么呢? 这篇文章主要包括以下两方面内容 集成腾讯广告联盟的SDK 启动页加载过程中,后台初始化数据 我们在设计启动页时的常规做法是建立一个Activity来加载开屏图片或者广告,作为程序的入口,那么在这个三到五秒时间内如果进行数据下载,当用户点击了跳过按钮或者计时结束了数据还没初始化完成,已经进入了主页面

  • Android启动页用户相关政策弹框的实现代码

    现在Android上架各大平台都要求App首页添加一个弹框,显示用户协议以及一些隐私政策,不然上架各大平台,现在就来简单的实现一下这个对话框 既然是一个对话框,那我们就先来简单的封装一个对话框,这样方便后续的一些修改: widget_user_dialog.xml <?xml version="1.0" encoding="utf-8"?> <androidx.appcompat.widget.LinearLayoutCompat xmlns:an

  • Android 启动页白屏解决方案

    当我们打开app的时候是不是会有一瞬间的白屏然后再进入主活动,虽然这并不会造成什么不好的后果,但是感觉用户体验就不是很好.像网易云音乐等等,打开一瞬间就显示了他们的loge,无缝衔接,没有白屏,怎么做到的呢? 一开始我的思路是这样的.可能是因为我们的主活动逻辑太多,所以加载会变慢,导致显示白屏.如果使用一个只显示一张本地图片的活动,那会不会就不会显示白屏了呢.话不多说我们尝试一下: Activity中的代码: /** * 启动页,显示倾旅的logo,停顿2秒后跳转 */ public clas

  • Android启动页优化之实现应用秒开

    Android 应用冷启动时,需要从Application开始启动,加载时间就会比较长,这段时间里,用户所能看到的就是"白屏"(这是因为默认的AppTheme的 android:windowBackground 默认是设置成白色的),因此我认为真正的启动页就应该是让用户点开应用时看到的不是"白屏",而是我们创建的一个页面,可以是一张图片.一段文字. 这样,不明真相的用户直观感觉到的就是,这个应用可以秒开. 1.首先在 drawable 目录下新建一个 splash_

  • Android中 TeaScreenPopupWindow多类型筛选弹框功能的实例代码

    Github地址 YangsBryant/TeaScreenPopupWindow (Github排版比较好,建议进入这里查看详情,如果觉得好,点个star吧!) 引入module allprojects { repositories { google() jcenter() maven { url 'https://www.jitpack.io' } } } implementation 'com.github.YangsBryant:TeaScreenPopupWindow:1.0.2' 主

  • Android高德地图marker自定义弹框窗口

    本文实例为大家分享了Android高德地图marker自定义弹框窗口的具体代码,供大家参考,具体内容如下 最终效果: 1.gradle里添加高德地图依赖 implementation 'com.amap.api:map2d:latest.integration'//2d地图功能 implementation 'com.amap.api:location:latest.integration'//定位功能 2.如果要用到定位的话,就首先到高德控制台里面加入本应用的信息获取到key,再在Applic

  • vue.js中toast用法及使用toast弹框的实例代码

    1.首先引入 import { Toast } from 'vant' 写个小列子 绑定一个click事件 2.写事件 在methods写方法 showToast() { this.$toast({ message: "今日签到+3", }) }, 3.效果图如下 一个简单的toast提示成就好了 下面通过实例代码看下vue 中使用 Toast弹框 import { ToastPlugin,ConfirmPlugin,AlertPlugin} from 'vux' Vue.use(To

  • vue+elementui 实现新增和修改共用一个弹框的完整代码

    element-ui是由饿了么前端团队推出的一套为开发者.设计师和产品经理准备的基于Vue.js 2.0的桌面组件库,而手机端有对应框架是 Mint UI .整个ui风格简约,很实用,同时也极大的提高了开发者的效率,是一个非常受欢迎的组件库. 一.新增 1.新增按钮 2.新增事件 在methods中,用来打开弹窗, dialogVisible在data中定义使用有true或false来控制显示弹框 **3.新增确定,弹框确定事件 ,新增和修改共用一个确定事件,使用id区别 **3.新增事件 调新

随机推荐