国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Snackbar源碼分析

why_rookie / 1931人閱讀

摘要:分別對應于中的幾個常量值。源碼分析的方法源碼分析創建需要使用靜態的方法,并且其中的參數是一個查找父布局的起點這里可以看到,的布局是,假如我們需要自定義并且設置字體顏色,大小等屬性。表示回調已在隊列中。

目錄介紹

1.最簡單創造方法

1.1 Snackbar作用

1.2 最簡單的創建

1.3 Snackbar消失的幾種方式

2.源碼分析

2.1 Snackbar的make方法源碼分析

2.2 對Snackbar屬性進行設置

2.3 Snackbar的show顯示與點擊消失

2.4 顯示和隱藏中動畫源碼分析

3.經典總結

3.1 Snackbar和SnackbarManager類的設計

4.思考問題分析

4.1 Snackbar的設計思路

4.2 什么時候Snackbar顯示會導致FloatingActionButton上移

4.3 Snackbar控件show時為何從下往上移出來

4.4 為什么Snackbar總是顯示在最下面

4.5 Snackbar與吐司有何區別

5.Snackbar封裝庫

好消息

博客筆記大匯總【16年3月到至今】,包括Java基礎及深入知識點,Android技術博客,Python學習筆記等等,還包括平時開發中遇到的bug匯總,當然也在工作之余收集了大量的面試題,長期更新維護并且修正,持續完善……開源的文件是markdown格式的!同時也開源了生活博客,從12年起,積累共計47篇[近20萬字],轉載請注明出處,謝謝!

鏈接地址:https://github.com/yangchong2...

如果覺得好,可以star一下,謝謝!當然也歡迎提出建議,萬事起于忽微,量變引起質變!

Snackbar封裝庫項目地址:https://github.com/yangchong2...

02.Toast源碼深度分析

最簡單的創建,簡單改造避免重復創建,show()方法源碼分析,scheduleTimeoutLocked吐司如何自動銷毀的,TN類中的消息機制是如何執行的,普通應用的Toast顯示數量是有限制的,用代碼解釋為何Activity銷毀后Toast仍會顯示,Toast偶爾報錯Unable to add window是如何產生的,Toast運行在子線程問題,Toast如何添加系統窗口的權限等等

03.DialogFragment源碼分析

最簡單的使用方法,onCreate(@Nullable Bundle savedInstanceState)源碼分析,重點分析彈窗展示和銷毀源碼,使用中show()方法遇到的IllegalStateException分析

05.PopupWindow源碼分析

顯示PopupWindow,注意問題寬和高屬性,showAsDropDown()源碼,dismiss()源碼分析,PopupWindow和Dialog有什么區別?為何彈窗點擊一下就dismiss呢?

06.Snackbar源碼分析

最簡單的創建,Snackbar的make方法源碼分析,Snackbar的show顯示與點擊消失源碼分析,顯示和隱藏中動畫源碼分析,Snackbar的設計思路,為什么Snackbar總是顯示在最下面

07.彈窗常見問題

DialogFragment使用中show()方法遇到的IllegalStateException,什么常見產生的?Toast偶爾報錯Unable to add window,Toast運行在子線程導致崩潰如何解決?

1.最簡單創造方法 1.1 Snackbar作用

Snackbar是Android支持庫中用于顯示簡單消息并且提供和用戶的一個簡單操作的一種彈出式提醒。當使用Snackbar時,提示會出現在消息最底部,通常含有一段信息和一個可點擊的按鈕。

同樣作為消息提示,Snackbar相比于Toast而言,增加了一個用戶操作,并且在同時彈出多個消息時,Snackbar會停止前一個,直接顯示后一個,也就是說同一時刻只會有一個Snackbar在顯示;而Toast則不然,如果不做特殊處理,那么同時可以有多個Toast出現;Snackbar相比于Dialog,操作更少,因為只有一個用戶操作的接口,而Dialog最多可以設置三個,另外Snackbar的出現并不影響用戶的繼續操作,而Dialog則必須需要用戶做出響應,所以相比Dialog,Snackbar更輕量。

1.2 最簡單的創建

如下所示

