真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Snackbar源碼分析-創(chuàng)新互聯(lián)

目錄介紹
  • 1.最簡(jiǎn)單創(chuàng)造方法
    • 1.1 Snackbar作用
    • 1.2 最簡(jiǎn)單的創(chuàng)建
    • 1.3 Snackbar消失的幾種方式
  • 2.源碼分析
    • 2.1 Snackbar的make方法源碼分析
    • 2.2 對(duì)Snackbar屬性進(jìn)行設(shè)置
    • 2.3 Snackbar的show顯示與點(diǎn)擊消失
    • 2.4 顯示和隱藏中動(dòng)畫源碼分析
  • 3.經(jīng)典總結(jié)
    • 3.1 Snackbar和SnackbarManager類的設(shè)計(jì)
  • 4.思考問(wèn)題分析
    • 4.1 Snackbar的設(shè)計(jì)思路
    • 4.2 什么時(shí)候Snackbar顯示會(huì)導(dǎo)致FloatingActionButton上移
    • 4.3 Snackbar控件show時(shí)為何從下往上移出來(lái)
    • 4.4 為什么Snackbar總是顯示在最下面
    • 4.5 Snackbar與吐司有何區(qū)別
  • 5.Snackbar封裝庫(kù)

好消息

  • 博客筆記大匯總【16年3月到至今】,包括Java基礎(chǔ)及深入知識(shí)點(diǎn),Android技術(shù)博客,Python學(xué)習(xí)筆記等等,還包括平時(shí)開發(fā)中遇到的bug匯總,當(dāng)然也在工作之余收集了大量的面試題,長(zhǎng)期更新維護(hù)并且修正,持續(xù)完善……開源的文件是markdown格式的!同時(shí)也開源了生活博客,從12年起,積累共計(jì)47篇[近20萬(wàn)字],轉(zhuǎn)載請(qǐng)注明出處,謝謝!
  • 鏈接地址:https://github.com/yangchong211/YCBlogs
  • 如果覺得好,可以star一下,謝謝!當(dāng)然也歡迎提出建議,萬(wàn)事起于忽微,量變引起質(zhì)變!
  • Snackbar封裝庫(kù)項(xiàng)目地址:https://github.com/yangchong211/YCDialog
  • 02.Toast源碼深度分析
    • 最簡(jiǎn)單的創(chuàng)建,簡(jiǎn)單改造避免重復(fù)創(chuàng)建,show()方法源碼分析,scheduleTimeoutLocked吐司如何自動(dòng)銷毀的,TN類中的消息機(jī)制是如何執(zhí)行的,普通應(yīng)用的Toast顯示數(shù)量是有限制的,用代碼解釋為何Activity銷毀后Toast仍會(huì)顯示,Toast偶爾報(bào)錯(cuò)Unable to add window是如何產(chǎn)生的,Toast運(yùn)行在子線程問(wèn)題,Toast如何添加系統(tǒng)窗口的權(quán)限等等
  • 03.DialogFragment源碼分析
    • 最簡(jiǎn)單的使用方法,onCreate(@Nullable Bundle savedInstanceState)源碼分析,重點(diǎn)分析彈窗展示和銷毀源碼,使用中show()方法遇到的IllegalStateException分析
  • 05.PopupWindow源碼分析
    • 顯示PopupWindow,注意問(wèn)題寬和高屬性,showAsDropDown()源碼,dismiss()源碼分析,PopupWindow和Dialog有什么區(qū)別?為何彈窗點(diǎn)擊一下就dismiss呢?
  • 06.Snackbar源碼分析
    • 最簡(jiǎn)單的創(chuàng)建,Snackbar的make方法源碼分析,Snackbar的show顯示與點(diǎn)擊消失源碼分析,顯示和隱藏中動(dòng)畫源碼分析,Snackbar的設(shè)計(jì)思路,為什么Snackbar總是顯示在最下面
  • 07.彈窗常見問(wèn)題
    • DialogFragment使用中show()方法遇到的IllegalStateException,什么常見產(chǎn)生的?Toast偶爾報(bào)錯(cuò)Unable to add window,Toast運(yùn)行在子線程導(dǎo)致崩潰如何解決?

1.最簡(jiǎn)單創(chuàng)造方法

