当前位置: 移动技术网 > IT编程>移动开发>Android > Android自定义ViewFlipper实现滚动效果

Android自定义ViewFlipper实现滚动效果

2019年09月09日  | 移动技术网IT编程  | 我要评论

退不回,国产汽车标志大全,从化钟楼古村

本文实例为大家分享了自定义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。

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

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网