自定义Dialog Theme的Activity

##背景
最近公司开发NFC开门的功能,咋一眼看功能很简单,直接用Dialog方式封装就能解决问题。但是我们公司是模块化的方式搭建开发App,为了让模块间的代码层次清晰与扩展及易与阅读,因此我们最终用Activity的方式实现Dialog的样式及功能。
Dialog 1
dialog 2

以下的开发过程以dialog1图片举例说明

##开发过程
###1.创建Theme样式

   

1、如果继承的Activity是AppCompatActivity,需要用@style/AppTheme XX的样式
2、如果阴影部分出现文字,用windowNoTitle和android:windowNoTitle设置为True即可

扩展:1.windowNoTitle = false 并且 android:windowNoTitle = false 时,会出现两个标题,位于下方的是AppCompatActivity的标题栏。
2.windowNoTitle = true并且 android:windowNoTitle = true时 ,无标题。

###2.创建Activity动画

 

####2.1 淡出淡入动画





###3.创建自定义Dialog实现
####3.1 layout布局

  

        

        

    

#####3.1.1 btn_black_shape_25.xml




    
    

#####3.1.2 common_rounded_dialog_bg.xml



    

    

####3.2 activity实现

在实现全屏显示Dialog显示时,一定要注意适配Android 8.0,网络上上大多说“删除AndroidManifest.xml中相应Activity的 android:screenOrientation="“属性;或者删除相应Activity的android:theme=”"属性中对应style中true属性”,我认为使用Hook方式优雅绕过检查来实现效果会更好。

class UnlockDoorActivity : BaseDataBindingActivity() {

    var hasFinishView = true

    override fun onCreate(savedInstanceState: Bundle?) {
        
        ActivityHook.hookOrientation(this)
        super.onCreate(savedInstanceState)

        val windowManager: WindowManager? = this.windowManager
        val display: Display? = windowManager?.defaultDisplay
        val lp = this.window?.attributes
        lp?.width = display?.width
        lp?.gravity = Gravity.BOTTOM
        this.window?.attributes = lp
    }

   ....
    override val layoutId: Int = R.layout.activity_unlock_door
   ....

    override fun finish() {
        super.finish()
        //activity消失时的动画
        overridePendingTransition(R.anim.fade_in, R.anim.fade_out)
    }
}

3.2.2 ActivityHook.java

/**
 * http://www.manongjc.com/article/37655.html
 */
public class ActivityHook {

  /**
   * java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
   * 

* 修复android 8.0存在的问题 *

* 在Activity中onCreate()中super之前调用 * * @param activity Activity */ public static void hookOrientation(Activity activity) { //目标版本8.0及其以上 if (activity.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) { if (isTranslucentOrFloating(activity)) { fixOrientation(activity); } } } /** * 设置屏幕不固定,绕过检查 * * @param activity Activity */ private static void fixOrientation(Activity activity) { try { Class activityClass = Activity.class; Field mActivityInfoField = activityClass.getDeclaredField("mActivityInfo"); mActivityInfoField.setAccessible(true); ActivityInfo activityInfo = (ActivityInfo) mActivityInfoField.get(activity); //设置屏幕不固定 activityInfo.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; } catch (Exception e) { e.printStackTrace(); } } /** * 检查屏幕 横竖屏或者锁定就是固定 * * @param activity Activity * @return true */ private static boolean isTranslucentOrFloating(Activity activity) { boolean isTranslucentOrFloating = false; try { Class styleableClass = Class.forName("com.android.internal.R$styleable"); Field WindowField = styleableClass.getDeclaredField("Window"); WindowField.setAccessible(true); int[] styleableRes = (int[]) WindowField.get(null); //先获取到TypedArray final TypedArray typedArray = activity.obtainStyledAttributes(styleableRes); Class ActivityInfoClass = ActivityInfo.class; //调用检查是否屏幕旋转 Method isTranslucentOrFloatingMethod = ActivityInfoClass.getDeclaredMethod("isTranslucentOrFloating", TypedArray.class); isTranslucentOrFloatingMethod.setAccessible(true); isTranslucentOrFloating = (boolean) isTranslucentOrFloatingMethod.invoke(null, typedArray); } catch (Exception e) { e.printStackTrace(); } return isTranslucentOrFloating; } }

##参考
android 8.0 Only fullscreen opaque activities can request orientation(Hook方式优雅绕过检查 )

你可能感兴趣的:(自定义activity,dialog,主题)