Snackbar sb = Snackbar.make(v,"瀟湘劍雨",Snackbar.LENGTH_LONG)
        .setAction("刪除嗎?", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //點擊了"是嗎?"字符串操作
                ToastUtils.showRoundRectToast("逗比");
            }
        })
        .setActionTextColor(Color.RED)
        .setText("楊充是個逗比")
        .addCallback(new BaseTransientBottomBar.BaseCallback() {
            @Override
            public void onDismissed(Snackbar transientBottomBar, int event) {
                super.onDismissed(transientBottomBar, event);
                switch (event) {
                    case Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE:
                    case Snackbar.Callback.DISMISS_EVENT_MANUAL:
                    case Snackbar.Callback.DISMISS_EVENT_SWIPE:
                    case Snackbar.Callback.DISMISS_EVENT_TIMEOUT:
                        ToastUtils.showRoundRectToast("刪除成功");
                        break;
                    case Snackbar.Callback.DISMISS_EVENT_ACTION:
                        ToastUtils.showRoundRectToast("撤銷了刪除操作");
                        break;
                }
                Log.d("MainActivity","onDismissed");
            }
            @Override
            public void onShown(Snackbar transientBottomBar) {
                super.onShown(transientBottomBar);
                Log.d("MainActivity","onShown");
            }
        });
sb.show();
1.3 Snackbar消失的幾種方式

Snackbar顯示只有一種方式,那就是調用show()方法,但是消失有幾種方式:時間到了自動消失、點擊了右側按鈕消失、新的Snackbar出現導致舊的Snackbar消失、滑動消失或者通過調用dismiss()消失。

分別對應于Snackbar.Callback中的幾個常量值。

DISMISS_EVENT_ACTION:點擊了右側按鈕導致消失

DISMISS_EVENT_CONSECUTIVE:新的Snackbar出現導致舊的消失

DISMISS_EVENT_MANUAL:調用了dismiss方法導致消失

DISMISS_EVENT_SWIPE:滑動導致消失

DISMISS_EVENT_TIMEOUT:設置的顯示時間到了導致消失

Callback有兩個方法

void onDismissed(B transientBottomBar, @DismissEvent int event)

void onShown(B transientBottomBar)

其中onShown在Snackbar可見時調用,onDismissed在Snackbar準備消失時調用。

2.源碼分析 2.1 Snackbar的make方法源碼分析

創建Snackbar需要使用靜態的make方法,并且其中的view參數是一個查找父布局的起點

這里可以看到,snackBar的布局是design_layout_snackbar_include,假如我們需要自定義SnackBar并且設置字體顏色,大小等屬性。則需要拿到這個布局的控件id等。關于封裝庫,可以查看:https://github.com/yangchong2...

其中findSuitableParent()方法為以view為起點尋找合適的父布局,下面看看findSuitableParent()如何做的?

看了下面源碼可知:可以看到如果view是CoordinatorLayout,那么就直接作為父布局了;如果是FrameLayout,并且如果是android.R.id.content,也就是查找到了DecorView,即最頂部,那么就只用這個view;如果不是的話,先保存下來;接下來就是獲取view的父布局,然后循環再次判斷。這樣導致的結果最終會有兩個選擇,要么是CoordinatorLayout,要么就是FrameLayout,并且是最頂層的那個布局。

如果從View往上搜尋,如果有CoordinatorLayout,那么就使用該CoordinatorLayout ;如果從View往上搜尋,沒有CoordinatorLayout,那么就使用android.R.id.content的FrameLayout

2.2 對Snackbar屬性進行設置

2.2.1 setActionTextColor設置action顏色

可以看到先是獲取父布局contentLayout,然后在獲取snackbar_action的mActionView

@NonNull
public Snackbar setActionTextColor(@ColorInt int color) {
    final SnackbarContentLayout contentLayout = (SnackbarContentLayout) mView.getChildAt(0);
    final TextView tv = contentLayout.getActionView();
    tv.setTextColor(color);
    return this;
}

//然后看SnackbarContentLayout類中getActionView方法
@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    mMessageView = (TextView) findViewById(R.id.snackbar_text);
    mActionView = (Button) findViewById(R.id.snackbar_action);
}
public Button getActionView() {
    return mActionView;
}

