Android啟動(dòng)頁(yè)用戶相關(guān)政策彈框的實(shí)現(xiàn)代碼
現(xiàn)在Android上架各大平臺(tái)都要求App首頁(yè)添加一個(gè)彈框,顯示用戶協(xié)議以及一些隱私政策,不然上架各大平臺(tái),現(xiàn)在就來(lái)簡(jiǎn)單的實(shí)現(xiàn)一下這個(gè)對(duì)話框
既然是一個(gè)對(duì)話框,那我們就先來(lái)簡(jiǎn)單的封裝一個(gè)對(duì)話框,這樣方便后續(xù)的一些修改:
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="我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容我是內(nèi)容"
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文件這里就不放出來(lái)了,不懂得可以問(wèn)問(wèn)度娘,主要就是設(shè)置個(gè)圓角,然后還有顏色
AgreementDialog.java
這里就是封裝的對(duì)話框,包括標(biāo)題、確定、取消等一些控件的封裝,主要我們用SpannableString 這個(gè)來(lái)實(shí)現(xiàn)內(nèi)容的編輯,可以設(shè)置指定內(nèi)容的演示顏色、大小以及樣式等等,需求有需要的話大家可以自己擴(kuò)展一下
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);
}
//構(gòu)造方法
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);
}
//設(shè)置點(diǎn)擊對(duì)話框外部不可取消
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);
}
}
對(duì)于這種對(duì)話框,并不是每次都需要彈出來(lái),只有用戶在第一次安裝的時(shí)候才會(huì)彈出,后面啟動(dòng)的話就無(wú)需在彈出來(lái)了,所以我們要進(jìn)行一個(gè)判斷,判斷用戶是不是第一次使用
先定義一個(gè)boolean的值,用于判斷用戶是不是第一次使用
//是否是第一次使用 private boolean isFirstUse;
這里可以用SharedPreferences來(lái)進(jìn)行保存這個(gè)值是false還是true
SharedPreferences preferences = getSharedPreferences("isFirstUse", MODE_PRIVATE);
//默認(rèn)設(shè)置為true
isFirstUse = preferences.getBoolean("isFirstUse", true);
如果是第一次使用,那我們就設(shè)置對(duì)應(yīng)的標(biāo)題、內(nèi)容等相關(guān)值,如果不是就不做操作
new AgreementDialog(context, generateSp("感謝您信任并使用" + AppUtils.getAppName(this)+"XXXXXX《"+ AppUtils.getAppName(this) + "用戶協(xié)議》" +
"和《"+ 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:
//實(shí)例化Editor對(duì)象
SharedPreferences.Editor editor = preferences.edit();
//存入數(shù)據(jù)
editor.putBoolean("isFirstUse", false);
//提交修改
editor.commit();
//這里是一開(kāi)始的申請(qǐng)權(quán)限,不懂可以看我之前的博客
requirePermission();
break;
case R.id.tv_dialog_no:
finish();
break;
}
}
}).show();
} else {
}
記得一定要.show(),不然對(duì)話框不會(huì)彈出來(lái),這里面的重點(diǎn)部分在于generateSp()這個(gè)方法,這里就是為了設(shè)置“用戶協(xié)議”這幾個(gè)字體的顏色
private SpannableString generateSp(String text) {
//定義需要操作的內(nèi)容
String high_light_1 = "《用戶協(xié)議》";
String high_light_2 = "《隱私政策》";
SpannableString spannableString = new SpannableString(text);
//初始位置
int start = 0;
//結(jié)束位置
int end;
int index;
//indexOf(String str, int fromIndex): 返回從 fromIndex 位置開(kāi)始查找指定字符在字符串中第一次出現(xiàn)處的索引,如果此字符串中沒(méi)有這樣的字符,則返回 -1。
//簡(jiǎn)單來(lái)說(shuō),(index = text.indexOf(high_light_1, start)) > -1這部分代碼就是為了查找你的內(nèi)容里面有沒(méi)有high_light_1這個(gè)值的內(nèi)容,并確定它的起始位置
while ((index = text.indexOf(high_light_1, start)) > -1) {
//結(jié)束的位置
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) {
// 點(diǎn)擊用戶協(xié)議的相關(guān)操作,可以使用WebView來(lái)加載一個(gè)網(wǎng)頁(yè)
}
}, 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) {
// 點(diǎn)擊隱私政策的相關(guān)操作,可以使用WebView來(lái)加載一個(gè)網(wǎng)頁(yè)
}
}, index, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
start = end;
}
//最后返回SpannableString
return spannableString;
}
最后就是QMUITouchableSpan.java
用來(lái)觸發(fā)用戶點(diǎn)擊時(shí)的相關(guān)操作
/**
* Created by Sammi on 2020/2/27.
* /**
* 可 Touch 的 Span,在 {@link #setPressed(boolean)} 后根據(jù)是否 pressed 來(lái)觸發(fā)不同的UI狀態(tài)
* <p>
* 提供設(shè)置 span 的文字顏色和背景顏色的功能, 在構(gòu)造時(shí)傳入
* </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);
}
}
附上效果圖

總結(jié)
到此這篇關(guān)于Android啟動(dòng)頁(yè)用戶相關(guān)政策彈框的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Android啟動(dòng)頁(yè)用戶相關(guān)政策彈框的實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android App開(kāi)發(fā)中使用RecyclerView實(shí)現(xiàn)Gallery畫廊的實(shí)例
這篇文章主要介紹了Android App開(kāi)發(fā)中使用RecyclerView實(shí)現(xiàn)Gallery畫廊的實(shí)例,比普通的ListView實(shí)現(xiàn)的效果更為強(qiáng)大,需要的朋友可以參考下2016-04-04
Android獲取手機(jī)安裝應(yīng)用程序的詳細(xì)信息
在開(kāi)發(fā)Android應(yīng)用時(shí),有時(shí)我們需要獲取設(shè)備上已安裝的所有應(yīng)用程序的信息,這篇文章為大家整理了一些常用的方法,希望對(duì)大家有所幫助2025-03-03
Android自定義View實(shí)現(xiàn)通訊錄字母索引(仿微信通訊錄)
本文主要介紹了Android自定義View實(shí)現(xiàn)通訊錄字母索引(仿微信通訊錄)的實(shí)現(xiàn)步驟與方法,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2016-12-12
Android端權(quán)限隱私的合規(guī)化處理實(shí)戰(zhàn)記錄
大家應(yīng)該都發(fā)現(xiàn)了,現(xiàn)在很多應(yīng)用市場(chǎng)都要求應(yīng)用上架需要用戶協(xié)議,這篇文章主要給大家介紹了關(guān)于Android端權(quán)限隱私合規(guī)化處理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-08-08
Android中ListView如何分頁(yè)加載數(shù)據(jù)
這篇文章主要介紹了Android中ListView如何分頁(yè)加載數(shù)據(jù),本文就結(jié)合實(shí)例來(lái)演示一下使用ListView獲取數(shù)據(jù)的過(guò)程,需要的朋友可以參考下2015-12-12
Android調(diào)用前后攝像頭同時(shí)工作實(shí)例代碼
本篇文章主要介紹了Android調(diào)用前后攝像頭同時(shí)工作實(shí)例代碼,這里整理了詳細(xì)的代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-07-07

