ScrollView计时器循环滚动

2024-08-31 22:58

本文主要是介绍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{@Overridepublic 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);}}}@Overrideprotected 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() {@Overridepublic 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() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {update_container.setTranslationY((Float) animation.getAnimatedValue());}});updateContainerAni.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {}@Overridepublic 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);}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}});}@Overridepublic 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;}}@Overrideprotected 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();}}  

这篇关于ScrollView计时器循环滚动的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1125233

相关文章

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

poj3750约瑟夫环,循环队列

Description 有N个小孩围成一圈,给他们从1开始依次编号,现指定从第W个开始报数,报到第S个时,该小孩出列,然后从下一个小孩开始报数,仍是报到S个出列,如此重复下去,直到所有的小孩都出列(总人数不足S个时将循环报数),求小孩出列的顺序。 Input 第一行输入小孩的人数N(N<=64) 接下来每行输入一个小孩的名字(人名不超过15个字符) 最后一行输入W,S (W < N),用

校验码:奇偶校验,CRC循环冗余校验,海明校验码

文章目录 奇偶校验码CRC循环冗余校验码海明校验码 奇偶校验码 码距:任何一种编码都由许多码字构成,任意两个码字之间最少变化的二进制位数就称为数据检验码的码距。 奇偶校验码的编码方法是:由若干位有效信息(如一个字节),再加上一个二进制位(校验位)组成校验码。 奇校验:整个校验码中1的个数为奇数 偶校验:整个校验码中1的个数为偶数 奇偶校验,可检测1位(奇数位)的错误,不可纠错。

react笔记 8-17 属性绑定 class绑定 引入图片 循环遍历

1、绑定属性 constructor(){super()this.state={name:"张三",title:'我是一个title'}}render() {return (<div><div>aaaaaaa{this.state.name}<div title={this.state.title}>我是一个title</div></div></div>)} 绑定属性直接使用花括号{}   注

Spring是如何解决循环依赖?

现象解释: 在Spring框架中,循环依赖(Circular Dependency)是指两个或多个Bean之间相互依赖,形成了一个循环。例如,Bean A依赖于Bean B,而Bean B又依赖于Bean A。Spring通过多种机制解决循环依赖问题,具体来说,主要有以下几种方式: 1.三级缓存机制 Spring容器在实例化Bean时使用了三级缓存来解决循环依赖,主要涉及三个缓存结构: 一级

FPGA开发:条件语句 × 循环语句

条件语句 if_else语句 if_else语句,用来判断是否满足所给定的条件,根据判断的结果(真或假)决定执行给出的两种操作之一。 if(表达式)语句; 例如: if(a>b) out1=int1; if(表达式)         语句1; else         语句2; 例如: if(a>b)out1=int1;elseout1=int2; if(表达式1) 语句1; els

UniApp实现漂亮的音乐歌词滚动播放效果

在现代的音乐播放应用中,歌词的展示和滚动播放已经成为了一个非常常见的功能。今天,我们将通过UniApp来实现一个漂亮的歌词滚动播放功能。我们将使用UniApp提供的组件和API来完成这个任务。 页面结构 在页面的模板部分,我们需要创建一个音频播放器和歌词展示区域。使用<scroll-view>组件来实现歌词的滚动效果。 <template><view class="audio-co

shell循环sleep while例子 条件判断

i=1# 小于5等于时候才执行while [ ${i} -le 5 ]doecho ${i}i=`expr ${i} + 1`# 休眠3秒sleep 3doneecho done 参考 http://c.biancheng.net/cpp/view/2736.html

【语音告警】博灵智能语音报警灯JavaScript循环播报场景实例-语音报警灯|声光报警器|网络信号灯

功能说明 本文将以JavaScript代码为实例,讲解如何通过JavaScript代码调用博灵语音通知终端 A4实现声光语音告警。主要博灵语音通知终端如何实现无线循环播报或者周期播报的功能。 本代码实现HTTP接口的声光语音播报,并指定循环次数、播报内容。由于通知终端采用TTS语音合成技术,所以本次案例中无需预先录制音频。 代码实战 为了通过JavaScript调用博灵语音通知终端,实现HT

HarmonyOS】ArkTS学习之基于TextTimer的简易计时器的elapsedTime最小时间单位问题

本文旨在纪录自己对TextTimer使用过程的疑惑问题 我在查看教程时候,发现很多博客在onTimer(event: (utc: number, elapsedTime: number) => void) 这里提到elapsedTime:计时器经过的时间,单位为毫秒。我不清楚是否为版本问题。 在我查看version11和version10的api时候,说的都是设置格式的最小单位。 经过个人检验的