• Android垂直跑马灯


    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);
        }
    }
     

  • 相关阅读:
    数商云:订单积压达 930 亿欧元,西门子如何通过供应链数字化转型缩短交货期
    opencv的极线几何
    【Java集合】HashMap系列(四)——HashMap在JDK1.7和JDK1.8中的并发问题的分析以及如何保证并发安全
    4.3 Pollard‘s rho algorithm
    【openKylin】OpenKylin1.0 x86_64 VMWare安装手册
    网工内推 | 国企、上市公司,IA/IP认证即可,有年终、绩效
    2022年面试复盘大全500道:Redis+ZK+Nginx+数据库+分布式+微服务
    pycharm pro v2023.2.4(Python开发)
    Failure [DELETE_FAILED_INTERNAL_ERROR]的解决办法
    JVM垃圾收集器--分代收集器
  • 原文地址:https://blog.csdn.net/chezabo6116/article/details/126389403