android 消息垂直滚动轮播控件

本文已更新,请移步最新发布的文章,功能更加完善!ViewsFlipper–最易用的的仿淘宝、京东消息轮播控件
类似淘宝首页的那种消息垂直滚动的控件,实现也很简单,网上也有很多例子,不过网上大多数的例子都是利用android的原生控件ViewFlipper,这个控件我也用了,最后发现很坑爹,有很多问题。
先说使用ViewFliper遇到的问题。首先一个就是ViewFlipper在手机锁屏然后再开屏之后有时候不再自动滚动,看了ViewFlipper的源码就知道,ViewFlipper中注册了一个广播接收器(BroadcastReceiver)用来接收系统锁屏和开屏的消息,并用来控制其中的一个boolean变量mUserPresent,这个变量将直接决定着ViewFlipper是否能自动滚动,但是我测试发现,有时候手机锁屏再开屏之后,ViewFlipper的广播接收器根本没有收到开屏的广播消息,导致变量的状态没有改变,从而导致ViewFlipper无法自动滚动。

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {            final String action = intent.getAction();            if (Intent.ACTION_SCREEN_OFF.equals(action)) {                mUserPresent = false;                updateRunning();            } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                mUserPresent = true;                updateRunning(false);            }        }    };    ...    private void updateRunning(boolean flipNow) {        boolean running = mVisible && mStarted && mUserPresent;        if (running != mRunning) {            if (running) {                showOnly(mWhichChild, flipNow);                postDelayed(mFlipRunnable, mFlipInterval);            } else {                removeCallbacks(mFlipRunnable);            }            mRunning = running;        }        if (LOGD) {            Log.d(TAG, "updateRunning() mVisible=" + mVisible + ", mStarted=" + mStarted                    + ", mUserPresent=" + mUserPresent + ", mRunning=" + mRunning);        }    }

而且我在Fragment中使用ViewFlipper还遇到了来回切换之后显示重影的问题,不过这个问题可以在切换的使用调用ViewFlipper的stopFlipping和stopFlippng函数来解决,不过这样做你还是会发现一个问题,就是切回来之后显示的第一个消息是带有入场动画的,但是上面却是空白!

查看ViewFlipper的startFlipping源码,可以看到 startFlipping调用了updateRunning(true)方法,这个方法又调用了父类ViewAnimator的showOnly(childId, flipNow)方法,showOnly方法就是根据传入的参数childId展示哪一项子view,并且根据flipNow决定是否播放动画,很不幸,调用startFlipping默认传入的参数就是播放动画,这就导致在显示第一项的时候展示了入场动画,但是上面为什么是空白的,我暂时也没搞懂,那个大神知道了还请告知一下!小菜在此感激不尽。

public void startFlipping() {        mStarted = true;        updateRunning();    }    private void updateRunning() {        updateRunning(true);    }

既然ViewFlipper不符合要求,那就自己写一个MyViewFlipper吧,借鉴ViewFlipper的源码,改动了部分代码,去掉了广播注册的部分,然后将startFlipping中传入不播放动画,效果如下图:

大功告成!
下面贴代码

  • **1、TextViewSwitcher **