2.2.2 看setAction()方法的實現

首先是獲取父布局contentLayout,然后通過contentLayout調用getActionView()方法,返回的tv其實就是右邊的Button,然后判斷文本和監聽器,設置可見性、文本、監聽器。

@NonNull
public Snackbar setAction(CharSequence text, final View.OnClickListener listener) {
    final SnackbarContentLayout contentLayout = (SnackbarContentLayout) mView.getChildAt(0);
    final TextView tv = contentLayout.getActionView();

    if (TextUtils.isEmpty(text) || listener == null) {
        tv.setVisibility(View.GONE);
        tv.setOnClickListener(null);
    } else {
        tv.setVisibility(View.VISIBLE);
        tv.setText(text);
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                listener.onClick(view);
                // Now dismiss the Snackbar
                dispatchDismiss(BaseCallback.DISMISS_EVENT_ACTION);
            }
        });
    }
    return this;
}

2.3 Snackbar的show顯示與點擊消失

2.3.1 show顯示

可以看到,首先獲取一個SnackbarManager對象,然后調用它的show方法。可以看到在這個方法中,先判斷如果是當前正在顯示的SnackBar對應的CallBack,則更新顯示時長,然后從消息隊列中移除,最后調用scheduleTimeoutLocked方法發送定時消息dismiss;如果是下一個要顯示的,則更新顯示時長;如果都不是,那么就創建一個SnackbarRecord對象。

isCurrentSnackbarLocked:如果當前已經有一個Snackbar顯示了,又再調用了該對象的show方法,但是只是設置了不同時間,那么isCurrentSnackbarLocked就會是true,執行里面的方法。

isNextSnackbarLocked:如果當前已有一個Snackbar正在顯示,又創建了一個新的Snackbar并調用show方法,則執行這個條件代碼

如果兩條件都不成立,則需要創建一個新記錄并對其進行排隊。

public void show() {
    SnackbarManager.getInstance().show(mDuration, mManagerCallback);
}

public void show(int duration, Callback callback) {
    synchronized (mLock) {
        if (isCurrentSnackbarLocked(callback)) {
            // 表示回調已在隊列中。我們只需更新持續時間
            mCurrentSnackbar.duration = duration;

            // 如果這是當前正在顯示的Snackbar,請調用重新調度它的
            // timeout
            mHandler.removeCallbacksAndMessages(mCurrentSnackbar);
            // 這個方法很重要,當執行時間結束后,就會自動dismiss。下面再詳細分析
            scheduleTimeoutLocked(mCurrentSnackbar);
            return;
        } else if (isNextSnackbarLocked(callback)) {
            //我們只需更新持續時間
            mNextSnackbar.duration = duration;
        } else {
            //否則,我們需要創建一個新記錄并對其進行排隊。
            mNextSnackbar = new SnackbarRecord(duration, callback);
        }
        if (mCurrentSnackbar != null && cancelSnackbarLocked(mCurrentSnackbar,Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE)) {
            // 如果我們目前有一個Snackbar,請嘗試取消它并排隊等待。
            return;
        } else {
            // 清除當前的快捷鍵
            mCurrentSnackbar = null;
            //很重要
            showNextSnackbarLocked();
        }
    }
}

//注意這個callback方法
final SnackbarManager.Callback mManagerCallback = new SnackbarManager.Callback() {
    @Override
    public void show() {
        sHandler.sendMessage(sHandler.obtainMessage(MSG_SHOW, BaseTransientBottomBar.this));
    }

    @Override
    public void dismiss(int event) {
        sHandler.sendMessage(sHandler.obtainMessage(MSG_DISMISS, event, 0,
                BaseTransientBottomBar.this));
    }
};

//處理sHandler發送的消息
static {
    sHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            switch (message.what) {
                case MSG_SHOW:
                    ((BaseTransientBottomBar) message.obj).showView();
                    return true;
                case MSG_DISMISS:
                    ((BaseTransientBottomBar) message.obj).hideView(message.arg1);
                    return true;
            }
            return false;
        }
    });
}

