本文实例为大家分享了自定义view实现了类似百度手机助手,首页评论滚动效果。

看效果:

gif做的不好,其效果就是:几个viewitem不停的向上滚动,新加入item有个淡入的效果。

说下实现思路:自定义view继承至LinearLayout,控制item数量及其动画效果,实现item复用,传入数据即可,使用方便。

代码:

/**

* Jiantao.Yang

*

* @description 仿百度手机助手,评论滚动效果

* @time 2015/1/16 17:37

*/

public class ViewFlipper extends LinearLayout {

private final int MAX_SHOW_ITEM_SIZE = 5;

private IAdapter mIAdapter;

private int mCount;

//最后一个item动画

private Animation mLastOneAnimation;

//其它item动画

private Animation mCommonAnimation;

//数据下标

private int mCurrentIndex;

/**

* 这里动画时间是1600毫秒,所以间隔得大于动画时间

*/

private static final int DEFAULT_INTERVAL = 2000;

private int mFlipInterval = DEFAULT_INTERVAL;

private boolean mAutoStart = false;

private boolean mRunning = false;

private boolean mStarted = false;

private boolean mVisible = false;

private boolean mUserPresent = true;

public ViewFlipper(Context context) {

super(context);

init(context);

}

public ViewFlipper(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}

public ViewFlipper(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init(context);

}

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);

}

}

};

@Override

protected void onAttachedToWindow() {

super.onAttachedToWindow();

// Listen for broadcasts related to user-presence

final IntentFilter filter = new IntentFilter();

filter.addAction(Intent.ACTION_SCREEN_OFF);

filter.addAction(Intent.ACTION_USER_PRESENT);

// OK, this is gross but needed. This class is supported by the

// remote views machanism and as a part of that the remote views

// can be inflated by a context for another user without the app

// having interact users permission - just for loading resources.

// For exmaple, when adding widgets from a user profile to the

// home screen. Therefore, we register the receiver as the current

// user not the one the context is for.

getContext().registerReceiver(mReceiver, filter);

if (mAutoStart) {

// Automatically start when requested

startFlipping();

}

}

@Override

protected void onDetachedFromWindow() {

super.onDetachedFromWindow();

mVisible = false;

getContext().unregisterReceiver(mReceiver);

updateRunning();

}

@Override

protected void onWindowVisibilityChanged(int visibility) {

super.onWindowVisibilityChanged(visibility);

mVisible = visibility == VISIBLE;

updateRunning(mVisible);

// updateRunning(false);

}

private void init(Context context) {

this.setOrientation(LinearLayout.VERTICAL);

}

public void setIAdapter(IAdapter iAdapter) {

this.mIAdapter = iAdapter;

initShowItems();

}

public void startFlipping() {

mStarted = true;

updateRunning();

}

public void stopFlipping() {

mStarted = false;

updateRunning();

}

private void updateRunning() {

updateRunning(true);

}

/**

* Returns true if the child views are flipping.

*/

public boolean isFlipping() {

return mStarted;

}

/**

* Set if this view automatically calls {@link #startFlipping()} when it

* becomes attached to a window.

*/

public void setAutoStart(boolean autoStart) {

mAutoStart = autoStart;

}

/**

* Returns true if this view automatically calls {@link #startFlipping()}

* when it becomes attached to a window.

*/

public boolean isAutoStart() {

return mAutoStart;

}

@Override

public void onInitializeAccessibilityEvent(AccessibilityEvent event) {

super.onInitializeAccessibilityEvent(event);

event.setClassName(ViewFlipper.class.getName());

}

@Override

public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {

super.onInitializeAccessibilityNodeInfo(info);

info.setClassName(ViewFlipper.class.getName());

}

/**

* 初始化childViews

*/

private void initShowItems() {

if (mIAdapter != null) {

mCount = mIAdapter.getCount();

for (int i = 0; i < mCount; i++) {

if (i == MAX_SHOW_ITEM_SIZE) {

break;

}

View convertView = getChildAt(i);

View item = mIAdapter.getItemView(convertView, i);

addView(item, i);

}

}

}

