Android自定義Dialog的2種常見方法
前言
大多數(shù)中,使用系統(tǒng)內(nèi)置的dialog并不能滿足UE的設計需要
方式一:繼承DialogFragment,也是官方推薦的方式
通常我們只需要關注三個回調(diào)方法:
- onCreateDialog:創(chuàng)建一個dialog外殼
- onCreateView:給dialog外殼填充自己想要的樣式布局
- onViewCreated:這里面給布局的view進行初始化操作,可以設置一些監(jiān)聽器等等
事例
自定義布局文件:隨便寫一個
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/threat_call_rootView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/dialog_white_big_corner_roundrect_bg">
<LinearLayout
android:id="@+id/threat_call_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/dialog_white_big_corner_roundrect_bg"
android:orientation="vertical"
android:paddingLeft="32dp"
android:paddingTop="48dp"
android:paddingRight="32dp"
android:paddingBottom="48dp">
<TextView
android:id="@+id/threat_call_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="標題"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/threat_call_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:lineSpacingExtra="3sp"
android:text="正文"
android:textColor="@color/black"
android:textSize="14sp" />
<EditText
android:id="@+id/threat_call_edittext"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="16dp"
android:width="100dp"
android:background="@drawable/sip_threat_call_dialog_edittext_stroke"http://給editText加個外邊框
android:hint=" (optional)"
android:lineSpacingExtra="3sp"
android:maxLength="255"
android:minLines="1"
android:paddingLeft="5dp"http://這個屬性的一個妙用可以改變光標的起始位置,不然光標有可能看不到
android:text=""
android:textCursorDrawable="@null"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/threat_call_block_btn"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="16dp"
android:background="@drawable/sip_threat_call_dialog_btn_bg"
android:gravity="center"
android:text="BLOCK"
android:textStyle="bold" />
<Button
android:id="@+id/threat_call_cancel_btn"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="1dp"
android:background="@drawable/sip_threat_call_dialog_btn_bg"
android:gravity="center"
android:text="CANCEL"
android:textStyle="bold" />
</LinearLayout>
</RelativeLayout>selfFragment類:
package com.example.hellojni;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
public class selfDialogFragment extends DialogFragment {
View container;
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
return new Dialog(getContext(),R.style.bottom_dialog);
// return super.onCreateDialog(savedInstanceState);//不采用系統(tǒng)默認的dialog樣式,自定義dialog主題
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Window window = getDialog().getWindow();
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.WRAP_CONTENT);
window.setGravity(Gravity.CENTER);//設置dialog位置處于中央
if(!iPaid(getContext())){
window.getDecorView().setMinimumWidth(getResources().getDisplayMetrics().widthPixels);//這個設置的目的是為了讓dialog橫向?qū)挾仁浅錆M屏幕的
}
// window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);//本來想解決dialog打開軟鍵盤后,彈窗跟著往上走的效果,效果確實有,不過依然沒有解決我的問題,下面會詳解。
return inflater.inflate(R.layout.dialog_block_reason,container,false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
View dialogViewContent = view.findViewById(R.id.block_number_container);
EditText editText = view.findViewById(R.id.optional_block_number);
container = view.findViewById(R.id.block_number_container);
editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
dialogViewContent.setOnTouchListener(new View.OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
//強制收起軟件盤的方式:
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(),0);
return false;
}
});
view.findViewById(R.id.cancel_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismissAllowingStateLoss();
hideSoftInputAndDissmissDialog();
}
});
private void hideSoftInputAndDissmissDialog() {
dismissAllowingStateLoss();
if (getActivity() != null) {//為了解決dialog彈出軟鍵盤退出界面后軟鍵盤依然存在的問題
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
}
@Override
public void onStart() {
super.onStart();
}
//判斷是否為Pad的方法,通過計算屏幕對角線長度
private boolean isPad(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
double x = Math.pow(dm.widthPixels / dm.xdpi, 2);
double y = Math.pow(dm.heightPixels / dm.ydpi, 2);
double screenInches = Math.sqrt(x + y); // 屏幕尺寸
return screenInches >= 7.0;
}
}- 坑點講解
- 當dialog有editText的時候,如果你的dialog主題中的
<item name="android:windowIsFloating">false</item> 指定為false的話,即便加上了 window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);也不行 效果如下:可以清楚的看到,軟鍵盤還是擋住了兩個按鈕

android:windowIsFloating設為true時,效果如下:

