Android自定义textview实现竖直滚动跑马灯效果
作者:m0_38091800 发布时间:2023-09-30 07:42:05
标签:Android,textview,跑马灯
本文实例为大家分享了Android自定义textview实现跑马灯效果的具体代码,供大家参考,具体内容如下
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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="myandroidstituds.test3.MainActivity">
<LinearLayout
android:layout_centerInParent="true"
android:layout_width="180dp"
android:layout_height="50dp">
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#55000000"
/>
</LinearLayout>
<myandroidstituds.test3.MarqueeLayout
android:id="@+id/mar"
android:layout_centerInParent="true"
android:layout_width="180dp"
android:layout_height="50dp">
<TextView
android:id="@+id/tv1"
android:textSize="20sp"
android:gravity="center"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#000000"
android:visibility="gone"
android:text="两个黄鹂鸣翠柳"
/>
<TextView
android:id="@+id/tv2"
android:textSize="20sp"
android:background="@android:color/transparent"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#000000"
android:visibility="gone"
android:text="一行白鹭上青天"
/>
</myandroidstituds.test3.MarqueeLayout>
</RelativeLayout>
自定义MarqueeLayout
public class MarqueeLayout extends FrameLayout implements ViewTreeObserver.OnGlobalLayoutListener{
private View view1;
private View view2;
public int interval = 2000;
public MarqueeLayout(Context context) {
this(context,null);
}
public MarqueeLayout(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public MarqueeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
getViewTreeObserver().addOnGlobalLayoutListener(this);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
if(getChildCount()!=2){
throw new IllegalArgumentException("MarqueeLayout should have 2 child!");
}
view1 = getChildAt(0);
view2 = getChildAt(1);
}
@Override
public void onGlobalLayout() {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
view2.setTranslationY(view2.getHeight());
}
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
startAnim();
}
};
boolean isAniming = false;
/**
* 开始滚动
*/
public void start(){
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
startAnim();
}
});
}
public void startAnim(){
if(isAniming)return;
isAniming = true;
int targetY1 = view1.getTranslationY()==0?-view1.getHeight():0;
int targetY2 = view2.getTranslationY()==0?-view2.getHeight():0;
ViewCompat.animate(view1)
.translationY(targetY1)
.setListener(new ViewPropertyAnimatorListenerAdapter(){
@Override
public void onAnimationEnd(View view) {
super.onAnimationEnd(view);
//移动到下方
resetView(view);
}
})
.setDuration(400).start();
ViewCompat.animate(view2)
.translationY(targetY2)
.setListener(new ViewPropertyAnimatorListenerAdapter(){
@Override
public void onAnimationEnd(View view) {
super.onAnimationEnd(view);
//移动到下方
resetView(view);
isAniming = false;
handler.sendEmptyMessageDelayed(0,interval);
}
})
.setDuration(400)
.start();
}
private void resetView(View view) {
if(view.getTranslationY()==-view.getHeight()){
view.setTranslationY(view.getHeight()*2);
}
}
public void stop(){
handler.removeCallbacksAndMessages(null);
}
}
在Activity中的使用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MarqueeLayout marqueeLayout = (MarqueeLayout) findViewById(R.id.mar);
TextView tv1 = (TextView) findViewById(R.id.tv1);
TextView tv2 = (TextView) findViewById(R.id.tv2);
marqueeLayout.start();
tv1.setVisibility(tv1.getTranslationY() == 0 ? View.VISIBLE : View.GONE);
tv2.setVisibility(tv2.getTranslationY() == 0 ? View.VISIBLE : View.GONE);
}
}


猜你喜欢
- 一、JVM 类加载机制JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程。1. 加载:加载是类
- idea乱码修改bin目录下的idea.exe.vmoptions无效今天在学习Activiti工作流的时候,发现创建bpmn文件总是出现中
- DataBindings属性是很多控件都有的属性,作用有2方面。一方面是用于与数据库的数据进行绑定,进行数据显示。另一方面用于与控件或类的对
- 代码如下所示: public static Bitmap
- 本文实例讲述了C#实现控制Windows系统关机、重启和注销的方法。分享给大家供大家参考。具体分析如下:使用.NET和C#.NET,我们可以
- 本文实例为大家分享了Java实现考试系统的具体代码,供大家参考,具体内容如下说明这里的考试系统是指由学生,老师以及考试机构成的,学生通过用户
- Spring容器中的Bean是否线程安全,容器本身并没有提供Bean的线程安全策略,因此可以说Spring容器中的Bean本身不具备线程安全
- JNI,Java Native Interface,是 native code 的编程接口。JNI 使 Java 代码程序可以与 nativ
- 题目描述:给定一 m*n 的矩阵,请按照逆时针螺旋顺序,返回矩阵中所有元素。示例:思路:这是一道典型的模拟问题:我们可以分析一下,遍历前进轨
- 最近学习了一下seata,由于nacos现在也挺火,于是学习了seata注册到nacos,然后集成springcloud1.nacos配置(
- OpenFileDialog类提供了用户打开文件的功能,它有如下属性:属性InitialDirectory:设置对话框的初始目录。Filte
- 前言在手写sql的时候,根据参数处理查询条件.select * from staff where 1 = 1 and staff_id in
- 本文实例讲述了C#中数组段用法。分享给大家供大家参考。具体分析如下:1.数组段说明① 结构ArraySegment<T>表示数组
- 多线程编程多线程编程模式.NET 中,有三种异步编程模式,分别是基于任务的异步模式(TAP)、基于事件的异步模式(EAP)、异步编程模式(A
- 以最终客户的角度来看,JAR文件就是一种封装,他们不需要知道jar文件中有多少个.class文件,每个文件中的功能与作用,同样可以得到他们希
- 提到输入参数的基本验证(非空、长度、大小、格式…),在以前我们还是通过手写代码,各种if、else、StringUtils.isEmpty、
- 在我们编程过程中如果需要执行一些简单的定时任务,无须做复杂的控制,我们可以考虑使用JDK中的Timer定时任务来实现。下面LZ就其原理、实例
- 一、表创建一、表创建//创建一个空表DataTable dt = new DataTable();//创建一个名为"Table_N
- 什么是进程?当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。而一个进程又是由多个线程所组成的。什么
- Android开发过程中,特别是新开的项目,底部状态栏的切换使用的频率非常的高,主要的实现方式有:(1)、TabLayout + Fragm