然后看看showNextSnackbarLocked這個方法,注意:mCurrentSnackbar當前正在顯示的,而mNextSnackbar是下一個要顯示的。能看到會調用callback的show方法,而這個calllback對象就是我們在調用snackbar的show方法是傳進去的那個。向Snackbar的Handler發送一個消息,最后顯示Snackbar。

private void showNextSnackbarLocked() {
    if (mNextSnackbar != null) {
        mCurrentSnackbar = mNextSnackbar;
        mNextSnackbar = null;

        final Callback callback = mCurrentSnackbar.callback.get();
        if (callback != null) {
            callback.show();
        } else {
            // The callback doesn"t exist any more, clear out the Snackbar
            mCurrentSnackbar = null;
        }
    }
}

2.3.2 看看scheduleTimeoutLocked源碼如何銷毀snackBar

可以發現,如果我們設置為無限期,則不會設置超時,直接return函數。然后發送了一個叫做MSG_TIMEOUT的消息,繼續追終,最后會到達cancelSnackbarLocked方法。在cancelSnackbarLocked這個方法中,首先移除SnackbarRecord發出的所有消息,然后調用Callback的dismiss方法,從上面我們知道最終是向Snackbar的sHandler發送了一條消息,最終是調用Snackbar的hideView消失。

private void scheduleTimeoutLocked(SnackbarRecord r) {
    if (r.duration == Snackbar.LENGTH_INDEFINITE) {
        // If we"re set to indefinite, we don"t want to set a timeout
        return;
    }

    int durationMs = LONG_DURATION_MS;
    if (r.duration > 0) {
        durationMs = r.duration;
    } else if (r.duration == Snackbar.LENGTH_SHORT) {
        durationMs = SHORT_DURATION_MS;
    }
    mHandler.removeCallbacksAndMessages(r);
    mHandler.sendMessageDelayed(Message.obtain(mHandler, MSG_TIMEOUT, r), durationMs);
}

//接受mHandler消息并且處理
mHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
    @Override
    public boolean handleMessage(Message message) {
        switch (message.what) {
            case MSG_TIMEOUT:
                handleTimeout((SnackbarRecord) message.obj);
                return true;
        }
        return false;
    }
});

//
void handleTimeout(SnackbarRecord record) {
    synchronized (mLock) {
        if (mCurrentSnackbar == record || mNextSnackbar == record) {
            cancelSnackbarLocked(record, Snackbar.Callback.DISMISS_EVENT_TIMEOUT);
        }
    }
}

//最終可以追蹤到這個方法
private boolean cancelSnackbarLocked(SnackbarRecord record, int event) {
    final Callback callback = record.callback.get();
    if (callback != null) {
        // Make sure we remove any timeouts for the SnackbarRecord
        mHandler.removeCallbacksAndMessages(record);
        callback.dismiss(event);
        return true;
    }
    return false;
}

2.4 顯示和隱藏中動畫源碼分析

在顯示的時候是這樣設置動畫的,具體如下所示

在隱藏的時候是這樣設置動畫的,具體如下所示

最后具體看一下animateViewOut部分源碼

可以看到在動畫結束的最后都調用了onViewHidden方法,所以最終都是要調用onViewHidden方法的。

private void animateViewOut(final int event) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        ViewCompat.animate(mView)
                .translationY(mView.getHeight())
                .setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
                .setDuration(ANIMATION_DURATION)
                .setListener(new ViewPropertyAnimatorListenerAdapter() {
                    @Override
                    public void onAnimationStart(View view) {
                        mContentViewCallback.animateContentOut(0, ANIMATION_FADE_DURATION);
                    }

                    @Override
                    public void onAnimationEnd(View view) {
                        onViewHidden(event);
                    }
                }).start();
    } else {
        Animation anim = AnimationUtils.loadAnimation(mView.getContext(),
                R.anim.design_snackbar_out);
        anim.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
        anim.setDuration(ANIMATION_DURATION);
        anim.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationEnd(Animation animation) {
                onViewHidden(event);
            }

            @Override
            public void onAnimationStart(Animation animation) {}

            @Override
            public void onAnimationRepeat(Animation animation) {}
        });
        mView.startAnimation(anim);
    }
}

onViewHidden提供具體的業務處理,具體如下所示

