Android自定义Dialog的2种常见方法

目录
  • 前言
  • 方式一:继承DialogFragment,也是官方推荐的方式
    • 事例
  • 方式二:直接继承Dialog类或者AppCompatDialog类
  • 更新

前言

大多数中,使用系统内置的dialog并不能满足UE的设计需要

方式一:继承DialogFragment,也是官方推荐的方式

通常我们只需要关注三个回调方法:

  • onCreateDialog:创建一个dialog外壳
  • onCreateView:给dialog外壳填充自己想要的样式布局
  • onViewCreated:这里面给布局的view进行初始化操作,可以设置一些监听器等等

事例

自定义布局文件:随便写一个

<?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"//给editText加个外边框
            android:hint="  (optional)"
            android:lineSpacingExtra="3sp"
            android:maxLength="255"
            android:minLines="1"
            android:paddingLeft="5dp"//这个属性的一个妙用可以改变光标的起始位置,不然光标有可能看不到
            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);//不采用系统默认的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横向宽度是充满屏幕的
         }
//        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是不够的,具体这两个参数的详细区别,官方文档说的也很含糊,反正我没读懂。

我比较认同这篇文章的看法: 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,并设置监听器,事件响应等
  • 初始化window相关的属性,比如设置window的宽度和高度,以及window所显示的位置等等

在构造函数中设置想要的主题:这里提供两种比较常用的主题

