使用Android属性动画-ObjectAnimator实现跑马灯效果(水平方向)

0、背景:

解决【通过设置TextView的以下属性来实现跑马灯效果,但当文字不满一行时,文字不移动】的问题

android:ellipsize="marquee"  //跑马灯效果
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"

1、效果图预览:

使用Android属性动画-ObjectAnimator实现跑马灯效果(水平方向)_第1张图片
QQ图片20200828170802.gif

2、activity_main.xml




    

        
    

3、MainActivity.java

public class MainActivity extends AppCompatActivity {
    private HorizontalScrollView layout_announce_open_time;
    private TextView tv_announce_open_time;
    //
    private final static int MAX_TIME_SEC = 15;//最长时间(走完内容的时间,单位为秒)
    private final static int MIN_TIME_SEC = 5;//最短时间(走完内容的时间,单位为秒)

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //
        initView();
        initData();
        initEvent();
    }

    @Override
    public void onResume() {
        super.onResume();
        showNotification();
    }

    @Override
    public void onStop() {
        super.onStop();
        hideNotification();
    }

    private void initView() {
        layout_announce_open_time = findViewById(R.id.layout_announce_open_time);
        tv_announce_open_time = findViewById(R.id.tv_announce_open_time);
    }

    private void initData() {
        tv_announce_open_time.setText("这里填充文字");
        showNotification();
    }

    private void initEvent() {
        //禁止触摸事件以此来禁止HorizontalScrollView响应左右滑动
        layout_announce_open_time.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View arg0, MotionEvent arg1) {
                Log.e("ATU", "HorizontalScrollView-onTouch");
                //不能滑动
                return true;
                //可以滑动
                //return false;
            }
        });
    }

    //通知
    private ObjectAnimator announce_open_timeAnimator;

    private void showNotification() {
        tv_announce_open_time.setVisibility(View.VISIBLE);
        if (null == announce_open_timeAnimator || !announce_open_timeAnimator.isRunning()) {
            tv_announce_open_time.post(new Runnable() {
                @Override
                public void run() {
                    int contentWidth = tv_announce_open_time.getWidth();//由于这里需要获取宽度,并且在onResume获取,故需要使用post
                    float bgWidth = layout_announce_open_time.getWidth();//这是背景的宽度
                    long totalTime = (long) (contentWidth / bgWidth * MAX_TIME_SEC);//背景需要15秒,文字内容宽度的时间(这样子计算能不考虑到特殊字符)
                    totalTime = totalTime < MIN_TIME_SEC ? MIN_TIME_SEC * 1000 : totalTime * 1000;//小于5秒按
                    announce_open_timeAnimator = ObjectAnimator.ofFloat(tv_announce_open_time, "translationX", bgWidth, -contentWidth);//从最右边,到最左边0处,加上文字的宽度(即-文字宽度)
                    announce_open_timeAnimator.setRepeatCount(ValueAnimator.INFINITE);//无限循环
                    //announce_open_timeAnimator.setRepeatMode(ValueAnimator.REVERSE);//往返操作,这个左右来回
                    announce_open_timeAnimator.setDuration(totalTime);//5秒 15秒
                    announce_open_timeAnimator.setInterpolator(new LinearInterpolator());//插值器设置为 以一个恒定的速度变化的动画
                    announce_open_timeAnimator.start();
                }
            });
        } else {
            Log.e("ATU", "正在做动画中");
        }
    }

    private void hideNotification() {
        tv_announce_open_time.setVisibility(View.INVISIBLE);
        if (null != announce_open_timeAnimator) {
            announce_open_timeAnimator.cancel();
            announce_open_timeAnimator = null;
        }
    }

}
注意:在Activity或者Fragment中的onResume()和onStop()方法分别调用
 @Override
    public void onResume() {
        super.onResume();
        //
        showNotification();
    }

    @Override
    public void onStop() {
        super.onStop();
        //
        hideNotification();
    }

你可能感兴趣的:(使用Android属性动画-ObjectAnimator实现跑马灯效果(水平方向))