美文网首页Android知识Android开发经验谈Android技术知识
Android文字垂直滚动、纵向走马灯的几种实现方式

Android文字垂直滚动、纵向走马灯的几种实现方式

作者: RubinZuo | 来源:发表于2017-12-25 11:10 被阅读0次
    screen_shot.gif

    方法一、使用系统控件ViewFlipper方式:

    布局文件:

    <ViewFlipper
            android:id="@+id/view_flipper"
            android:layout_width="300dp"
            android:layout_height="35dp"
            android:layout_centerInParent="true"
            android:autoStart="true"
            android:background="@drawable/warning_bg"
            android:flipInterval="3000"
            android:inAnimation="@anim/slide_in_bottom"
            android:outAnimation="@anim/slide_out_top">
    
            <TextView
                android:id="@+id/tv_warning_content1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:ellipsize="middle"
                android:gravity="center"
                android:singleLine="true"
                android:text="有预警信息有预警信息有预警信息"
                android:textColor="#000000"
                android:textSize="16sp"/>
    
            <TextView
                android:id="@+id/tv_warning_content2"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:ellipsize="middle"
                android:gravity="center"
                android:singleLine="true"
                android:text="当前天气状况当前天气状况当前"
                android:textColor="#000000"
                android:textSize="16sp"/>
    
            <TextView
                android:id="@+id/tv_warning_content3"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:ellipsize="middle"
                android:gravity="center"
                android:singleLine="true"
                android:text="123456465"
                android:textColor="#000000"
                android:textSize="16sp"/>
        </ViewFlipper>
    

    背景文件:warning_bg.xml

    <?xml version="1.0" encoding="utf-8"?>
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
           android:shape="rectangle">
    
        <solid android:color="#34000000"/>
        <corners android:radius="80dp"/>
    
    </shape>
    

    切入动画:slide_in_bottom.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    
        <translate
            android:duration="1000"
            android:fromYDelta="100%p"
            android:toYDelta="0" />
    </set>
    

    切出动画:slide_out_top.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    
        <translate
            android:duration="1000"
            android:fromYDelta="0"
            android:toYDelta="-100%p" />
    
    </set>
    

    注意:如果不在布局文件里设置: android:autoStart="true", 可以在代码中动态设置开始循环mViewFlipper.startFlipping();
    在Activity中显示正常,但在fragment中可能会有重影的现象。

    方法二、使用三方框架

    Gradle:

    compile 'com.sunfusheng:marqueeview:1.3.3'
    

    属性

    Attribute 属性 Description 描述
    mvAnimDuration 一行文字动画执行时间
    mvInterval 两行文字翻页时间间隔
    mvTextSize 文字大小
    mvTextColor 文字颜色
    mvGravity 文字位置:left、center、right
    mvSingleLine 单行设置
    mvDirection 动画滚动方向:bottom_to_top、top_to_bottom、right_to_left、left_to_right

    XML

    <com.sunfusheng.marqueeview.MarqueeView
        android:id="@+id/marqueeView"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        app:mvAnimDuration="1000"
        app:mvDirection="bottom_to_top"
        app:mvInterval="3000"
        app:mvTextColor="@color/white"
        app:mvTextSize="14sp"
        app:mvSingleLine="true"/>
    

    设置字符串列表数据

    MarqueeView marqueeView = (MarqueeView) findViewById(R.id.marqueeView);
    
    List<String> info = new ArrayList<>();
    info.add("11111111111111");
    info.add("22222222222222");
    info.add("33333333333333");
    info.add("44444444444444");
    info.add("55555555555555");
    info.add("66666666666666");
    marqueeView.startWithList(info);
    
    // 在代码里设置自己的动画
    marqueeView.startWithList(info, R.anim.anim_bottom_in, R.anim.anim_top_out);
    

    设置字符串数据

    String notice = "心中有阳光,脚底有力量!心中有阳光,脚底有力量!心中有阳光,脚底有力量!";
    marqueeView.startWithText(notice);
    
    // 在代码里设置自己的动画
    marqueeView.startWithText(notice, R.anim.anim_bottom_in, R.anim.anim_top_out);
    

    设置事件监听

    marqueeView.setOnItemClickListener(new MarqueeView.OnItemClickListener() {
        @Override
        public void onItemClick(int position, TextView textView) {
            Toast.makeText(getApplicationContext(), String.valueOf(marqueeView1.getPosition()) + ". " + textView.getText(), Toast.LENGTH_SHORT).show();
        }
    });
    

    重影问题可参考以下解决方案

    @Override
    public void onStart() {
        super.onStart(); 
        marqueeView.startFlipping();
    }
    
    @Override
    public void onStop() {
        super.onStop();
        marqueeView.stopFlipping();
    }
    

    注意:这个库主要还是继承了ViewFlipper,类似的库还有MarqueeViewLibrary,实现方法基本类似,在Activity中显示正常,但在fragment中可能会有重影的现象。

    方法三、使用系统控件TextSwitcher实现

    布局文件

    <TextSwitcher
                android:id="@+id/text_switcher"
                android:layout_width="285dp"
                android:layout_height="35dp"
                android:background="@drawable/warning_bg"/>
    

    背景文件:warning_bg.xml

    <?xml version="1.0" encoding="utf-8"?>
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
           android:shape="rectangle">
    
        <solid android:color="#34000000"/>
        <corners android:radius="80dp"/>
    
    </shape>
    

    代码:

       private int index = 0;//textview上下滚动下标
        private Handler handler = new Handler();
        private boolean isFlipping = false; // 是否启用预警信息轮播
        private List<String> mWarningTextList = new ArrayList<>();
    
        private void setTextSwitcher() {
            mTextSwitcher.setInAnimation(AnimationUtils.loadAnimation(mContext, R.anim.slide_in_bottom));
            mTextSwitcher.setOutAnimation(AnimationUtils.loadAnimation(mContext, R.anim.slide_out_top));
            mTextSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
                @Override
                public View makeView() {
                    TextView textView = new TextView(mContext);
                    textView.setSingleLine();
                    textView.setTextSize(12);//字号
                    textView.setTextColor(Color.parseColor("#ffffff"));
                    textView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
                    textView.setSingleLine();
                    textView.setGravity(Gravity.CENTER);
                    FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                    params.gravity = Gravity.CENTER;
                    textView.setLayoutParams(params);
                    textView.setPadding(25, 0, 25, 0);
                    return textView;
                }
            });
        }
        
            private Runnable runnable = new Runnable() {
            @Override
            public void run() {
                if (!isFlipping) {
                    return;
                }
                index++;
                mTextSwitcher.setText(mWarningTextList.get(index % mWarningTextList.size()));
                if (index == mWarningTextList.size()) {
                    index = 0;
                }
                startFlipping();
            }
        };
    
        //开启信息轮播
        public void startFlipping() {
            if (mWarningTextList.size() > 1) {
                handler.removeCallbacks(runnable);
                isFlipping = true;
                handler.postDelayed(runnable, 3000);
            }
        }
    
        //关闭信息轮播
        public void stopFlipping() {
            if (mWarningTextList.size() > 1) {
                isFlipping = false;
                handler.removeCallbacks(runnable);
            }
        }
        
        //设置数据
        private void setData() {
            if (mWarningTextList.size() == 1) {
                mTextSwitcher.setText(mWarningTextList.get(0));
                index = 0;
            }
            if (mWarningTextList.size() > 1) {
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mTextSwitcher.setText(mWarningTextList.get(0));
                        index = 0;
                    }
                }, 1000);
                mTextSwitcher.setInAnimation(AnimationUtils.loadAnimation(mContext, R.anim.slide_in_bottom));
                mTextSwitcher.setOutAnimation(AnimationUtils.loadAnimation(mContext, R.anim.slide_out_top));
                startFlipping();
            }
        }
        
           @Override
        public void onResume() {
            super.onResume();
           startFlipping();
        }
    
        @Override
        public void onStop() {
            super.onStop();
            stopFlipping();
        }
    

    切入动画:slide_in_bottom.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    
        <translate
            android:duration="1000"
            android:fromYDelta="100%p"
            android:toYDelta="0" />
    </set>
    

    切出动画:slide_out_top.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    
        <translate
            android:duration="1000"
            android:fromYDelta="0"
            android:toYDelta="-100%p" />
    
    </set>
    

    注意:这种方法在Activity和Fragment中均使用正常,可以解决Android文字垂直滚动、纵向走马灯在Fragment中重叠的现象。

    相关文章

      网友评论

        本文标题:Android文字垂直滚动、纵向走马灯的几种实现方式

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