首先調用SnackbarManager的onDismissed方法,然后判斷Snackbar.Callback是不是null,調用Snackbar.Callback的onDismissed方法,就是我們上面介紹的處理Snackbar消失的方法。最后就是將Snackbar的mView移除。

3.經典總結 3.1 Snackbar和SnackbarManager類的設計

Snackbar和SnackbarManager,SnackbarManager內部有兩個SnackbarRecord,一個mCurrentSnackbar,一個mNextSnackbar,SnackbarManager通過這兩個對象實現Snackbar的順序顯示,如果在一個Snackbar顯示之前有Snackbar正在顯示,那么使用mNextSnackbar保存第二個Snackbar,然后讓第一個Snackbar消失,然后消失之后再調用SnackbarManager顯示下一個Snackbar,如此循環,實現了Snackbar的順序顯示。

Snackbar負責顯示和消失,具體來說其實就是添加和移除View的過程。Snackbar和SnackbarManager的設計很巧妙,利用一個SnackbarRecord對象保存Snackbar的顯示時間以及SnackbarManager.Callback對象,前面說到每一個Snackbar都有一個叫做mManagerCallback的SnackbarManager.Callback對象,下面看一下SnackRecord類的定義:

Snackbar向SnackbarManager發送消息主要是調用SnackbarManager.getInstace()返回一個單例對象;而SnackManager向Snackbar發送消息就是通過show方法傳入的Callback對象。SnackbarManager中的Handler只處理一個MSG_TIMEOUT事件,最后是調用Snackbar的hideView消失的;Snackbar的sHandler處理兩個消息,showView和hideView,而消息的發送者是mManagerCallback,控制者是SnackbarManager。

4.思考問題分析 4.1 Snackbar的設計思路

具體可以看經典總結3.1

4.2 什么時候Snackbar顯示會導致FloatingActionButton上移

為什么CoordinatorLayout + FloatingActionButton,當Snackbar顯示的時候FloatingActionButton會上移呢,這個是怎么實現的?

把CoordinatorLayout替換成FrameLayout確不行。這個問題我們還沒說。其實這個不是在Snackbar里面處理的,是通過CoordinatorLayout和Behavior來處理的。那具體的處理在哪里呢。FloatingActionButton類里面Behavior類。正是Behavior里面的兩個函數layoutDependsOn()和onDependentViewChanged()函數作用的結果。直接進去看下FloatingActionButton內部類Behavior里面這兩個函數的代碼。

4.3 Snackbar控件show時為何從下往上移出來

至于說Snackbar控件show時為何從下往上移出來,看下面這段代碼就知道呢,如下所示

4.4 為什么Snackbar總是顯示在最下面

直接找到make方法中的填充布局,然后去看design_layout_snackbar_include的布局參數,結果如下:

4.5 Snackbar與吐司有何區別

與Toast進行比較,SnackBar有優勢:

1.SnackBar可以自動消失,也可以手動取消(側滑取消,但是需要在特殊的布局中,后面會仔細說)

2.SnackBar可以通過setAction()來與用戶進行交互

3.通過CallBack我們可以獲取SnackBar的狀態

5.Snackbar封裝庫

可以一行代碼調用,也可以自己使用鏈式編程調用。支持設置顯示時長屬性;可以設置背景色;可以設置文字大小,顏色;可以設置action內容,文字大小,顏色,還有點擊事件;可以設置icon;代碼如下所示,更多內容可以直接運行demo哦!

//1.只設置text
SnackBarUtils.showSnackBar(this,"滾犢子");

//2.設置text,action,和點擊事件
SnackBarUtils.showSnackBar(this, "滾犢子", "ACTION", new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ToastUtils.showRoundRectToast("滾犢子啦?");
    }
});

//3.設置text,action,和點擊事件,和icon
SnackBarUtils.showSnackBar(this, "滾犢子", "ACTION",R.drawable.icon_cancel, new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ToastUtils.showRoundRectToast("滾犢子啦?");
    }
});