/**

* Internal method to start or stop dispatching flip {@link android.os.Message} based

* on {@link #mRunning} and {@link #mVisible} state.

*

* @param flipNow Determines whether or not to execute the animation now, in

* addition to queuing future flips. If omitted, defaults to

* true.

*/

private void updateRunning(boolean flipNow) {

boolean running = mVisible && mStarted && mUserPresent;

System.out.println(" updateRunning running:" + running + " mVisible " + mVisible + " userPresent " + mUserPresent);

if (running != mRunning) {

if (running && (mCount > MAX_SHOW_ITEM_SIZE)) {

showItems(mCurrentIndex++, flipNow);

Message msg = mHandler.obtainMessage(FLIP_MSG);

mHandler.sendMessageDelayed(msg, mFlipInterval);

} else {

mHandler.removeMessages(FLIP_MSG);

}

mRunning = running;

}

}

private void showItems(final int position, boolean animate) {

if (animate && (mLastOneAnimation == null || mCommonAnimation == null)) {

mLastOneAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.lastone_anim);

mCommonAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.common_anim);

}

int childCount = getChildCount();

for (int i = 0; i < childCount; i++) {

View child = getChildAt(i);

child.clearAnimation();

int index = position + i;

child = mIAdapter.getItemView(child, (index >= mIAdapter.getCount()) ? (index - mIAdapter.getCount()) : index);

if (animate) {

if (i == childCount - 1) {

child.setAnimation(mLastOneAnimation);

} else {

child.setAnimation(mCommonAnimation);

}

}

child.setVisibility(View.VISIBLE);

}

if (animate) {

mCommonAnimation.startNow();

mLastOneAnimation.startNow();

}

//保证传入的position小于getCount

if (mCurrentIndex >= mIAdapter.getCount()) {

mCurrentIndex = 0;

}

}

private final int FLIP_MSG = 1;

private final Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

if (msg.what == FLIP_MSG) {

if (mRunning) {

showItems(mCurrentIndex++, true);

msg = obtainMessage(FLIP_MSG);

sendMessageDelayed(msg, mFlipInterval);

}

}

}

};

public interface IAdapter {

/**

* @param convertView

* @param position

* @return

*/

public View getItemView(View convertView, int position);

/**

* @return 数据count

*/

public int getCount();

}

}

再来看看调用部分:

public class MainActivity extends ActionBarActivity implements ViewFlipper.IAdapter {

ViewFlipper viewFlipper;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

viewFlipper = (ViewFlipper) findViewById(R.id.view_flipper);

viewFlipper.setIAdapter(this);

}

@Override

protected void onResume() {

super.onResume();

viewFlipper.startFlipping();

}

@Override

public View getItemView(View convertView, int position) {

View item = null;

TextView textView;

if (convertView == null) {

item = View.inflate(this, R.layout.item, null);

} else {

item = convertView;

}

textView = (TextView) item.findViewById(R.id.textview);

textView.setText("测试数据:" + position);

return item;

}

@Override

public int getCount() {

return 8;

}

}

可以看出,MainActivity实现了ViewFlipper.IAdapter接口,setAdapter后调用startFlipper即可。

这里布局文件我就不贴出来了,附上工程源码,项目里动画时间有点长,修改下就ok。

限于水平有限,不足之处难免,望各位不舍指正,与君共勉。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