1.1 Snackbar作用
  • Snackbar是Android支持庫(kù)中用于顯示簡(jiǎn)單消息并且提供和用戶的一個(gè)簡(jiǎn)單操作的一種彈出式提醒。當(dāng)使用Snackbar時(shí),提示會(huì)出現(xiàn)在消息最底部,通常含有一段信息和一個(gè)可點(diǎn)擊的按鈕。
  • 同樣作為消息提示,Snackbar相比于Toast而言,增加了一個(gè)用戶操作,并且在同時(shí)彈出多個(gè)消息時(shí),Snackbar會(huì)停止前一個(gè),直接顯示后一個(gè),也就是說(shuō)同一時(shí)刻只會(huì)有一個(gè)Snackbar在顯示;而Toast則不然,如果不做特殊處理,那么同時(shí)可以有多個(gè)Toast出現(xiàn);Snackbar相比于Dialog,操作更少,因?yàn)橹挥幸粋€(gè)用戶操作的接口,而Dialog最多可以設(shè)置三個(gè),另外Snackbar的出現(xiàn)并不影響用戶的繼續(xù)操作,而Dialog則必須需要用戶做出響應(yīng),所以相比Dialog,Snackbar更輕量。
1.2 最簡(jiǎn)單的創(chuàng)建
  • 如下所示
    Snackbar sb = Snackbar.make(v,"瀟湘劍雨",Snackbar.LENGTH_LONG)
        .setAction("刪除嗎?", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //點(diǎn)擊了"是嗎?"字符串操作
                ToastUtils.showRoundRectToast("逗比");
            }
        })
        .setActionTextColor(Color.RED)
        .setText("楊充是個(gè)逗比")
        .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顯示只有一種方式,那就是調(diào)用show()方法,但是消失有幾種方式:時(shí)間到了自動(dòng)消失、點(diǎn)擊了右側(cè)按鈕消失、新的Snackbar出現(xiàn)導(dǎo)致舊的Snackbar消失、滑動(dòng)消失或者通過(guò)調(diào)用dismiss()消失。
    • 分別對(duì)應(yīng)于Snackbar.Callback中的幾個(gè)常量值。
      • DISMISS_EVENT_ACTION:點(diǎn)擊了右側(cè)按鈕導(dǎo)致消失
      • DISMISS_EVENT_CONSECUTIVE:新的Snackbar出現(xiàn)導(dǎo)致舊的消失
      • DISMISS_EVENT_MANUAL:調(diào)用了dismiss方法導(dǎo)致消失
      • DISMISS_EVENT_SWIPE:滑動(dòng)導(dǎo)致消失
      • DISMISS_EVENT_TIMEOUT:設(shè)置的顯示時(shí)間到了導(dǎo)致消失
    • Callback有兩個(gè)方法
      • void onDismissed(B transientBottomBar, @DismissEvent int event)
      • void onShown(B transientBottomBar)
      • 其中onShown在Snackbar可見時(shí)調(diào)用,onDismissed在Snackbar準(zhǔn)備消失時(shí)調(diào)用。

2.源碼分析

2.1 Snackbar的make方法源碼分析
  • 創(chuàng)建Snackbar需要使用靜態(tài)的make方法,并且其中的view參數(shù)是一個(gè)查找父布局的起點(diǎn)
    • 這里可以看到,snackBar的布局是design_layout_snackbar_include,假如我們需要自定義SnackBar并且設(shè)置字體顏色,大小等屬性。則需要拿到這個(gè)布局的控件id等。關(guān)于封裝庫(kù),可以查看:https://github.com/yangchong211/YCDialog
    • Snackbar源碼分析
  • 其中findSuitableParent()方法為以view為起點(diǎn)尋找合適的父布局,下面看看findSuitableParent()如何做的?
    • 看了下面源碼可知:可以看到如果view是CoordinatorLayout,那么就直接作為父布局了;如果是FrameLayout,并且如果是android.R.id.content,也就是查找到了DecorView,即最頂部,那么就只用這個(gè)view;如果不是的話,先保存下來(lái);接下來(lái)就是獲取view的父布局,然后循環(huán)再次判斷。這樣導(dǎo)致的結(jié)果最終會(huì)有兩個(gè)選擇,要么是CoordinatorLayout,要么就是FrameLayout,并且是最頂層的那個(gè)布局。
    • 如果從View往上搜尋,如果有CoordinatorLayout,那么就使用該CoordinatorLayout ;如果從View往上搜尋,沒有CoordinatorLayout,那么就使用android.R.id.content的FrameLayout
    • Snackbar源碼分析