<!--对话框会在屏幕中间显示-->
<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横向宽度充满整个屏幕 -->
    <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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android自定义Dialog框样式

    本文实例为大家分享了Android自定义Dialog框样式的具体代码,供大家参考,具体内容如下 首先定义dialog的布局文件,buy_goods_dialog.xml如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_w

  • Android自定义样式圆角dialog对话框

    本文实例为大家分享了Android创建自定义样式圆角dialog对话框的具体代码,供大家参考,具体内容如下 效果如上,圆角对话框,标题和正文都可以自己设定 做法: 1.在res文件的layout文件夹创建自己的对话框布局,命名为my_dialog.xml 2.在res文件的drawable文件夹创建自己的对话框样式(圆角),命名为my_dialog_shape.xml 3.写一个方法调用对话框布局,触发条件自定义,这里我是写了一个按钮,在按钮的点击事件里调用方法,弹出对话框.在这个方法里可以定义

  • Android自定义Dialog原理实例解析

    Android开发过程中,常常会遇到一些需求场景--在界面上弹出一个弹框,对用户进行提醒并让用户进行某些选择性的操作, 如退出登录时的弹窗,让用户选择"退出"还是"取消"等操作. Android系统提供了Dialog类,以及Dialog的子类,常见如AlertDialog来实现此类功能. 一般情况下,利用Android提供的Dialog及其子类能够满足多数此类需求,然而,其不足之处体现在: 1. 基于Android提供的Dialog及其子类样式单一,风格上与App本

  • Android自定义底部弹出框ButtomDialog

    本文实例为大家分享了Android自定义底部弹出框的具体代码,供大家参考,具体内容如下 先看看效果和你要的是否一样 一 .先来配置自定义控件需要的资源 1.在res文件夹下创建一个anim文件夹并创建两个slide_in_bottom.xml.slide_out_bottom.xml文件,负责弹框进出动画. <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://

  • android自定义Dialog弹框和背景阴影显示效果

    本文实例为大家分享了android自定义Dialog弹框和背景阴影显示的具体代码,供大家参考,具体内容如下 首先需要自定义一个类,继承Dialog import android.app.Dialog; import android.content.Context; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager;

  • Android 自定义加载动画Dialog弹窗效果的示例代码

    效果图 首先是创建弹窗的背景 这是上面用到的 以shape_bg_5_blue.xml为例,其他的三个无非就是里面的颜色不一样而已 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:radius="5dp"

  • Android自定义Dialog的2种常见方法

    目录 前言 方式一:继承DialogFragment,也是官方推荐的方式 事例 方式二:直接继承Dialog类或者AppCompatDialog类 更新 前言 大多数中,使用系统内置的dialog并不能满足UE的设计需要 方式一:继承DialogFragment,也是官方推荐的方式 通常我们只需要关注三个回调方法: onCreateDialog:创建一个dialog外壳 onCreateView:给dialog外壳填充自己想要的样式布局 onViewCreated:这里面给布局的view进行初始

  • Android自定义dialog简单实现方法

    本文实例讲述了Android自定义dialog简单实现方法.分享给大家供大家参考,具体如下: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.function_music); // 实例化新的窗口 Window w = getWindow(); // 获取默认显示数据 Display display

  • Android 自定义Dialog去除title导航栏的解决方法

    如下所示: Dialog dialog = new Dialog(context); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(view); 以上这篇Android 自定义Dialog去除title导航栏的解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • Android自定义Dialog的方法实例

    因为公司需要不同样式的dialog,既有取消和确认键 又需要只有确认键的 并且系统自带dialog样式太丑 所以就自己做了个 接下来看代码: /** * Created by on 2017/9/16. * 自定义Dialog */ public class MyDialog extends Dialog { private Button yes;//确定按钮 private Button no;//取消按钮 private TextView titleTv;//消息标题文本 private T

  • Android自定义Dialog实现加载对话框效果

    前言 最近开发中用到许多对话框,之前都是在外面的代码中创建AlertDialog并设置自定义布局实现常见的对话框,诸如更新提示等含有取消和删除两个按钮的对话框我们可以通过代码创建一个AlertDialog并通过它暴露的一系列方法设置我们自定义的布局和style,但有时候系统的AlertDialog并不能实现更好的定制,这时,我们就想到了自定义Dialog.通过查看AlertDialog的类结构发现它也是继承于Dialog,于是我们也可以通过继承Dialog实现我们自定义的Dialog.这篇文章将

  • vue3自定义dialog、modal组件的方法

    vue3-layer:基于Vue3.0开发的PC桌面端自定义对话框组件. 基于vue3构建的PC网页端自定义弹出框组件.全面覆盖各种弹窗应用场景,拥有10+种弹窗类型.30+种自定义参数配置.7+种弹窗动画效果,支持拖拽.缩放.最大化.全屏及自定义激活当前置顶层等功能. 前几天分享过一个Vue3.0移动端弹层组件V3Popup,如果感兴趣也可以去看看. https://www.jb51.net/article/203415.htm v3layer在开发设计之初灵感来自有赞Vant3.0.饿了么E

  • Android中Dialog去黑边的方法

    本文实例展示了Android中Dialog去黑边的方法.并且分为保留阴影与不保留阴影两种实现方法.供大家参考借鉴.具体实现方法如下: 1.不保留阴影 代码如下: <?xml version="1.0" encoding="utf-8"?> <resources> <style name="dialog" parent="@android:style/Theme.Dialog"><!--

  • Python实现自定义函数的5种常见形式分析

    本文实例讲述了Python自定义函数的5种常见形式.分享给大家供大家参考,具体如下: Python自定义函数是以def开头,空一格之后是这个自定义函数的名称,名称后面是一对括号,括号里放置形参列表,结束括号后面一定要有冒号":",函数的执行体程序代码也要有适当的缩排.Python自定义函数的通用语法是: def   函数名称(形参列表): 执行体程序代码 Python自定义函数的5种常见形式: 1.标准自定义函数: -----形参列表是标准的tuple数据类型 >>>

  • Android中图片圆角三种实现方法

    目录 方法一 方法二 方法三 Android 开发中,经常需要对图片进行二次处理,比如添加圆角效果 或 显示圆形图片: 方法一 通过第三方框架 Glide 设置圆角效果: 写法1: RequestOptions options = new RequestOptions().error(R.drawable.img_load_failure).bitmapTransform(new RoundedCorners(30));//图片圆角为30 Glide.with(this).load(URL) /

  • ASP.NET中弹出消息框的几种常见方法

    本文实例讲述了ASP.NET中弹出消息框的几种常见方法.分享给大家供大家参考.具体分析如下: 在ASP.NET网站开发中,经常需要使用到alert消息框,尤其是在提交网页的时候,往往需要在服务器端对数据进行检验,并给出提示或警告. 这里,仅介绍几种不同的实现方法. 1.众所周知的方法是采用如下代码来实现: 复制代码 代码如下: Response.Write("<script>alert('弹出的消息')</script>"); 不可否认,这种方法是最常用,也是最

随机推荐