1.只能在父控件内做动画的解决方案
1).直接改布局,适用于简单的布局,relativelayout很容易做到父控件为全屏
2).如果有用到三方控件,改他东西很麻烦的话可以尝试用framelayout,因为它可以共享点击事件
3).如果要全屏跑又不是很多布局又很麻烦的话,比如要遮掉baseactivity或者basefragment的一些东西,可以用下面的方法:
public ImageView setAnimation(View iv, Animation anim) {
int[] location = new int[2];
iv.getLocationOnScreen(location);// 获取在整个屏幕内的绝对坐标
ImageView tView = new ImageView(this);
tView.setScaleType(ScaleType.FIT_XY);
tView.setImageBitmap(ImageReflect.loadBitmapFromView(iv));
LayoutParams lp = new LayoutParams(iv.getWidth(), iv.getHeight());
lp.gravity = Gravity.LEFT | Gravity.TOP;
lp.setMargins(location[0], location[1], 0, 0);
tView.setLayoutParams(lp);
rootView.addView(tView);
tView.startAnimation(anim);
return tView;
}
public static Bitmap loadBitmapFromView(View v) {
if (v == null || v.getWidth() <= 0) {
return null;
}
Bitmap screenshot;
screenshot = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(screenshot);
v.draw(c);
return screenshot;
}
用listview做动画会卡,因为如果有10个条目,listview至少会调20次getview,gridview会更多,所以推荐使用recycleview
recycleview做动画一般有两种一种是设置recycleview的ItemAnimator,一种是直接在adapter里写动画
1)adapter设动画
因为我们的项目是数据预加载的viewpager,所以对一些不需要刷新的数据在可见时只需要走下动画展示给用户所以单独写了animatorIn,而需要刷新的就直接写在onBindViewHolder里:
@Override
public void onBindViewHolder(ViewHolder holder, final int i) {
holderMap.put(i, holder.itemView);
holder.itemView.setTranslationY(0);
holder.itemView.setAlpha(0);
if (inAnimation != null) {
HzCommonMethod.startAnimators(holder.itemView, inAnimation, (i + 1) * 35 * (getItemCount() > 6 ? 1 : 2), i == 0 ? endListener
: (endListener = null));
}
/**
* 只走遍进入动画,不更新数据
*
* @param endListener
*/
public void animatorIn(AnimatorListenerAdapter endListener) {
for (int i = 0; i < mDataset.size(); i++) {
View itemView = holderMap.get(i).itemView;
if(itemView.getTranslationY()!=0){
itemView.setTranslationY(0);
itemView.setAlpha(0);
}
int delay = i<5?80*i:40*(2*(i-5)+1);
HzCommonMethod.startInAnimators(itemView, -58, 160, 6, 280, 240, delay, i==0?endListener:null);
}
}
</pre>主要用了一个map来保存viewholder里需要做动画的item,方便下次使用,然后再onbindviewholder里实时更新这个view,下面是退出的动画</div><div style="top:0px"><pre name="code" class="java"> public void animatorOut(AnimatorListenerAdapter endListener) {
for (int i = mDataset.size()-1; i >= 0; i--) {
View itemView = holderMap.get(i).itemView;
HzCommonMethod.startOutAnimators(itemView, -5, 120, 317, 200, getDelay(i), i==0?endListener:null);
}
}
这种方式更复杂一些,基本思路是在add,change,remove时设置不同的动画显示,然后又对频繁动画做了一些处理,可以继承
https://github.com/wasabeef/recyclerview-animators 这个项目来实现。
这个是我fork了这个项目然后对我们项目中用到的分页加载方式做的一些实现
https://github.com/yuxia5454/recyclerview-animators
3)两种方式的对比:
adapter方式更简单一些,可自定义的东西也更方便。itemAnimator方式可以在有动态的添加删除某个item时有更炫的效果,实现方式比较复杂,但继承github那个项目也还好,具体看需求
3.动画时点击过快处理
一般用户不会再展示动画未完成时就乱点,但测试会。。。而且用户无意间点卡也不好,所以最好做下限制,方法是在BaseActivity里重定义事件分发规则,当动画未完成时,直接返回true
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (HzContants.isAnimating == true) {
return true;
}