Android开罐头———打造动漫二次元加载读取的自定义dialog

自定义dialog当然已经被写烂咯,本文的重点是很方便地获取二次元动漫动图。自带的progress dialog看腻了吗?来换个和bilibili一样的动漫二次元加载吧!

image.png

一、动画来源获取

1.1 来源简介

先来预览下效果咯:

yicha3.gif

很萌很萌吧!!!loading动画当然还是帧动画咯,由于是二次元,pixiv(俗称p站)可谓是动漫图片最多的站点了,上面有数以亿计的动漫图片和动图。

pixiv :新兴的日本同人画、插画作品分享站点。
采用了web2.0的方式,每个参与者都有自己的主页并可以对作品评价打分。

但是由于版权的保护性政策,动图是无法直接下载到gif的,所以我们必须通过一些非常规手段获取,巧合的是,获取到的是动画帧的图片压缩包,所以可以直接拿来当做安卓开发的帧动画使用!

1.2 动画帧获取

p站如今支持中文,所以阅读上没有了障碍,大家可以搜索自己喜欢主题的动图,或者直接去每日排行榜获取高人气动图,我们以此链接 为例。

  • 使用chrome内核的浏览器,右键选择检查:


    image.png
  • 进入开发者工具界面后,按下Ctrl+FCommand+F)搜索关键词zip,其实已经可以看到我们要的下载链接了,但是不能直接复制,必须选中整个段落后,右键copy到文本编辑器中。
    image.png
  • 在文本编辑器中,删除所有的转义字符\后,复制名字里带有600x600的那个zip链接,然后粘贴到浏览器或者迅雷中下载。

    image.png

  • 解压后即可获得动画帧图片,顺序为名称。


    image.png

警告:pixiv站点所有图片拥有版权©️,商用请联系原作者,下载仅仅是个人学习参考之用。

二、帧动画xml文件的建立

怕是没有人不会吧,直接贴代码了,具体的duration根据实际情况自己调节:

<animation-list
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false"
>
    <item
        android:drawable="@drawable/loading_1"
        android:duration="100"
    />
    <item
        android:drawable="@drawable/loading_2"
        android:duration="100"
    />
    <item
        android:drawable="@drawable/loading_3"
        android:duration="100"
    />
    <item
        android:drawable="@drawable/loading_4"
        android:duration="100"
    />
    <item
        android:drawable="@drawable/loading_5"
        android:duration="100"
    />
    <item
        android:drawable="@drawable/loading_6"
        android:duration="100"
    />
    <item
        android:drawable="@drawable/loading_7"
        android:duration="100"
    />
    <item
        android:drawable="@drawable/loading_8"
        android:duration="100"
    />
</animation-list>

三、自定义dialog的建立

3.1 Dialog概念

dialog的官方定义:

A dialog is a small window that prompts the user to make a decision or enter additional information. A dialog does not fill the screen and is normally used for modal events that require users to take an action before they can proceed.

先来了解下什么是Window:

Window表示窗口的概念,它实际上是View的直接管理者,包括View的视图创建,事件分发机制都必须先经过Window。

自定义Dialog,要先明确Dialog的地位。

  • View是android中视图的呈现方式,但是View不能单独存在,必须依附在Window窗口这个抽象概念上,而Android中提供视图的地方有Activity,Dialog,Toast。
  • 所以某种程度上来说,Dialog是和活动平起平坐的,Dialog的Window创建过程与Activity类似(几乎没区别),所以Dialog也有setContentView方法。具体的创建过程可以参考《Android开发艺术探索》这本书。

所以我们在后面想要管理Dialog的对话框大小就必须使用WindowManager类,而不是去设置父布局的params。

3.2 建立dialog布局文件

