公司项目新加需求,可以对扣分情况进行实时展示,就像某大型滤镜美颜直播间那种垂直展示聊天弹幕一样,在网上找了好多大佬的实现方法,发现我们的需求只是简单的展示,就选了一个最简单的方式实现 链接地址
但是发现这兄弟把代码都堆在了Activity里面,我的直播界面代码已经够多了,防止Activity代码太乱,就继承了一下LinearLayout,只对外提供目前需要的几个方法
- 继承之后的代码
/**
* @author: OlderJiao
* @date: 2020/12/18
* @ClassName: yjz_student_android
*/
public class MyDanmuView extends LinearLayout {
private LayoutTransition transition;
//最大展示数量 默认四条
private int maxItem = 4;
public MyDanmuView(Context context) {
super(context);
}
public MyDanmuView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyDanmuView);
maxItem = typedArray.getInteger(R.styleable.MyDanmuView_maxItem, maxItem);
typedArray.recycle();
init();
}
public MyDanmuView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void init() {
transition = new LayoutTransition();
//创建属性动画
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(null, "alpha", 0, 1);
//动画监听
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
//动画结束
if (getChildCount() == maxItem + 1) {
handler.sendEmptyMessage(2);
}
}
@Override
public void onAnimationRepeat(Animator animation) {
super.onAnimationRepeat(animation);
}
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
//动画开始
if (getChildCount() == maxItem) {
handler.sendEmptyMessage(1);
}
}
});
//设置layout动画属性
transition.setAnimator(LayoutTransition.APPEARING, objectAnimator);
//删除的动画效果
PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0, 0);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(null, new PropertyValuesHolder[]{alpha}).setDuration(transition.getDuration(LayoutTransition.DISAPPEARING));
transition.setAnimator(LayoutTransition.DISAPPEARING, animator);
setLayoutTransition(transition);
}
/**
* 设置最大展示数量
*
* @param maxItem
*/
public void setMaxItem(int maxItem) {
this.maxItem = maxItem;
}
public void setData(String name, String cause) {
View view = getTextView();
//获取学生姓名
TextView nameTxt = view.findViewById(R.id.studentNameTxt);
//扣分原因
TextView causeTxt = view.findViewById(R.id.causeTxt);
//设置学生姓名
nameTxt.setText(TextUtils.isEmpty(name) ? "佚名" : name);
//扣分原因
causeTxt.setText(TextUtils.isEmpty(cause) ? "无" : cause);
//添加子布局
addView(view);
}
/**
* 获取子控件布局
*
* @return View
*/
private View getTextView() {
return LayoutInflater.from(getContext()).inflate(R.layout.item_live_danmu, null);
}
/**
* 回收
*/
public void destory() {
if (handler != null) {
handler.removeCallbacksAndMessages(null);
handler = null;
}
if (transition != null) {
if (!transition.isRunning()) {
transition = null;
}
}
}
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
//给展示的第一个view增加渐变透明动画
getChildAt(0).animate().alpha(0).setDuration(transition.getDuration(LayoutTransition.APPEARING)).start();
break;
case 2:
//删除顶部view
removeViewAt(0);
break;
}
}
};
}
布局文件可以自己去定义,其中关于ObjectAnimator和PropertyValuesHolder的使用看一下这篇文章,这里就不赘述了,还有另外用到的一个动画 PropertyValuesHolder
- 自定义属性代码
<declare-styleable name="MyDanmuView">
<attr name="maxItem" format="integer" />
</declare-styleable>
使用的时候,布局里面直接引用就好了
最后,让我们共同开发,共同进步。谢谢!!!