ScrollView计时器循环滚动

来源:互联网 发布:ios 扑克牌效果源码 编辑:程序博客网 时间:2024/05/19 17:57

这里写图片描述

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