ScrollView计时器循环滚动

这里写图片描述

MainActivity中代码如下,我都做了相关的注释,很清晰

package com.safly.myapplication;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.graphics.Color;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.app.WindowDecorActionBar;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.OvershootInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    ImageView dele_update_tip;
    Button atOnceUpdate;
    ScrollView mScrollView;
    LinearLayout mScrollViewLL;
    RelativeLayout update_container;

    TextView updateView;
    float updateContainerH;
    int updateTextScrollH;
    int perH;
    List<String> updateInfos;
    int measuredHeight;
    int height;
    private Handler mHandler = new Handler();
    private MyRun myRun = new MyRun();

    /**
     * 这里进行视图滚动的设置操作
     * 方法是:动画结束1秒后开始滚动
     * 然后100毫秒重复一次,每次位移是1dp
     *当scrollview屏幕内可显示的高度+位移高度<=总高度时候就一直循环移动移动
     * 相反呢就回归原位继续循环滚动视图文本
     */
  class MyRun implements Runnable{
        @Override
        public void run() {
            Log.i("MainActivity","---updateTextScrollH---"+updateTextScrollH+",height---"+height+",measuredHeight--"+measuredHeight);
            updateTextScrollH = updateTextScrollH + perH;

            if (updateTextScrollH + height<=measuredHeight){

                mScrollView.scrollTo(0,updateTextScrollH);
                mHandler.postDelayed(myRun, 100);
            }else{
                mScrollView.scrollTo(0,0);
                mHandler.removeCallbacks(myRun);
                updateTextScrollH = 0;
                if (height> measuredHeight){
                    return;
                }
                mHandler.postDelayed(myRun, 100);
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initRes();
        initUpdateInfo();
        mesure();
        addScrollViewUpdateInfos();
        initUpdateContainerAni();

        /**
         *这里也需要进行操作
         *donw时:去掉myrun然后定位到移动到的位置
         *move:获取当时的位置,移动到即可
         * up:更新位置 开始循环滚动视图
         *
         */
        mScrollView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:

                        mHandler.removeCallbacks(myRun);
                        mScrollView.scrollTo(0,updateTextScrollH);
                        Log.i(TAG,"-----ACTION_DOWN updateTextScrollH-----"+updateTextScrollH);
                        break;
                    case MotionEvent.ACTION_MOVE:

//                        int moveY = (int) event.getY();
//                        mScrollView.scrollTo(0,moveY);

                        break;
                    case MotionEvent.ACTION_UP:
                        float scaleY = mScrollView.getScrollY();
                        updateTextScrollH = (int) scaleY;
                        Log.i(TAG,"-----ACTION_UP updateTextScrollH-----"+updateTextScrollH);
                        mHandler.postDelayed(myRun,1000);
                        break;
                }
                return false;
            }
        });


    }

    /**
     * 获取控件资源
     */
    private void initRes() {
        dele_update_tip = (ImageView) findViewById(R.id.dele_update_tip);
        dele_update_tip.setOnClickListener(this);
        atOnceUpdate = (Button) findViewById(R.id.update);
        atOnceUpdate.setOnClickListener(this);
        mScrollView = (ScrollView) findViewById(R.id.mScrollView);
        mScrollViewLL = (LinearLayout) findViewById(R.id.mScrollView_LL);
        update_container = (RelativeLayout) findViewById(R.id.update_container);
    }

    /**
     * 为ScrollView中的addView操作,随机添加5条textView文本数据
     */
    private void initUpdateInfo() {
        updateInfos = new ArrayList<>();
        for (int i =0;i<5;i++){
            updateInfos.add((i+1)+"--"+MeasureUtil.getRandomString((int)(1+Math.random()*(10-1+1))));
        }
    }

    /**
     * 初始化视图从屏幕外弹出来,测量高度,高度直接就从xml写死了,当然可以通过代码进行获取控件高度
     * 可以通过addOnGlobalLayoutListener、post(run)、onWindowFocusChanged
     */
    private void mesure() {
        updateContainerH = DisplayUtil.dip2px(this, 230);
        perH = DisplayUtil.dip2px(this, 1f);
    }

    /**
     * 为scrollview添加数据addView
     */
    private void addScrollViewUpdateInfos() {
        if (mScrollView !=null ){
            View view0 = mScrollView.getChildAt(0);
            if (view0 instanceof LinearLayout){
                mScrollViewLL = (LinearLayout) view0;
                for (int i = 0;i<updateInfos.size();i++){
                    updateView = null;
                    updateView = new TextView(this);
                    updateView.setText(updateInfos.get(i));
                    updateView.setTextColor(Color.parseColor("#8E8E8E"));
                    mScrollViewLL.addView(updateView);
                }
            }
        }
    }

    /**
     * 利用ValueAnimator动画,在addUpdateListener中设置插值器
     * 当动画结束后,1秒后开始滚动scrollView里面的视图文本
     * 然后循环滚动即可
     *
     * 这里获取了2个值
     * measuredHeight:mscrollview的全部高度
     * height:屏幕能看见的scrollview高度
     */
    private void initUpdateContainerAni() {
        ValueAnimator updateContainerAni  =  ValueAnimator.ofFloat(-updateContainerH,0);
        updateContainerAni.setInterpolator(new BounceInterpolator());
        updateContainerAni.setTarget(update_container);
        updateContainerAni.setDuration(1500).start();
        updateContainerAni.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                update_container.setTranslationY((Float) animation.getAnimatedValue());
            }
        });

        updateContainerAni.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                measuredHeight = mScrollViewLL.getMeasuredHeight();
                height = mScrollView.getHeight();
                Log.i("MainActivity","height--"+height+",measuredHeight--"+measuredHeight);
                mScrollView.scrollTo(0,0);
                mHandler.postDelayed(myRun,1000);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
    }




    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.dele_update_tip:
                finish();
                break;
            case R.id.update:
                Toast.makeText(MainActivity.this,"update",Toast.LENGTH_LONG).show();
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacks(myRun);
        mHandler = null;
    }
}

