以前作过的一个项目中要实现这样的效果:从屏幕的上端向下滑入一个带色的文字提示框,停留几秒以后再滑出屏幕以外。当时我并无想到去用第三方库,本身摸索着作出来了。个人作法很简单,就是在界面的最上方放置一个TextView,而后给它设置滑出和滑入的动画。下图就是完成的效果:java
看起来仍是能够的。写法并不高明,但当时确实知足了个人需求,也让我在解决问题的过程当中获得了锻炼。如今就来介绍一下个人作法吧。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