先上效果图,有兴趣的可以读下去,本来这个控件都不算自定义控件,技术含量很低,但一开始自己找这类效果时,也是找了好久不见有此类文章,特写下来备忘一下。
主要技术点如下:
1.使用LinearLayout做为弹幕的容器,放置好界面大小后,只需要特别指定gravity为bottom
2.使用代码指定一个LayoutTransition到界面上放置的LinearLayout
3.自定义LayoutTransition中各种事件关联的动画对象
4.进行子控件的add和remove,就可以看到动画进入与退出的效果了。
关键代码:
/**
* 自定义动画效果
*/
private void setTransition() {
/**
* view出现时 view自身的动画效果
*/
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 0f, 1f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 0f, 1f);
PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 0f, 1f);
ObjectAnimator multAnim = ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY, pvhZ) //使用此种方法,可定义多属性同时修改的动画
.setDuration(mTransitioner.getDuration(LayoutTransition.APPEARING));
multAnim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
View view = (View) ((ObjectAnimator) animation).getTarget(); //使用动画监听器,主要是为了处理缩放的中心点修改到自己想要的位置
view.setPivotX(0f);
view.setPivotY(view.getHeight());
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
mTransitioner.setAnimator(LayoutTransition.APPEARING, multAnim);
/**
* view 消失时,view自身的动画效果
*/
pvhX = PropertyValuesHolder.ofFloat("alpha", 1f, 0f);
pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f, 0f);
pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f, 0f);
multAnim = ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY, pvhZ)
.setDuration(mTransitioner.getDuration(LayoutTransition.DISAPPEARING));
multAnim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
View view = (View) ((ObjectAnimator) animation).getTarget();
view.setPivotX(0f);
view.setPivotY(0f);
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, multAnim);
/**
* view出现时,导致整个布局改变的动画
*/
/**
* view消失,导致整个布局改变时的动画
*/
}
动态增加聊天汽泡:
/**
* 发送弹幕内容到界面上
* @param inputStr
*/
private void addContentToDanmaku(String inputStr) {
View inputView = createDanmakuView(inputStr); //创建弹幕的背景及内容
LinearLayout.LayoutParams inputLP = createDanmakuLP(); //自定义每一条弹幕的margin值
danmakuContainer.addView(inputView,inputLP);
inputView.postDelayed(autoRemoveSelf(inputView),5000); //5秒后自动删除自己这条弹幕
}
private View createDanmakuView(String inputStr) {
TextView textView = new TextView(this);
textView.setText(inputStr);
textView.setTextColor(getResources().getColor(R.color.black));
textView.setTextSize(getDip(10));
textView.setBackgroundResource(getBgResId());
textView.setCompoundDrawables(getHeadDrawable(),null,null,null);
return textView;
}