android viewflipper 动画,Android自定义ViewFlipper实现滚动效果相关推荐

  1. Android 气泡动画(自定义View类)

    Android 气泡动画(自定义View类) 一.前言 二.代码 1. 随机移动的气泡 2.热水气泡 一.前言 最近有需求制作一个水壶的气泡动画,首先在网上查找了一番,找到了一个文章. https:/ ...

  2. android 科技动画,android开发ViewFlipper触摸动画

    [IT168技术]介绍:在教程中,我们可以学习如何解决在Android项目的共同问题,有更多的关于Android的项目信息,我建议你下载ADT Android Pluglins和Eclipse. 背景 ...

  3. android弹球动画,Android动画之自定义Evaluator实现弹球效果

    前言 今天给大家带来的是自定义Evaluator实现弹球效果,我们先给大家来个效果图. 下面我们介绍具体代码流程 1. 自定义Point类 public class Point { private i ...

  4. Android属性动画与自定义View——实现vivo x6更新系统的动画效果

    晚上好,现在是凌晨两点半,然后我还在写代码.电脑里播放着<凌晨两点半>,晚上写代码,脑子更清醒,思路更清晰. 今天聊聊属性动画和自定义View搭配使用,前面都讲到自定义View和属性动画, ...

  5. android 海浪动画,android自定义波浪加载动画的实现代码

    本文实例为大家分享了android自定义波浪加载动画的具体代码,供大家参考,具体内容如下 效果图 1.自定义控件 WaveView package com.example.wh.myapplicati ...

  6. android卡包动画,自定义View实现银行卡卡包动画效果

    本来不想自己造轮子的,但奈何没找动相应效果的轮子,所以只能自己写了,其实还是白嫖来的轻松,哈哈 先看效果 这个是完成的效果,还可以吧!关键也不难一个自定义View搞定 先说一下思路,继承一个Relat ...

  7. android scrollview 动画,Android ScrollView实现下拉弹回动画效果

    这里设计一个自定义View,继承了ScrollView,实现可以下拉里面的内容,松手后画面弹回,这个自定义的View可以当做ScrollView来使用. 一般设计时的应用效果: 一.自定义View的设 ...

  8. android 底部动画,Android实现360手机助手底部的动画菜单

    首先来看下我们实现的效果和360效果的对比: 360手机助手效果演示 本库实现的效果(Icon来自360手机助手,侵删) xml布局文件 注:为了美观,讲每个Button的高度以及固定,设置wrap_ ...

  9. android 齿轮动画,Android仿正点闹钟时间齿轮滑动效果

    看到正点闹钟上的设置时间的滑动效果非常好看,自己就想做一个那样的,在网上就开始搜资料了,看到网上有的齿轮效果的代码非常多,也非常难懂,我就决定自己研究一下,现在我就把我的研究成果分享给大家.我研究的这 ...

  10. android 逐字动画,Android实现文本逐字显示View(类似rpg游戏人物对话,文本逐字显示)...

    前面好多篇文章都是Android Studio.源码编译.ndk等相关教程,今天敲一敲代码,不然都生锈了哈_. 来个古装动画美图,缓解大家疲劳的眼睛...(话说有木有人知道这是谁???) Paste_ ...

最新文章

  1. 如何直观地理解「协方差矩阵」?
  2. Verilog中的二维数组及其初始化
  3. leetcode191. 位1的个数
  4. 汇编程序—将一个全是字母,以0结尾的字符串,转化为大写
  5. sqllite查询数据量_详解SQLite中的查询规划器
  6. 和整数相乘_小学数学基础概念归纳总结:整数篇
  7. w ndows安装程序无法将,windows安装程序无法将windows配置在硬件上运行
  8. 你想成为什么级别的程序员?
  9. 字写的不好没关系,用python随便就生成了艺术签名
  10. 人生的意义是通过努力活得更好
  11. CAPA换届大会召开,发布信息无障碍最新报告及“可及APP”
  12. 外卖O2O硝烟初起巨头们各自是啥思路?
  13. dnn降噪_可能是周杰伦粉丝必买好物?1MORE降噪圈铁蓝牙耳机PRO版体验
  14. 务虚:大局观、方法与关键点
  15. 分布式调度:对概念和应用的回顾
  16. 《触动人心—设计优秀的iPhone应用》读书笔记(一)
  17. 永中Office与QQ
  18. Mac 环境下下配置opencv +python
  19. 曲堤黄瓜批发市场:小黄瓜用上云计算 蔬菜收购结算刷卡就走
  20. 大根堆与小根堆的理解,如何手写一个堆,以及什么时候用自己手写的堆,什么时候用语言提供堆的api,(二者的区别)

热门文章

  1. MyBatis(三)------MyBatis的核心组件
  2. semaphore的几种用法
  3. Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)
  4. SpringBoot(三) SpringBoot中的日志配置
  5. Day002_LInux基础_常用命令
  6. PhpStorm Live Template加PHP短语法Short Open Tags打造原生模板
  7. Nginx之(一)Nginx是什么
  8. 自旋锁原理及java自旋锁
  9. VS2010+OpenCV2.4.6永久性配置方法
  10. 实例化Spring容器的两种常用方式