彈框場景:
1.只是某個界面需要彈框
比如當應(yīng)用進入主界面,需要提框提示升級時漩蟆,這個彈框就只會在當前Activity出現(xiàn),這個時候可以直接使用AlertDialog
//alertDialog初始化窒升,注意使用v7包下的AlertDialog跷睦,這樣樣式可以統(tǒng)一
//上下文傳入需要綁定彈框的Activity引用,這里不可傳ApplicationContext
//因為該window類型默認是TYPE_APPLICATION,token只能是Activity
final AlertDialog updateDialog = new AlertDialog.Builder(ctx, R.style.app_update)
.setCancelable(false)
.create();
updateDialog.show();
//自定義布局需要在show方法后調(diào)用
updateDialog.setContentView(R.layout.activity_updatedialog);
//R.style.app_update,自定義的彈框樣式溅潜,注意使用AppCompat主題
<style name="app_update" parent="@style/Theme.AppCompat.Dialog.Alert">
<item name="android:windowBackground">@drawable/bg_insert_1</item>
<item name="windowMinWidthMajor">85%</item>
<item name="windowMinWidthMinor">85%</item>
</style>
//windowbackground背景
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="16dp"
android:insetTop="16dp"
android:insetRight="16dp"
android:insetBottom="16dp">
<shape android:shape="rectangle">
<corners android:radius="10dp" />
<solid android:color="#e6ffffff" />
</shape>
</inset>
需要注意的是术唬,這種彈框的顯示不會執(zhí)行Activity的onPause,另外彈框的寬度可以通過改變windowMinWidthMajor和windowMinWidthMinor加上inset同時改變,inset屬性類似于padding滚澜,這些屬性和布局都是從源碼里面試驗和摳出來的,彈框位置可以代碼設(shè)置window的gravity屬性來調(diào)節(jié)(ps:還沒找到xml里對應(yīng)的屬性來更改)
2.需要彈框的地方在app各個地方粗仓,而且屏幕其他位置還能接收到觸摸事件
比如一個競拍app需要顯示競拍推送信息,這個彈框就是全局提示了,這種需求相當于就是自定義Toast借浊,但是我們的需求可能更復(fù)雜些塘淑,需要彈出和彈出動畫,彈框內(nèi)有點擊事件蚂斤,支持自定義顯示時間存捺,進入后臺或者其他其他應(yīng)用時彈框消失,當應(yīng)用不處于前臺時不彈框曙蒸,簡直了捌治。。纽窟。
final WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
view = LayoutInflater.from(ctx).inflate(R.layout.ending_push, null, false);
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.MATCH_PARENT;
//彈框位于頂部
params.gravity = Gravity.TOP;
params.format = PixelFormat.TRANSLUCENT;
//轉(zhuǎn)場動畫
params.windowAnimations = R.style.ending_push_anim;
//window類型為toast肖油,很重要
params.type = WindowManager.LayoutParams.TYPE_TOAST;
params.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
//通過窗體管理器添加一個新的window
wm.addView(view, params);
runnable = new Runnable() {
@Override
public void run() {
if (view.getParent() != null) {
wm.removeView(view);
}
}
};
//十秒后移除
view.postDelayed(runnable,10*1000);
//window轉(zhuǎn)場動畫
<style name="ending_push_anim" parent="android:Animation">
<item name="android:windowEnterAnimation">@anim/slide_in_down</item>
<item name="android:windowExitAnimation">@anim/slide_out_up</item>
</style>
這里的上下文傳ApplicationContext和Activity是有區(qū)別的,區(qū)別是前者退出activity還是存在师倔,后者退出綁定的activity消失构韵,但是都可以在其他的activity正常彈出。至于判斷當前是否處于前后臺和進入前后臺的回調(diào)趋艘,相信有很多工具類疲恢,我使用的是一個類實現(xiàn)ActivityLifecycleCallbacks,監(jiān)聽Activity的onPause和onResume瓷胧,如果成對出現(xiàn)显拳,則在app應(yīng)用內(nèi),如果只有onPause搓萧,則進入后臺杂数,如果只有onResume,則進入前臺瘸洛。
3.需要彈框的地方在app各個地方揍移,但是需要屏蔽掉界面的觸摸事件
比如提示登錄的彈窗,需要在要登錄的邏輯處彈窗反肋,這個時候我們可以使用Dialog樣式的Activity那伐。
public class LoginDialogActivity extends BaseActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_auction_remindpay);
// 設(shè)置成觸摸window外部不會讓window消失
setFinishOnTouchOutside(false);
ButterKnife.bind(this);
}
@OnClick(R.id.ib_close)
void close() {
finish();
}
//屏蔽返回鍵
@Override
public void onBackPressed() {
}
}
<activity android:name=".LoginDialogActivity"
android:theme="@style/login"
android:screenOrientation="portrait"/>
<style name="auction_order_remind" parent="@style/Theme.AppCompat.Dialog.Alert">
<item name="android:windowBackground">@drawable/bg_insert_1</item>
<item name="android:textColor">@android:color/black</item>
<item name="windowMinWidthMajor">45%</item>
<item name="windowMinWidthMinor">45%</item>
//activity會默認有個title,這個屬性可以讓它消失
<item name="windowNoTitle">true</item>
//自定義背景模糊程度
<item name="android:backgroundDimAmount">0.6</item>
</style>
總結(jié)
寫這篇文章之前石蔗,百度了很多有關(guān)Dialog設(shè)置樣式的文章罕邀,基本都是千篇一律像這樣的:
<style name="custom_dialog" parent="@style/Theme.AppCompat.Dialog">
<item name="android:windowMinWidthMajor">90%</item>
<item name="android:windowMinWidthMinor">90%</item>
<item name="android:windowFrame">@android:color/transparent</item><!--邊框 -->
<item name="android:windowIsFloating">true</item><!--是否浮現(xiàn)在activity之上 -->
<item name="android:windowIsTranslucent">true</item><!--半透明 -->
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:backgroundDimEnabled">true</item><!--模糊 -->
</style>
其實最后效果也對,但是有些屬性真心沒有作用或者已經(jīng)設(shè)置過了养距,有些問題一定要明明白白诉探,切不可蒙混過關(guān)。