2.2 對(duì)Snackbar屬性進(jìn)行設(shè)置
  • 2.2.1 setActionTextColor設(shè)置action顏色

    我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、太湖ssl等。為1000多家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的太湖網(wǎng)站制作公司
    • 可以看到先是獲取父布局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類中g(shù)etActionView方法@Override
    br/>@Override
    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()方法的實(shí)現(xiàn)

    • 首先是獲取父布局contentLayout,然后通過(guò)contentLayout調(diào)用getActionView()方法,返回的tv其實(shí)就是右邊的Button,然后判斷文本和監(jiān)聽器,設(shè)置可見性、文本、監(jiān)聽器。

      @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顯示與點(diǎn)擊消失
  • 2.3.1 show顯示

    • 可以看到,首先獲取一個(gè)SnackbarManager對(duì)象,然后調(diào)用它的show方法??梢钥吹皆谶@個(gè)方法中,先判斷如果是當(dāng)前正在顯示的SnackBar對(duì)應(yīng)的CallBack,則更新顯示時(shí)長(zhǎng),然后從消息隊(duì)列中移除,最后調(diào)用scheduleTimeoutLocked方法發(fā)送定時(shí)消息dismiss;如果是下一個(gè)要顯示的,則更新顯示時(shí)長(zhǎng);如果都不是,那么就創(chuàng)建一個(gè)SnackbarRecord對(duì)象。
    • isCurrentSnackbarLocked:如果當(dāng)前已經(jīng)有一個(gè)Snackbar顯示了,又再調(diào)用了該對(duì)象的show方法,但是只是設(shè)置了不同時(shí)間,那么isCurrentSnackbarLocked就會(huì)是true,執(zhí)行里面的方法。
    • isNextSnackbarLocked:如果當(dāng)前已有一個(gè)Snackbar正在顯示,又創(chuàng)建了一個(gè)新的Snackbar并調(diào)用show方法,則執(zhí)行這個(gè)條件代碼
    • 如果兩條件都不成立,則需要?jiǎng)?chuàng)建一個(gè)新記錄并對(duì)其進(jìn)行排隊(duì)。
      public void show() {
      SnackbarManager.getInstance().show(mDuration, mManagerCallback);
      }

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

     // 如果這是當(dāng)前正在顯示的Snackbar,請(qǐng)調(diào)用重新調(diào)度它的
            // timeout
            mHandler.removeCallbacksAndMessages(mCurrentSnackbar);
            // 這個(gè)方法很重要,當(dāng)執(zhí)行時(shí)間結(jié)束后,就會(huì)自動(dòng)dismiss。下面再詳細(xì)分析
            scheduleTimeoutLocked(mCurrentSnackbar);
            return;
        } else if (isNextSnackbarLocked(callback)) {
            //我們只需更新持續(xù)時(shí)間
            mNextSnackbar.duration = duration;
        } else {
            //否則,我們需要?jiǎng)?chuàng)建一個(gè)新記錄并對(duì)其進(jìn)行排隊(duì)。
            mNextSnackbar = new SnackbarRecord(duration, callback);
        }
        if (mCurrentSnackbar != null && cancelSnackbarLocked(mCurrentSnackbar,Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE)) {
            // 如果我們目前有一個(gè)Snackbar,請(qǐng)嘗試取消它并排隊(duì)等待。
            return;
        } else {
            // 清除當(dāng)前的快捷鍵
            mCurrentSnackbar = null;
            //很重要
            showNextSnackbarLocked();
        }
    }

    }

    //注意這個(gè)callback方法
    final SnackbarManager.Callback mManagerCallback = new SnackbarManager.Callback() {@Override
    br/>@Override
    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發(fā)送的消息
    static {
    sHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {@Override
    br/>@Override
    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這個(gè)方法,注意:mCurrentSnackbar當(dāng)前正在顯示的,而mNextSnackbar是下一個(gè)要顯示的。能看到會(huì)調(diào)用callback的show方法,而這個(gè)calllback對(duì)象就是我們?cè)谡{(diào)用snackbar的show方法是傳進(jìn)去的那個(gè)。向Snackbar的Handler發(fā)送一個(gè)消息,最后顯示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

    • 可以發(fā)現(xiàn),如果我們?cè)O(shè)置為無(wú)限期,則不會(huì)設(shè)置超時(shí),直接return函數(shù)。然后發(fā)送了一個(gè)叫做MSG_TIMEOUT的消息,繼續(xù)追終,最后會(huì)到達(dá)cancelSnackbarLocked方法。在cancelSnackbarLocked這個(gè)方法中,首先移除SnackbarRecord發(fā)出的所有消息,然后調(diào)用Callback的dismiss方法,從上面我們知道最終是向Snackbar的sHandler發(fā)送了一條消息,最終是調(diào)用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
    br/>@Override
    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);
    }
    }
    }

    //最終可以追蹤到這個(gè)方法
    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 顯示和隱藏中動(dòng)畫源碼分析
  • 在顯示的時(shí)候是這樣設(shè)置動(dòng)畫的,具體如下所示
    • Snackbar源碼分析
  • 在隱藏的時(shí)候是這樣設(shè)置動(dòng)畫的,具體如下所示
    • Snackbar源碼分析
  • 最后具體看一下animateViewOut部分源碼

    • 可以看到在動(dòng)畫結(jié)束的最后都調(diào)用了onViewHidden方法,所以最終都是要調(diào)用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提供具體的業(yè)務(wù)處理,具體如下所示
    • 首先調(diào)用SnackbarManager的onDismissed方法,然后判斷Snackbar.Callback是不是null,調(diào)用Snackbar.Callback的onDismissed方法,就是我們上面介紹的處理Snackbar消失的方法。最后就是將Snackbar的mView移除。
    • Snackbar源碼分析

