美文网首页
使用Android属性动画-ObjectAnimator实现跑马

使用Android属性动画-ObjectAnimator实现跑马

作者: jdallen | 来源:发表于2020-04-21 15:42 被阅读0次

0、背景:

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

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

1、效果图预览:

QQ图片20200828170802.gif

2、activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <HorizontalScrollView
        android:id="@+id/layout_announce_open_time"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_margin="20dp"
        android:background="#000000"
        android:scrollbars="none">

        <TextView
            android:id="@+id/tv_announce_open_time"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:singleLine="true"
            android:textColor="#F7EBBD"
            android:textSize="20sp"
            android:textStyle="bold"
            tools:text="我是加工高" />
    </HorizontalScrollView>
</LinearLayout>

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实现跑马

      本文链接:https://www.haomeiwen.com/subject/nvouihtx.html