直播弹幕滑动的view

本文介绍如何在直播项目中创建一个随手指滑动的弹幕视图。通过在页面上覆盖一个view,并利用onTouchEvent处理触摸事件,计算滑动距离来实现清屏效果。提供相关XML布局代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们在做直播项目的时候,进入到直播页面时候,在这个页面会有一个随手指活动的页面,而这些聊天弹幕就是出现在这个页面上的,其实他是在上面覆盖一个viwe,让后让他随手值滑动而实现清屏的操作,这里就用到了onTouchEvent的触摸事件,计算滑动的距离,下面就简单的介绍一下:

直接上代码,注释很全就不一一讲解了,

主布局:

public class MainActivity extends Activity {


    private RelativeLayout rl_left;
    private int rlWidth;// 布局的宽度
    private static final int MAX_OFFSET = 5;// 5个像素误差,滑动小于5个像素就没有动画
    private float downX;// 按下时的点
    private float viewXdown;// 按下时View的位置
    private boolean lastSlidePull = false;// 最后一次滑动的方向
    private float maxOffset = 0;// 最大的滑动距离


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initLeftView();//初始化控件
}


    //获取屏幕宽高
    private int getScreenSize() {
        int width;
        DisplayMetrics metric = new DisplayMetrics();//DisplayMetircs 类可以很方便的获取分辨率
        getWindowManager().getDefaultDisplay().getMetrics(metric);//将当前窗口的一些信息放在DisplayMetrics类中
        width = metric.widthPixels;   // 屏幕宽度(像素)
        return width;
    }


    private void initLeftView() {
        rl_left = (RelativeLayout) findViewById(R.id.rl_left);
        rlWidth = getScreenSize();
        rl_left.setX(-rlWidth);// 将rl_left的位置移动到手机屏幕左外
    }


    /**
     * 使用ValueAnimator将rl_left以动画的形式弹入到界面
     */
    private void slideToShow() {
        float startX = rl_left.getX();
        ValueAnimator valueAnimator = ValueAnimator.ofInt((int) startX, 0);
        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {


            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int offset = (Integer) animation.getAnimatedValue();
                rl_left.setX(offset);
            }
        });
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        float fraction = Math.abs(startX / rlWidth);
        valueAnimator.setDuration((long) (600 * fraction));
        valueAnimator.start();
    }


    /**
     * 使用ValueAnimator将rl_left以动画的形式弹出去
     */
    private void slideToHide() {
        float startX = rl_left.getX();
        ValueAnimator valueAnimator = ValueAnimator.ofInt((int) startX,
                -rlWidth);
        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {


            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int offset = (Integer) animation.getAnimatedValue();
                rl_left.setX(offset);
            }
        });
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        float fraction = Math.abs((rlWidth + startX) / rlWidth);
        valueAnimator.setDuration((long) (400 * fraction));
        valueAnimator.start();
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                this.downX = x;
                this.viewXdown = rl_left.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                float offset = (event.getX() - downX);// 滑动距离
                float posX = viewXdown + offset;// 计算可能的位置
                maxOffset = maxOffset > Math.abs(offset) ? maxOffset : Math
                        .abs(offset);
                if (offset > 0) {// pull to show
                    rl_left.setX(posX < 0 ? posX : 0);
                    if (posX >= 0) {// 防止不跟手,更新downX的值
                        this.downX += posX;
                    }
                    lastSlidePull = true;
                } else {// push to hide
//                    rl_left.setX(posX > -rlWidth ? posX : -rlWidth);
                    if (posX <= -rlWidth) {// 防止不跟手,更新downX的值
                        this.downX += (posX + rlWidth);
                    }
                    lastSlidePull = false;
                }
                break;
            case MotionEvent.ACTION_UP:
                if (maxOffset < MAX_OFFSET) {// 防止抖动
                    return super.onTouchEvent(event);
                }
                // 使用动画滑动到指定位置
                if (lastSlidePull) {
                    slideToShow();
                } else {
                    slideToHide();
                }
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
}

xml布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:background="@mipmap/ic_launcher"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <RelativeLayout
        android:id="@+id/rl_left"
        android:layout_width="match_parent"
        android:layout_height="match_parent"


        >
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="nihao"
            android:textSize="30dp"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="30dp"
            android:text="弹幕"/>
    </RelativeLayout>>
</RelativeLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值