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閱讀 228,835評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,676評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,730評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,873評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,266評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,482評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,036評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,846評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,025評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,279評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,751評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,016評論 2 375

推薦閱讀更多精彩內容