3.經(jīng)典總結(jié)

3.1 Snackbar和SnackbarManager類的設(shè)計(jì)
  • Snackbar和SnackbarManager,SnackbarManager內(nèi)部有兩個(gè)SnackbarRecord,一個(gè)mCurrentSnackbar,一個(gè)mNextSnackbar,SnackbarManager通過(guò)這兩個(gè)對(duì)象實(shí)現(xiàn)Snackbar的順序顯示,如果在一個(gè)Snackbar顯示之前有Snackbar正在顯示,那么使用mNextSnackbar保存第二個(gè)Snackbar,然后讓第一個(gè)Snackbar消失,然后消失之后再調(diào)用SnackbarManager顯示下一個(gè)Snackbar,如此循環(huán),實(shí)現(xiàn)了Snackbar的順序顯示。
  • Snackbar負(fù)責(zé)顯示和消失,具體來(lái)說(shuō)其實(shí)就是添加和移除View的過(guò)程。Snackbar和SnackbarManager的設(shè)計(jì)很巧妙,利用一個(gè)SnackbarRecord對(duì)象保存Snackbar的顯示時(shí)間以及SnackbarManager.Callback對(duì)象,前面說(shuō)到每一個(gè)Snackbar都有一個(gè)叫做mManagerCallback的SnackbarManager.Callback對(duì)象,下面看一下SnackRecord類的定義:
    • Snackbar源碼分析
  • Snackbar向SnackbarManager發(fā)送消息主要是調(diào)用SnackbarManager.getInstace()返回一個(gè)單例對(duì)象;而SnackManager向Snackbar發(fā)送消息就是通過(guò)show方法傳入的Callback對(duì)象。SnackbarManager中的Handler只處理一個(gè)MSG_TIMEOUT事件,最后是調(diào)用Snackbar的hideView消失的;Snackbar的sHandler處理兩個(gè)消息,showView和hideView,而消息的發(fā)送者是mManagerCallback,控制者是SnackbarManager。

4.思考問(wèn)題分析

4.1 Snackbar的設(shè)計(jì)思路
  • 具體可以看經(jīng)典總結(jié)3.1