直接上代码了,注意,我直接在布局最外层设定了固定的大小,且使用了一个圆角半透明矩形shape作为背景。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="120dp"
    android:layout_height="120dp"
    android:layout_gravity="center_horizontal"
    android:background="@drawable/shape_dialog_bg"
    android:layout_centerInParent="true"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp">

        <ImageView
            android:id="@+id/loading_view"
            android:layout_width="85dp"
            android:layout_height="85dp"
            android:scaleType="fitCenter"
            android:layout_centerInParent="true"
            android:src="@drawable/loading_data_anim"
            />

    </RelativeLayout>

    <TextView
        android:id="@+id/tv_load_dialog"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="读取中……"
        android:layout_marginTop="5dp"
        android:textColor="@color/color_666666"
        android:textSize="12sp"/>

</LinearLayout>

效果图:

image.png

3.3 自定义dialog的建立

我们新建一个类LoadingDialog继承自Dialog,初始化布局参数:

private void initView() {
       setContentView(R.layout.dialog_loading_layout);
       imageView = (ImageView) findViewById(R.id.loading_view);
       //启动我们的二次元帧动画
       AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable();
       animationDrawable.start();


       //获取WindowManager.LayoutParams来管理dialog最外部window的大小,理由在3.1          节中已经说明。其实这里不用设置,因为我们在布局最外层指定了居中,且设为固定大小             后对话框最外层布局会自适应(但是android5.0以上默认最外布局match_parent)。            
       WindowManager.LayoutParams params = getWindow().getAttributes();
       params.gravity = Gravity.CENTER;
       params.width = WindowManager.LayoutParams.WRAP_CONTENT;
       params.height = WindowManager.LayoutParams.WRAP_CONTENT;
       getWindow().setAttributes(params);

   }

但是坑来了,尽管我们设定了最外层布局为WRAP_CONTENT,但是它是默认白色的背景,所以我们的圆角矩形效果就失效了,借@青蛙要fly的一张图,如果设定background为黑色则效果更加直观:

image.png

解决的办法很简单,直接覆盖重写dialog style里的透明属性即可,另外,使用兼容包的dialog样式默认没有Title了,但是这里还是覆写一下:

<style name="dialog_no_title" parent="Theme.AppCompat.Dialog">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>

在构造函数中传入我们的新style(dialog提供了这个构造方法):

public LoadingDialog(Context context) {
        super(context,R.style.LoadingDialog);
        mContext=context;
    }

最后我们的自定义dialog就已经完成了,贴上完整代码:

public class LoadingDialog extends Dialog {
    private Context mContext;
    ImageView imageView;

    public LoadingDialog(Context context) {
        super(context,R.style.LoadingDialog);
        mContext=context;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initView();
    }

    private void initView() {
        setContentView(R.layout.dialog_loading_layout);
        imageView = (ImageView) findViewById(R.id.loading_view);
        AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable();
        animationDrawable.start();


        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        getWindow().setAttributes(params);

    }

    @Override
    public void dismiss() {
        super.dismiss();
    }
}

四、封装构建Dialog管理类

为了效率和复用性,我们使用单例模式封装一个线程安全的DialogManger类:

public class DialogManager {

    private static DialogManager mInstnce = null;
    private ProgressDialog mDialog;

    public static DialogManager getInstnce() {

        if (mInstnce == null) {
            //线程安全模式
            synchronized (DialogManager.class) {
                if (mInstnce == null) {
                    mInstnce = new DialogManager();
                }
            }
        }
        return mInstnce;
    }

    public void showProgressDialog(Context context) {

        if (mDialog == null) {
            mDialog = new ProgressDialog(context);
            //设置点击dialog外部,不会自动退出dialog
            mDialog.setCanceledOnTouchOutside(false);
        }
        mDialog.show();
    }

    public void dismissProgressDialog() {

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

这样,我们就可以一句话调出和取消读取界面了:

            //显示
        DialogManager.getInstnce().showProgressDialog(this);
         //取消显示
        DialogManager.getInstnce().dismissProgressDialog();

五、总结

其实整个过程非常简单,就是理解window类,然后自定义一个dialog,然后在dialog中启动帧动画,有些老生常谈的坑需要注意罢了。再来看一眼我们萌萌的loading动画吧:


yicha3.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容