Android换肤之Toast和Dialog

Android  代码片段  2023年3月3日 am8:08发布2年前 (2023)更新 91es.com站长
79 0 0

前言

前面介绍过Android静态换肤日夜模式的切换(原文:《Android静态换肤-日夜主题切换之继承Activity记录 》),从中我们知道,ToastDialog存在无法切换成功。原因是Toast或者Dialog是需要时才去初始化的,此时换肤插件没法获取到View。

PS:日夜模式不存在这个问题,当时记错了,应该动态换肤才有这个问题。因为Android本身就对日夜模式进行了优化,主动会重新获取对应模式下的资源。

本文就不删除了,作为自己的过程。

解决这个问题其实有两种方式

  1. 弹出Toast或Dialog时显示前通过换肤插件SkinManager获取当前皮肤的背景和颜色资源
  2. 提前初始化Toast和Dialog的布局即可

第一个方式就是我们在需要时重新设置;对于第二种方式,就是提前加载布局,让换肤lib获取到对应的View,这样就会自动切换。

今天就简单记录一下第二种,方便自己查阅。

正文

直入正题。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //Toast和Dialog提前初始化Layout
    ToastUtils.getInstance().initLayout(SkinApp.getContext());
    DialogUtils.getInstance().initLayout(SkinApp.getContext());
}

Toast

也就是Toast的简单封装。

Toast.java
public class ToastUtils {
    private Toast mToast = null;
    private View mRootView = null;
    private Context mContext;

    private ToastUtils() {
    }

    private static class ToastHolder {
        @SuppressLint("StaticFieldLeak")
        static ToastUtils toastUtils = new ToastUtils();
    }

    public static ToastUtils getInstance() {
        return ToastHolder.toastUtils;
    }

    @SuppressLint("InflateParams")
    public void initLayout(Context context) {
        mContext = context;
        mRootView = LayoutInflater.from(context).inflate(R.layout.toast_tips_layout, null);
    }

    public void show(int gravity, int xOffset, int yOffset, int duration, String message) {
        if (null == mContext || null == mRootView) {
            throw new RuntimeException("Please call initLayout() first.");
        }
        hide(); //确保只有一个
        mToast = new Toast(mContext);
        mToast.setView(mRootView);
        mToast.setGravity(gravity, xOffset, yOffset);
        ((TextView) mRootView.findViewById(R.id.toast_tv_tip_text)).setText(message);
        mToast.setDuration(duration);
        mToast.show();
    }

    public void hide() {
        if (null != mToast) {
            mToast.cancel();
            mToast = null;
        }
    }

    public void release() {
        hide();
        mRootView = null;
        mContext = null;
    }
}

Dialog

跟Toast差不多

styles.xml
<style name="dialog_theme" parent="@android:style/Theme.Dialog">
    <item name="android:windowFrame">@null</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:background">@android:color/transparent</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:backgroundDimEnabled">true</item>
    <item name="android:backgroundDimAmount">0.5</item>
</style>
DialogUtils.java
public class DialogUtils {

    private static Dialog mDialog = null;
    private View mRootView = null;

    private DialogUtils() {
    }

    private static class DialogHolder {
        @SuppressLint("StaticFieldLeak")
        static DialogUtils dialogUtils = new DialogUtils();
    }

    public static DialogUtils getInstance() {
        return DialogHolder.dialogUtils;
    }

    @SuppressLint("InflateParams")
    public void initLayout(Context context) {
        mRootView = LayoutInflater.from(context).inflate(R.layout.dialog_tips_layout, null);
        mDialog = new Dialog(context, R.style.dialog_theme);
    }

    public void show(int gravity, int width, int height, boolean cancel, String message) {
        if (null == mDialog || null == mRootView) {
            throw new RuntimeException("Please call initLayout() first.");
        }
        ((TextView) mRootView.findViewById(R.id.dialog_tv_tip_text)).setText(message);
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width, height);
        mDialog.setContentView(mRootView, layoutParams);
        mDialog.setCanceledOnTouchOutside(cancel);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
        } else {
            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE);
        }

        mDialog.getWindow().setGravity(gravity);
        mDialog.show();
    }

    public void hide() {
        if (null != mDialog) {
            mDialog.dismiss();
        }
    }

    public boolean isShowing() {
        if (null != mDialog) {
            return mDialog.isShowing();
        }
        return false;
    }

    public void release() {
        hide();
        mDialog = null;
        mRootView = null;
    }
}

参考文章

版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

梁实秋:先生们的书房

书房,多么典雅的一个名词!很容易令人联想到一个书香人家。书香是与铜臭相对待的。其实书未必香,铜亦未必臭。周彝商鼎,古色斑烂,终日摩娑亦不觉其臭,铸成钱币才沾染市侩味,可是不复流通的布帛刀错又常为高人赏玩之资。书之所以为香,大概是指松烟油墨印上了毛边连史,从不大通风的书房里散发出来的那一股怪味,不是桂...

低版本API废弃的警告Dialog

前言Android高版本上安装一些旧的APP,会存在会弹出对话框,内容:“此应用专为旧版Android打造,因此可能无法正常运行。请尝试检查更新或与开发者联系”。这样不是很友好,客户要求去掉。正文原因本质是Android高版本对启动应用的支持SDK的检测。下面是网上分析的,摘抄于此。...

[摘]查找当前目录下所有文件某一行的内容

前言在做monkey时,会间隔把当前所有应用的内存占用打印出来,因此为了方便查看内存是否有持续增长,会使用命令查看所有dump的文件内容。好记性不如烂笔头正文以下在Window系统中的git bash环境中测试(或者算是Linux环境)find . -type f -name “*.tx...

[摘]Android横屏和竖屏的方法

前言本文摘抄,方便自己查阅。正文AndroidManifest.xml配置在指定的要设置的Activity对应的标签中加入android:screenOrientation相关属性。unspecified:默认值 由系统来推断显示方向.判定的策略是和设备相关的,所以不同的设备会有不同的...

王安忆:洗澡

行李前的马路上没有一棵树,太阳就这样直晒下俩。他已经将八大包书捆上了自行车,自行车再也动不了了。那小伙子早已注意他了,很有信心地骑在他的黄鱼车上,他徒劳地推了推车,车却要倒,扶也扶不住。小伙子超前骑了半步,又朝后退了半步,然后说:“师傅要去哪里?”他看了那人一眼停了一下,才说:“静安寺。”小伙子就说...

[摘]Android如何设置TextView的行间距、行高。

在Android系统中TextView默认行间距比较窄,不美观。我们可以设置每行的行间距,可以通过属性android:lineSpacingExtra或android:lineSpacingMultiplier来做。修改行间距、行高你可以使用如下TextView属性1、android:lin...