Android 天气预报图文字幕垂直滚动效果


       在很多天气或者新闻的应用中,我们都能看到一些字幕滚动的效果,最简单的实现为跑马灯效果,用系统提供的属性即可实现. 复杂一些的就需要自己去用自定义控件实现. 比如 让TextView 实现垂直滚动. 这里我要讲的是垂直滚动的字幕效果,并且内容并不仅为文字,还可以加入图片或者其他元素. 废话不多说,还是直接上效果图:

                                 

  

首先还是看一下核心的实现:

目前我的做法是重写了ScrollView,对外提供几个重要的方法:

isScrolled()方法判断当前是否为滚动状态

setScrolled(boolean flag)设置滚动的开关

setPeriod(long period)设置从开始滚动到结束的时间

setSpeed(long speed)设置滚动的速度


下面说一些需要注意的地方:

1.由于是定时操作,所以需要在Activity的对应生命周期进行处理: 当界面由不可见到可见时,设置setScrolled(true)打开滚动开关,由可见到不可见时,setScrolled(false)

关闭开关

2. 可根据自己需要调用setPeriod(long period)setSpeed(long speed)控制滚动的速度

3. 由于是ScrollView实现的,中间放置的内容同ScrollView,不仅仅可以设置文字,还可以添加图片等其他元素,实现复杂的UI

4. 图文混排, 目前这个DEMO我还没做细致处理. 最主要的部分就是文字的处理,需要考虑中英文,全角半角,字体大小,段落处理,计算对应的字符宽高等进行排版

    图片等资源处理的部分就相对要简单,主要处理分辨率与计算宽高

    关于这些部分,之后我会慢慢做细致讲解.

这个Demo是我临时写的,UI和图文混排包括具体的滚动部分处理都相对简单,大家可以在这个例子的基础上进行扩展,根据需求做出自己想要的效果:

Demo下载地址:http://download.csdn.net/detail/t12x3456/5875157


下面是对应的代码:

首先是自定义View:

package com.tony.autoscroll;


import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ScrollView;


/**
 * @author Tony
 *
 */
public class AutoScrollView extends ScrollView {
	private final Handler handler = new Handler();
	 private long duration     = 50;
	 private boolean isScrolled   = false;
	private int currentIndex = 0;
	private long period = 1000;
	private int  currentY = -1;
	private double	x;
	private double 	y;
	private int type = -1;
  	/**
	 * @param context
	  */
	 public AutoScrollView(Context context) {
		this(context, null);
	}
	
	 /**
	  * @param context
	 * @param attrs
	  */
	public AutoScrollView(Context context, AttributeSet attrs) {
		 this(context, attrs, 0);
	}
	
 	/**
	  * @param context
	   * @param attrs
	   * @param defStyle
	   */
	public AutoScrollView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	 }
	
 	public boolean onTouchEvent(MotionEvent event) {
		 int Action = event.getAction();
 		switch (Action) {
 			case MotionEvent.ACTION_DOWN:
				x=event.getX();
 				y=event.getY();
				 if (type == 0) {
					 setScrolled(false);
                                }
				 break;
			 case MotionEvent.ACTION_MOVE:
				double moveY = event.getY() - y;
				 double moveX = event.getX() - x;
				 
				if ((moveY>20||moveY<-20) && (moveX < 50 || moveX > -50) && getParent() != null) {
					 getParent().requestDisallowInterceptTouchEvent(true);  
                                 }
			
				 break;
			case MotionEvent.ACTION_UP:
				 if (type == 0) {
					 currentIndex = getScrollY();
					setScrolled(true);
                }
				break;
 			default:
 				break;
		}
                  return super.onTouchEvent(event);  
	   }
	     @Override  
	     public boolean onInterceptTouchEvent(MotionEvent p_event)  
	    {  
		 
	        return true;  
	    }  
 	/**
 	  * 判断当前是否为滚动状态
	  * 
	  * @return the isScrolled
	  */
	 public boolean isScrolled() {
		return isScrolled;
	 }
	
	 /**
	  * 开启或者关闭自动滚动功能
	  * 
	  * @param isScrolled true为开启,false为关闭
	  */
	 public void setScrolled(boolean isScrolled) {
		this.isScrolled = isScrolled;
		autoScroll();
	 }
	
 	 /**
	  * 获取当前滚动到结尾时的停顿时间,单位:毫秒
	  * 
	  * @return the period
	  */
 	public long getPeriod() {
		return period;
	 } 
	
	/**
	  * 设置当前滚动到结尾时的停顿时间,单位:毫秒
	  * 
	  * @param period
	  *  the period to set
	 */
 	public void setPeriod(long period) {
		 this.period = period;
	 }
	
 	  /**
	  * 获取当前的滚动速度,单位:毫秒,值越小,速度越快。
	   * 
	  * @return the speed
	  */
	 public long getSpeed() {
		return duration;
 	 }
	
	 /**
	  * 设置当前的滚动速度,单位:毫秒,值越小,速度越快。
	  * 
	  * @param speed
	  *            the duration to set
	  */
	 public void setSpeed(long speed) {
		 this.duration = speed;
	 }
	 public void setType(int type){
		 this.type = type;
	 }
	 private void autoScroll() {
		 handler.postDelayed(new Runnable() {
			@Override
			 public void run() {
				boolean flag = isScrolled;
				 if (flag) {
					if (currentY == getScrollY()) {
						 try {
 							Thread.sleep(period);
						} catch (InterruptedException e) {
 							e.printStackTrace();
 						}
						currentIndex = 0;
						 scrollTo(0, 0);
						handler.postDelayed(this, period);
 					} else {
						currentY = getScrollY();
 						handler.postDelayed(this, duration);
						currentIndex++;
 						scrollTo(0, currentIndex * 1);
					}
				} else {
                                       //currentIndex = 0;
                                       //scrollTo(0, 0);
				}
			}
		}, duration);
	}
}

MainActivity:

package com.tony.autoscroll;

import com.example.testautoscroll.R;

import android.os.Bundle;
import android.app.Activity;

/**
 * link: blog.csdn.net/t12x3456
 * @author Tony
 *
 */
public class MainActivity extends Activity {

	private AutoScrollView scrollView;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	
		scrollView = (AutoScrollView) findViewById(R.id.auto_scrollview);
	}

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		
		if(!scrollView.isScrolled()){
			scrollView.setScrolled(true);
		}
		super.onStart();
	}
	
	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		
		if(scrollView.isScrolled()){
			scrollView.setScrolled(false);
		}
		super.onStop();
	}
}

如有转载,请声明出处: 时之沙: http://blog.csdn.net/t12x3456

你可能感兴趣的:(Android)