package com.example.lee.rollingtextview.view;import android.content.Context;import android.content.res.TypedArray;import android.support.annotation.AnimRes;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import android.widget.ViewAnimator;import com.example.lee.rollingtextview.R;import com.example.lee.rollingtextview.RollingTextAdapter;/** * Created by lihuayong on 18/7/20. * 代码参考ViewFlipper源码 * 修改了部分源码,如不再接收手机锁屏和开屏广播,需要调用api手动设置自动播放 * */public class TextViewSwitcher extends ViewAnimator {    private static final  String TAG = "TextViewSwitcher";    private static final int DEFAULT_FLIP_DURATION = 500;    private static final int DEFAULT_FLIP_INTERVAL = 3000;    private static final int DEFAULT_IN_ANIMATION = R.anim.rolling_text_in;    private static final int DEFAULT_OUT_ANIMATION = R.anim.rolling_text_out;    /**     * 切换的时间间隔     * */    private int mFlipInterval = DEFAULT_FLIP_INTERVAL;    /**     * 动画切换时间间隔     */    private int mFlipDuration = DEFAULT_FLIP_DURATION;    @AnimRes    private int mInAnimation = DEFAULT_IN_ANIMATION;    @AnimRes    private int mOutAnimation = DEFAULT_OUT_ANIMATION;    private boolean mAutoStart = false;    private boolean mVisible = false;    private boolean mStarted = false;    private boolean mRunning = false;    private RollingTextAdapter mAdapter;    private OnItemClickListener mListener;    private int mCurItem = 0;    public TextViewSwitcher(Context context) {        this(context,null);    }    public TextViewSwitcher(Context context, AttributeSet attrs) {        super(context, attrs);        parseConfig(context,attrs);        init(context);    }    private void parseConfig(Context context, @Nullable  AttributeSet attrs){        if(null != attrs) {            /** get set from xml files */            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextViewSwitcher);            mFlipDuration = a.getInteger(R.styleable.TextViewSwitcher_flipDuration, DEFAULT_FLIP_DURATION);            mFlipInterval = a.getInteger(R.styleable.TextViewSwitcher_flipInterval, DEFAULT_FLIP_INTERVAL);            mAutoStart = a.getBoolean(R.styleable.TextViewSwitcher_autoStart, false);            mInAnimation = a.getResourceId(R.styleable.TextViewSwitcher_inAnimation, DEFAULT_IN_ANIMATION);            mOutAnimation = a.getResourceId(R.styleable.TextViewSwitcher_outAnimation, DEFAULT_OUT_ANIMATION);            a.recycle();        }    }    private void init(Context context){        Animation animIn = AnimationUtils.loadAnimation(context, mInAnimation);        setInAnimation(animIn);        Animation animOut = AnimationUtils.loadAnimation(context, mOutAnimation);        setOutAnimation(animOut);        setFlipInterval(mFlipInterval);        setFlipDuration(mFlipDuration);        setAutoStart(mAutoStart);    }    /**     * load subview     */    private void start(){        if(this.mAdapter == null||this.mAdapter.getCount() <= 0){            return;        }        removeAllViews();        //auto start flipping while data size >= 2        if(this.mAdapter.getCount() >2)            setAutoStart(true);        else            setAutoStart(false);        for(int i =0;i
  • 4、进场和退场动画roll_text_in和roll_text_out
<?xml version="1.0" encoding="utf-8"?>    <?xml version="1.0" encoding="utf-8"?>    
  • 5、item_layout
<?xml version="1.0" encoding="utf-8"?>                                                

就先这样吧,刚刚开始写博客,XD。其中参考了网上的一些方法,链接没有保存就不在这里一一列举了,还请见谅。
工程demo链接下载地址

更多相关文章

  1. Android(安卓)API : SMS短信服务处理
  2. Android之——史上最简单旋转菜单实现效果
  3. Android(安卓)最简单的导航栏实现
  4. 程序媛也话Android(安卓)之 自定义控件(垂直方向滑动条)
  5. Android动画效果Animation之Tween实现简单动画
  6. Android(安卓)Handler解析
  7. 面试经典题Handler机制回答
  8. Android通知栏-Notification(通知消息)
  9. Android中的属性动画理解

随机推荐

  1. Debian 10 Buster release party 重庆站
  2. MySQL的增强型语法高亮终端-MyCli
  3. HCIA-VRP基础及操作
  4. Linux系统性能监控工具Tsar
  5. MySQL多线程备份工具Mydumper详解
  6. Spring、Shiro和EHCache 缓存的使用案例
  7. 用httping测试WEB页面响应时间
  8. CentOS 6下搭建Open***服务器
  9. Hadoop集群搭建及Hive的安装与使用
  10. 利用lshell来构建一个受限的用户SHELL环