0、背景:
解决【通过设置TextView的以下属性来实现跑马灯效果,但当文字不满一行时,文字不移动】的问题
android:ellipsize="marquee" //跑马灯效果
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
1、效果图预览:
![](https://img.haomeiwen.com/i4923945/f0bedb0967c5d289.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();
}
网友评论