//4.鏈式調用
SnackBarUtils.builder()
    .setBackgroundColor(this.getResources().getColor(R.color.color_7f000000))
    .setTextSize(14)
    .setTextColor(this.getResources().getColor(R.color.white))
    .setTextTypefaceStyle(Typeface.BOLD)
    .setText("滾犢子")
    .setMaxLines(4)
    .centerText()
    .setActionText("收到")
    .setActionTextColor(this.getResources().getColor(R.color.color_f25057))
    .setActionTextSize(16)
    .setActionTextTypefaceStyle(Typeface.BOLD)
    .setActionClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ToastUtils.showRoundRectToast("滾犢子啦?");
        }
    })
    .setIcon(R.drawable.icon_cancel)
    .setActivity(MainActivity.this)
    .setDuration(SnackBarUtils.DurationType.LENGTH_INDEFINITE)
    .build()
    .show();

關于其他內容介紹 01.關于博客匯總鏈接

1.技術博客匯總

2.開源項目匯總

3.生活博客匯總

4.喜馬拉雅音頻匯總

5.其他匯總

02.關于我的博客

我的個人站點:www.yczbj.org,www.ycbjie.cn

github:https://github.com/yangchong211

知乎:https://www.zhihu.com/people/...

簡書:http://www.jianshu.com/u/b7b2...

csdn:http://my.csdn.net/m0_37700275

喜馬拉雅聽書:http://www.ximalaya.com/zhubo...

開源中國:https://my.oschina.net/zbj161...

泡在網上的日子:http://www.jcodecraeer.com/me...

郵箱:yangchong211@163.com

阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV

segmentfault頭條:https://segmentfault.com/u/xi...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/71687.html

相關文章

  • Android之Window和彈窗問題

    摘要:指向的主要是實現和通信的。子不能單獨存在,需附屬特定的父。系統需申明權限才能創建。和類似,同樣是通過來實現。將添加到中顯示。方法完成的顯示。執行的檢查參數等設置檢查將保存到中將保存到中。因為通過和的將無法獲取到從而導致失敗。 目錄介紹 10.0.0.1 Window是什么?如何通過WindowManager添加Window(代碼實現)?WindowManager的主要功能是什么? 1...

    Lorry_Lu 評論0 收藏0
  • Activity、Window、View三者關系

    摘要:在代碼中的直接應用是或者是。就像一個控制器,統籌視圖的添加與顯示,以及通過其他回調方法,來與以及進行交互。創建需要通過創建,通過將加載其中,并將交給,進行視圖繪制以及其他交互。創建機制分析實例的創建中執行,從而生成了的實例。 目錄介紹 01.Window,View,子Window 02.什么是Activity 03.什么是Window 04.什么是DecorView 05.什么是Vi...

    Cristic 評論0 收藏0
  • Flutter Toast的使用,安卓開發知識點

    摘要:創建一個創建遵循準則的應用程序時,請為您的應用程序提供一致的外觀結構。例如,如果用戶不小心刪除了一條消息,則他們可以在中使用可選的動作來恢復該消息。來自第三方庫的依賴,是一個來自第三方庫的給用戶彈出提示的實現,它覆蓋了安卓,,及等平臺。 來自Material Design的官方Toast,Snackbars在執...

    番茄西紅柿 評論0 收藏2637
  • [Android] Toast問題深度剖析(二)

    摘要:所以,從體驗上考慮,這個情況并不屬于問題。一般情況下,這個節點占據了除了通知欄的所有區域。通知給對象的消息,都會被這個內部對象進行處理通過執行處理消息在通知給對象顯示的時候,對象將給對象發送一條消息,并在的函數中執行。 歡迎大家前往云+社區,獲取更多騰訊海量技術實踐干貨哦~ 作者:QQ音樂技術團隊 題記 Toast 作為 Android 系統中最常用的類之一,由于其方便的api設計和...

    cloud 評論0 收藏0
  • Android Material Design系列之FloatingActionButton和Sna

    摘要:今天主講的系列的兩個控件都不難,所以一起講了,分別是和。之所以出現這么久了,不太火,不太常用,估計跟他懸浮有關,容易擋住其他內容。那我們現在就研究改如何在滑動列表時隱藏和顯示這個懸浮按鈕。其實也非常簡單,和修改樣式的過程差不多。 今天主講的Material Design系列的兩個控件都不難,所以一起講了,分別是FloatingActionButton和Snackbar。這個系列都是主講...

    iKcamp 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<