不過中間多出來的那塊我也不知道受什么因素影響的,目前這個樣式還能湊活用吧
- 默認的dialog并非是橫向充滿屏幕的
我這邊用了使用了window.getDecorView().setMinimumWidth(getResources().getDisplayMetrics().widthPixels); 生效了,有的博客說是使用 window.getDecorView().setPadding(0,0,0,0)或者主題中有個屬性android:windowFullscree,不過這兩個我試過都貌似都沒有什么效果
- 當打開軟鍵盤,然后點擊空白處的時候,dialog消失,但是軟鍵盤卻還是打開著。
這個點我使用了getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);解決了,這句話等同于在展示dialog的activity中androidMenifests文件中設置 andorid:windowSoftInputMode = stateAlwaysHidden,而僅僅設置成stateHidden是不夠的,具體這兩個參數(shù)的詳細區(qū)別,官方文檔說的也很含糊,反正我沒讀懂。
我比較認同這篇文章的看法: Android 進入Activity時如何禁止彈出軟鍵盤輸入法
- 默認的dialog出場以及退場動畫是采用了縮放以及透明度,可以在主題中自定義出場動畫
enter動畫:
<?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromYDelta="100%p" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:toYDelta="50%p" android:duration="200"> </translate>
exit動畫:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<scale android:fromXScale="1.0" android:toXScale="0.9"
android:fromYScale="1.0" android:toYScale="0.9"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@android:anim/decelerate_interpolator"
android:duration="150" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:interpolator="@android:anim/decelerate_interpolator"
android:duration="150"/>
</set>方式二:直接繼承Dialog類或者AppCompatDialog類
通常只需要關注onCreate方法,在該方法中,一般需要做如下幾個事情:
- 通過
setContentView將自定義的布局填充到dialog中去 - 初始化布局中的子view,并設置監(jiān)聽器,事件響應等
- 初始化window相關的屬性,比如設置window的寬度和高度,以及window所顯示的位置等等
在構造函數(shù)中設置想要的主題:這里提供兩種比較常用的主題
<!--對話框會在屏幕中間顯示-->
<style name="dialog_theme_center_dispay" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item><!-- 設置dialog空白背景-->
<item name="android:windowIsFloating">true</item> <!-- dialog是否懸浮,當有軟鍵盤的時候會被頂上去-->
<item name="android:windowIsTranslucent">false</item> <!-- dialog是否半透明 -->
<item name="android:windowMinWidthMinor">100%</item> <!-- dialog橫向?qū)挾瘸錆M整個屏幕 -->
<item name="android:windowNoTitle">true</item><!-- dialog是否有標題 -->
<item name="android:windowBackground">@color/transparent</item><!-- dialog背景是透明的 -->
<item name="android:background">@color/transparent</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowSoftInputMode">stateHidden|adjustResize</item>
</style>
<!--對話框會從底部彈出-->
<style name="dialog_theme_bottom2top">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@color/transparent</item>
<item name="android:backgroundDimEnabled">true</item> <!--是否允許對話框的背景變暗:如果允許背景就變暗了。-->
<item name="android:windowMinWidthMinor">100%</item><!--寬度鋪滿全屏-->
<item name="android:windowCloseOnTouchOutside">true</item><!--點擊陰影的地方是否可以關閉對話框-->
<item name="android:windowAnimationStyle">@style/dialog_anim_bottom2top</item><!--對話框動畫-->
<item name="android:windowSoftInputMode">stateHidden|adjustResize</item>
</style>
<!--[對話框動畫]對話框會從底部彈出-->
<style name="dialog_anim_bottom2top" parent="@android:style/Animation">
<item name="android:windowEnterAnimation">@anim/bottom_in</item>
<item name="android:windowExitAnimation">@anim/bottom_out</item>
</style>bottom_in:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromYDelta="100%p"
android:toYDelta="0" />
</set>bottom_out:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="200"
android:fromYDelta="0"
android:toYDelta="50%p" />
<alpha
android:duration="200"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>更新
辨別當前設備是否是平板的方法通常有兩種:
public static boolean isLargeScreen(Context context) {
Configuration config = context.getResources().getConfiguration();
int size = config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
return (size >= Configuration.SCREENLAYOUT_SIZE_LARGE);
}public static boolean isPad(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
double x = Math.pow(dm.widthPixels / dm.xdpi, 2);
double y = Math.pow(dm.heightPixels / dm.ydpi, 2);
double screenInches = Math.sqrt(x + y); // 屏幕尺寸
return screenInches >= 7.0;
}
到此這篇關于Android自定義Dialog的2種常見方法的文章就介紹到這了,更多相關Android自定義Dialog內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- Android自定義Dialog框樣式
- Android自定義Dialog原理實例解析
- Android 自定義加載動畫Dialog彈窗效果的示例代碼
- Android自定義底部彈出框ButtomDialog
- android自定義Dialog彈框和背景陰影顯示效果
- Android自定義Dialog實現(xiàn)通用圓角對話框
- Android自定義dialog 自下往上彈出的實例代碼
- Android 自定義Dialog去除title導航欄的解決方法
- Android自定義Dialog實現(xiàn)加載對話框效果
- Android編程自定義AlertDialog樣式的方法詳解
- 解決Android中自定義DialogFragment解決寬度和高度問題
- Android 自定義 Dialog 實現(xiàn)列表 單選,多選,搜索功能
相關文章
Android中RecyclerView點擊Item設置事件
這篇文章主要介紹了Android中RecyclerView點擊Item設置事件的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-07-07
Android中ListView分頁加載數(shù)據(jù)功能實現(xiàn)
本篇文章主要介紹了Android中ListView分頁加載數(shù)據(jù)功能實現(xiàn),具有一定的參考價值,有需要的可以了解一下。2016-11-11
Android開發(fā)實現(xiàn)實時檢測藍牙連接狀態(tài)的方法【附源碼下載】
這篇文章主要介紹了Android開發(fā)實現(xiàn)實時檢測藍牙連接狀態(tài)的方法,涉及Android針對藍牙連接狀態(tài)的監(jiān)測操作相關實現(xiàn)技巧,需要的朋友可以參考下2017-11-11
Android實現(xiàn)使用微信登錄第三方APP的方法
這篇文章主要介紹了Android實現(xiàn)使用微信登錄第三方APP的方法,結合實例形式分析了Android微信登錄APP的操作步驟與具體功能實現(xiàn)技巧,需要的朋友可以參考下2016-11-11
新版Flutter集成到已有Android項目的實現(xiàn)
這篇文章主要介紹了新版Flutter集成到已有Android項目的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-03-03
Android編程實現(xiàn)Listview點擊展開和隱藏的方法
這篇文章主要介紹了Android編程實現(xiàn)Listview點擊展開和隱藏的方法,涉及Android中Listview的響應點擊與樣式變換相關操作技巧,需要的朋友可以參考下2015-12-12

