Android自定義滑動Toast

以前作過的一個項目中要實現這樣的效果:從屏幕的上端向下滑入一個帶色的文字提示框,停留幾秒以後再滑出屏幕以外。當時我並無想到去用第三方庫,本身摸索着作出來了。個人作法很簡單,就是在界面的最上方放置一個TextView,而後給它設置滑出和滑入的動畫。下圖就是完成的效果:java

SlidingToast

看起來仍是能夠的。寫法並不高明,但當時確實知足了個人需求,也讓我在解決問題的過程當中獲得了鍛鍊。如今就來介紹一下個人作法吧。android

一、建立項目

新建一個名爲SlidingToast的項目,再新建一個SlidingToastActivity。項目建立完成以後,先來建立SlidingToast提示框的佈局:
sliding_toast.xmlgit

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:gravity="center"
    android:paddingTop="5dp"
    android:paddingBottom="5dp"
    android:textColor="@android:color/white"
    android:background="@android:color/holo_blue_light"
    android:textSize="18sp"
    android:id="@+id/tv_toast"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:visibility="gone"
    android:orientation="vertical">
</TextView>

我須要的只是一個簡單的TextView,你能夠根據本身的須要建立改成複雜的佈局,好比添加圖片等等。跟Toast同樣,提示框通常狀況下是不會顯示,也不會佔用佈局空間的。因此android:visibility屬性設爲gone。github

寫好SlidingToast的佈局以後,咱們就能夠到Activity的佈局中使用了。但有一點務必要記住:SlidingToast不能被任何控件蓋住,它必須覆蓋在全部控件的上方。我採用的根佈局是RelativeLayout,因此在佈局文件中SlidingToast必須放置在最底層:segmentfault

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.lindroid.slidingtoast.SlidingToastActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:onClick="showSlidingToast"
        android:text="顯示SlidingToast"
        android:textAllCaps="false" />

    <include layout="@layout/sliding_toast" />
</RelativeLayout>

若是你的根佈局是LinearLayout的話,我建議是在外面再包裹一層FrameLayout,使SlidingToast可以位於LinearLayout之上。佈局的嵌套會影響性能,但這也是沒辦法的事。ide

二、實現動畫效果

SlidingToast的動畫分爲兩個步驟,第一步是先從根佈局上方滑入,第二步是向上滑出根佈局。這兩步均可以用補間動畫中的位移動畫來實現,代碼很簡單:佈局

public class SlidingToastActivity extends AppCompatActivity {
    private TextView tvToast;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sliding_toast);
        tvToast = (TextView) findViewById(R.id.tv_toast);
    }

    public void showSlidingToast(View view) {
        tvToast.setVisibility(View.VISIBLE);
        //設置SlidingToast的信息
        tvToast.setText("這是一條提示信息");

        //建立動畫集合
        AnimationSet animationSet = new AnimationSet(true);
        //滑入的動畫
        TranslateAnimation inAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, -1, Animation.RELATIVE_TO_SELF, 0);
        inAnimation.setDuration(500);
        inAnimation.setFillAfter(true);
        //將該滑入的位移動畫添加到動畫集合
        animationSet.addAnimation(inAnimation);

        //滑出的動畫
        TranslateAnimation outAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, -1);
        outAnimation.setDuration(500);
        outAnimation.setFillAfter(true);
        //設置動畫的啓動時間,滑出動畫在滑入動畫的2秒後執行
        outAnimation.setStartOffset(2000);
        //將該滑出的位移動畫添加到動畫集合
        animationSet.addAnimation(outAnimation);
        //開啓動畫
        tvToast.startAnimation(animationSet);
        //動畫監聽事件,動畫完成以後從新讓SlidingToast消失
        animationSet.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                tvToast.setVisibility(View.GONE);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }
}

只要具有補間動畫的知識,上面的代碼是很容易理解。咱們分別設置滑入和滑出兩個位移動畫,二者的持續時間相等,但方向相反,並且執行順序也有前後之分。咱們能夠建立一個動畫集合AnimationSet對象,而後按照執行順序將動畫添加到集合中,再調用setStartOffset方法讓滑出動畫在滑入動畫執行完畢後的2秒啓動。性能

動畫執行完成,SlidingToast會停留在界面上,這顯示不是咱們想要的,因此給動畫設置一個監聽事件,在動畫結束以後讓SlidingToast消失。學習

三、後記

可能有些朋友已經忍不住吐槽了:「直接用第三方庫Crouton不就好了嗎?還整這麼麻煩?」這……只能怪我孤陋寡聞,當時並不知道有Crouton這個庫。不過有時候本身動手實現一下仍是有所收穫的,至少對於我來講,現階段積累點代碼量仍是頗有必要的。接下來,我也會去嘗試一下Crouton,寫一篇學習筆記。動畫

源碼下載:
SlidingToast

相關文章
相關標籤/搜索