然后是布局文件

<?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"
    android:background="#4B0082"
    tools:context="com.safly.myapplication.MainActivity">

    <RelativeLayout
        android:id="@+id/update_container"
        android:layout_width="300dp"
        android:layout_height="230dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true">
        <ImageView
            android:id="@+id/dele_update_tip"
            android:layout_alignParentRight="true"
            android:padding="12dp"
            android:src="@mipmap/x"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <ImageView
                android:background="@mipmap/show"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <TextView
                android:id="@+id/x_update"
                android:typeface="normal"
                android:layout_marginLeft="96dp"
                android:textSize="18dp"
                android:textStyle="bold"
                android:layout_marginTop="50dp"
                android:textColor="#458B74"
                android:text="X分身更新了"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <TextView
                android:textColor="#8E8E8E"
                android:id="@+id/text_update"
                android:layout_alignLeft="@id/x_update"
                android:layout_below="@id/x_update"
                android:text="更新内容:"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
            <ScrollView
                android:id="@+id/mScrollView"
                android:scrollbars="none"
                android:layout_alignLeft="@id/text_update"
                android:layout_below="@id/text_update"
                android:layout_centerHorizontal="true"
                android:layout_width="100dp"
                android:layout_height="60dp">

                <LinearLayout
                    android:id="@+id/mScrollView_LL"
                    android:orientation="vertical"
                    android:layout_width="100dp"
                    android:layout_height="60dp">

                </LinearLayout>
            </ScrollView>
        </RelativeLayout>

        <Button
            android:id="@+id/update"
            android:textStyle="bold"
            android:textColor="#ffffff"
            android:textSize="20dp"
            android:text="立即更新"
            android:layout_marginLeft="84dp"
            android:layout_alignParentBottom="true"
            android:background="@mipmap/update"
            android:layout_width="wrap_content"
            android:layout_height="40dp" />
    </RelativeLayout>

</RelativeLayout>

最后2个工具类
DisplayUtil

package com.safly.myapplication;

import android.content.Context;

public final class DisplayUtil {

    /**
     * 将px值转换为dip或dp值,保证尺寸大小不变
     *
     * @param pxValue
     * @param context
     *            (DisplayMetrics类中属性density)
     * @return
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * 将dip或dp值转换为px值,保证尺寸大小不变
     *
     * @param dipValue
     * @param context
     *            (DisplayMetrics类中属性density)
     * @return
     */
    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    /**
     * 将px值转换为sp值,保证文字大小不变
     *
     * @param pxValue
     * @param context
     *            (DisplayMetrics类中属性scaledDensity)
     * @return
     */
    public static int px2sp(Context context, float pxValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / fontScale + 0.5f);
    }

    /**
     * 将sp值转换为px值,保证文字大小不变
     *
     * @param spValue
     * @param context
     *            (DisplayMetrics类中属性scaledDensity)
     * @return
     */
    public static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }
}

MeasureUtil

package com.safly.myapplication;

    import android.app.Activity;  
    import android.util.DisplayMetrics;

    import java.util.Random;

/**
     * 测绘工具类 
     */  
    public final class MeasureUtil {  
        /** 
         * 获取屏幕尺寸 
         *  
         * @param activity 
         *            Activity 
         * @return 屏幕尺寸像素值,下标为0的值为宽,下标为1的值为高 
         */  
        public static int[] getScreenSize(Activity activity) {  
            DisplayMetrics metrics = new DisplayMetrics();  
            activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);  
            return new int[] { metrics.widthPixels, metrics.heightPixels };  
        }


        public static String getRandomString(int length) { //length表示生成字符串的长度
            String base = "abcdefghijklmnopqrstuvwxyz0123456789";
            Random random = new Random();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < length; i++) {
                int number = random.nextInt(base.length());
                sb.append(base.charAt(number));
            }
            return sb.toString();
        }
    }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值