4.2 什么時(shí)候Snackbar顯示會(huì)導(dǎo)致FloatingActionButton上移
  • 為什么CoordinatorLayout + FloatingActionButton,當(dāng)Snackbar顯示的時(shí)候FloatingActionButton會(huì)上移呢,這個(gè)是怎么實(shí)現(xiàn)的?
    • 把CoordinatorLayout替換成FrameLayout確不行。這個(gè)問(wèn)題我們還沒說(shuō)。其實(shí)這個(gè)不是在Snackbar里面處理的,是通過(guò)CoordinatorLayout和Behavior來(lái)處理的。那具體的處理在哪里呢。FloatingActionButton類里面Behavior類。正是Behavior里面的兩個(gè)函數(shù)layoutDependsOn()和onDependentViewChanged()函數(shù)作用的結(jié)果。直接進(jìn)去看下FloatingActionButton內(nèi)部類Behavior里面這兩個(gè)函數(shù)的代碼。
4.3 Snackbar控件show時(shí)為何從下往上移出來(lái)
  • 至于說(shuō)Snackbar控件show時(shí)為何從下往上移出來(lái),看下面這段代碼就知道呢,如下所示
    • Snackbar源碼分析
4.4 為什么Snackbar總是顯示在最下面
  • 直接找到make方法中的填充布局,然后去看design_layout_snackbar_include的布局參數(shù),結(jié)果如下:
    • Snackbar源碼分析
4.5 Snackbar與吐司有何區(qū)別
  • 與Toast進(jìn)行比較,SnackBar有優(yōu)勢(shì):
    • 1.SnackBar可以自動(dòng)消失,也可以手動(dòng)取消(側(cè)滑取消,但是需要在特殊的布局中,后面會(huì)仔細(xì)說(shuō))
    • 2.SnackBar可以通過(guò)setAction()來(lái)與用戶進(jìn)行交互
    • 3.通過(guò)CallBack我們可以獲取SnackBar的狀態(tài)
    • Snackbar源碼分析

5.Snackbar封裝庫(kù)

  • 可以一行代碼調(diào)用,也可以自己使用鏈?zhǔn)骄幊陶{(diào)用。支持設(shè)置顯示時(shí)長(zhǎng)屬性;可以設(shè)置背景色;可以設(shè)置文字大小,顏色;可以設(shè)置action內(nèi)容,文字大小,顏色,還有點(diǎn)擊事件;可以設(shè)置icon;代碼如下所示,更多內(nèi)容可以直接運(yùn)行demo哦!

    //1.只設(shè)置text
    SnackBarUtils.showSnackBar(this,"滾犢子");
    
    //2.設(shè)置text,action,和點(diǎn)擊事件
    SnackBarUtils.showSnackBar(this, "滾犢子", "ACTION", new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ToastUtils.showRoundRectToast("滾犢子啦?");
        }
    });
    
    //3.設(shè)置text,action,和點(diǎn)擊事件,和icon
    SnackBarUtils.showSnackBar(this, "滾犢子", "ACTION",R.drawable.icon_cancel, new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ToastUtils.showRoundRectToast("滾犢子啦?");
        }
    });
    
    //4.鏈?zhǔn)秸{(diào)用
    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();

關(guān)于其他內(nèi)容介紹

01.關(guān)于博客匯總鏈接
  • 1.技術(shù)博客匯總
  • 2.開源項(xiàng)目匯總
  • 3.生活博客匯總
  • 4.喜馬拉雅音頻匯總
  • 5.其他匯總
02.關(guān)于我的博客
  • 我的個(gè)人站點(diǎn):www.yczbj.org,www.ycbjie.cn
  • github:https://github.com/yangchong211
  • 知乎:https://www.zhihu.com/people/yang-chong-69-24/pins/posts
  • 簡(jiǎn)書:http://www.jianshu.com/u/b7b2c6ed9284
  • csdn:http://my.csdn.net/m0_37700275
  • 喜馬拉雅聽書:http://www.ximalaya.com/zhubo/71989305/
  • 開源中國(guó):https://my.oschina.net/zbj1618/blog
  • 泡在網(wǎng)上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1
  • 郵箱:yangchong211@163.com
  • 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100- 239.headeruserinfo.3.dT4bcV
  • segmentfault頭條:https://segmentfault.com/u/xiangjianyu/articles

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。


新聞名稱:Snackbar源碼分析-創(chuàng)新互聯(lián)
當(dāng)前URL:http://weahome.cn/article/dichih.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部