Android啟動(dòng)頁(yè)用戶相關(guān)政策彈框的實(shí)現(xiàn)代碼
現(xiàn)在Android上架各大平臺(tái)都要求App首頁(yè)添加一個(gè)彈框,顯示用戶協(xié)議以及一些隱私政策,不然上架各大平臺(tái),現(xiàn)在就來簡(jiǎn)單的實(shí)現(xiàn)一下這個(gè)對(duì)話框
既然是一個(gè)對(duì)話框,那我們就先來簡(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文件這里就不放出來了,不懂得可以問問度娘,主要就是設(shè)置個(gè)圓角,然后還有顏色
AgreementDialog.java
這里就是封裝的對(duì)話框,包括標(biāo)題、確定、取消等一些控件的封裝,主要我們用SpannableString 這個(gè)來實(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ì)話框,并不是每次都需要彈出來,只有用戶在第一次安裝的時(shí)候才會(huì)彈出,后面啟動(dòng)的話就無需在彈出來了,所以我們要進(jìn)行一個(gè)判斷,判斷用戶是不是第一次使用
先定義一個(gè)boolean的值,用于判斷用戶是不是第一次使用
//是否是第一次使用 private boolean isFirstUse;
這里可以用SharedPreferences來進(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(); //這里是一開始的申請(qǐng)權(quán)限,不懂可以看我之前的博客 requirePermission(); break; case R.id.tv_dialog_no: finish(); break; } } }).show(); } else { }
記得一定要.show(),不然對(duì)話框不會(huì)彈出來,這里面的重點(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 位置開始查找指定字符在字符串中第一次出現(xiàn)處的索引,如果此字符串中沒有這樣的字符,則返回 -1。 //簡(jiǎn)單來說,(index = text.indexOf(high_light_1, start)) > -1這部分代碼就是為了查找你的內(nè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來加載一個(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來加載一個(gè)網(wǎng)頁(yè) } }, index, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); start = end; } //最后返回SpannableString return spannableString; }
最后就是QMUITouchableSpan.java
用來觸發(fā)用戶點(diǎn)擊時(shí)的相關(guān)操作
/** * Created by Sammi on 2020/2/27. * /** * 可 Touch 的 Span,在 {@link #setPressed(boolean)} 后根據(jù)是否 pressed 來觸發(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 設(shè)置圓角圖片實(shí)現(xiàn)代碼
在android應(yīng)用開發(fā)中,可能是美化需要,圖片需要處理成圓角,本文將給出實(shí)現(xiàn)代碼,開發(fā)中的遇到此問題的朋友可以參考下2012-11-11RecyclerView 源碼淺析測(cè)量 布局 繪制 預(yù)布局
這篇文章主要介紹了RecyclerView 源碼淺析測(cè)量 布局 繪制 預(yù)布局,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12詳解Android Material設(shè)計(jì)中陰影效果的實(shí)現(xiàn)方法
這篇文章主要介紹了Android Material設(shè)計(jì)中陰影效果的實(shí)現(xiàn)方法,包括自定義陰影的輪廓和裁剪等,需要的朋友可以參考下2016-04-04Android實(shí)現(xiàn)快遞單號(hào)查詢快遞狀態(tài)信息
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)快遞單號(hào)查詢快遞狀態(tài)信息,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Android 自定義ProgressDialog進(jìn)度條對(duì)話框用法詳解
ProgressDialog為進(jìn)度對(duì)話框。android手機(jī)自帶的對(duì)話框顯得比較單一,我們可以通過ProgressDialog來自己定義對(duì)話框中將要顯示出什么東西2016-01-01android中SharedPreferences實(shí)現(xiàn)存儲(chǔ)用戶名功能
本篇文章主要介紹了android中SharedPreferences實(shí)現(xiàn)保存用戶名功能,詳細(xì)的介紹了SharedPreferences的功能,需要的朋友可以參考下2017-04-04Android編程實(shí)現(xiàn)文件瀏覽功能的方法【類似于FileDialog的功能】
這篇文章主要介紹了Android編程實(shí)現(xiàn)文件瀏覽功能的方法,可實(shí)現(xiàn)類似于FileDialog的功能,涉及Android針對(duì)文件與目錄操作的相關(guān)技巧,需要的朋友可以參考下2016-11-11Android 超詳細(xì)SplashScreen入門教程
Android 12正式版即將發(fā)布,有一個(gè)非常顯著的視覺變化就是,Android 12強(qiáng)制給所有的App都增加了SplashScreen的功能。是的,即使你什么都不做,只要你的App安裝到了Android 12手機(jī)上,都會(huì)自動(dòng)擁有這個(gè)新功能2022-03-03Android 夜間模式的實(shí)現(xiàn)代碼示例
本篇文章主要介紹了Android 夜間模式的實(shí)現(xiàn)代碼示例,實(shí)現(xiàn)能夠根據(jù)不同的設(shè)定,呈現(xiàn)不同風(fēng)格的界面給用戶,有興趣的可以了解一下。2017-03-03