Android开发实现自定义水平滚动的容器示例
程序员文章站
2024-02-11 17:26:40
本文实例讲述了android开发实现自定义水平滚动的容器。分享给大家供大家参考,具体如下:
public class horizontalscrollview e...
本文实例讲述了android开发实现自定义水平滚动的容器。分享给大家供大家参考,具体如下:
public class horizontalscrollview extends viewgroup { //手势 private gesturedetector mgesturedetector; private horizontalscroller mscroller; private int curid; //快速滑动 private boolean isflying; //--回调函数------------------------------------- private onchangelistener mlistener; public void setonchangelistener(onchangelistener listener) { if (listener != null) { mlistener = listener; } } public interface onchangelistener{ void move2dest(int curid); } public horizontalscrollview(context context) { this(context, null); } public horizontalscrollview(context context, attributeset attrs) { this(context, attrs, 0); } public horizontalscrollview(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); mscroller = new horizontalscroller(); isflying = false; initgesture(context); } @override protected void onlayout(boolean changed, int l, int t, int r, int b) { // 模向移动, for (int i = 0; i < getchildcount(); i++) { view view = getchildat(i); //给水平方向的每个view定位 view.layout(i * getwidth(), 0, getwidth() + i * getwidth(), getheight()); } } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { for (int i = 0; i < getchildcount(); i++) { view view = getchildat(i); view.measure(widthmeasurespec, heightmeasurespec); } super.onmeasure(widthmeasurespec, heightmeasurespec); } @override public boolean ontouchevent(motionevent event) { mgesturedetector.ontouchevent(event); switch (event.getaction()) { case motionevent.action_down: if (!isflying) { move2dest(); } isflying = false; break; case motionevent.action_move: break; case motionevent.action_up: break; default: break; } return true; } public void move2dest() { // int destid = (getscrollx() + getwidth() / 2) / getwidth(); move2dest(destid); } public void move2dest(int destid) { curid = destid; if (destid > getchildcount() - 1) { destid = getchildcount() - 1; } if (mlistener != null) { mlistener.move2dest(curid); } int distance = (int) (destid * getwidth() - getscrollx()); // scrollby(distance, 0); mscroller.startscroll(getscrollx(), getscrolly(), distance, 0); invalidate(); } /** * invalidate()此方法会触发下面的方法 */ @override public void computescroll() { // 如果存在偏移,就不断刷新 if (mscroller.computescrolloffset()) { scrollto(mscroller.getcurrx(), 0); invalidate(); } super.computescroll(); } private void initgesture(context context) { mgesturedetector = new gesturedetector(context, new ongesturelistener() { @override public boolean onsingletapup(motionevent e) { return false; } @override public void onshowpress(motionevent e) { } @override public boolean onscroll(motionevent e1, motionevent e2, float distancex, float distancey) { scrollby((int) distancex, 0); return false; } @override public void onlongpress(motionevent e) { } @override /** * 快速滑动时 */ public boolean onfling(motionevent e1, motionevent e2, float velocityx, float velocityy) { isflying = true; if (curid > 0 && velocityx > 0) {// 表示向左移 move2dest(curid - 1); } else if (curid < getchildcount() && velocityx < 0) { move2dest(curid + 1);// 向右 } else { move2dest();// 移到原位 } return false; } @override public boolean ondown(motionevent e) { return false; } }); } }
/** * 位移计算工具类 * * @author chenlin * */ public class horizontalscroller { private int startx; private int starty; private int distancex; private int distancey; private int currentx; private int currenty; private long starttime; private long duration = 1000l; private boolean isfinish; /** * * @param scrollx * x坐标 * @param scrolly * y坐标 * @param distancex * x方向移动的距离 * @param distancey * y方向移动的距离 */ public void startscroll(int scrollx, int scrolly, int distancex, int distancey) { startx = scrollx; starty = scrolly; this.distancex = distancex; this.distancey = distancey; isfinish = false; starttime = systemclock.uptimemillis(); } /** * 计算偏移量, * * @return true 还在移动 false:移动已经停止 */ public boolean computescrolloffset() { if (isfinish) { return false; } long timepassed = systemclock.uptimemillis() - starttime; if (timepassed < duration) { currentx = (int) (startx + distancex * timepassed / duration); currenty = (int) (starty + distancey * timepassed / duration); system.out.println("currentx:::" + currentx); } else if (timepassed >= duration) { currentx = startx + distancex; currenty = starty + distancey; isfinish = true; } return true; } public int getcurrx() { return currentx; } public void setcurrentx(int currentx) { this.currentx = currentx; } public int getcurrenty() { return currenty; } public void setcurrenty(int currenty) { this.currenty = currenty; } }
使用方法
public class scrollactivity extends activity implements oncheckedchangelistener, onchangelistener { private int[] ids = { r.drawable.a1, r.drawable.a2, r.drawable.a3, r.drawable.a4, r.drawable.a5, r.drawable.a6 }; private horizontalscrollview mview; private linearlayout mlayout; private radiogroup mgroup; @override protected void oncreate(bundle savedinstancestate) { requestwindowfeature(window.feature_no_title); super.oncreate(savedinstancestate); setcontentview(r.layout.activity_myscrollview); init(); } private void init() { mlayout = (linearlayout) findviewbyid(r.id.body_layout); mgroup = (radiogroup) findviewbyid(r.id.radiogroup); mview = new horizontalscrollview(this); for (int i = 0; i < ids.length; i++) { imageview imageview = new imageview(this); imageview.setbackgroundresource(ids[i]); mview.addview(imageview); } mlayout.addview(mview); // 随便添加一个view view view = getlayoutinflater().inflate(r.layout.activity_progressview, null); mview.addview(view, 3); for (int i = 0; i < mview.getchildcount(); i++) { radiobutton radiobutton = new radiobutton(this); // 设置id的编号 radiobutton.setid(i); mgroup.setorientation(linearlayout.horizontal); mgroup.addview(radiobutton); if (i == 0) { radiobutton.setchecked(true); } } mgroup.setoncheckedchangelistener(this); mview.setonchangelistener(this); } @override public void oncheckedchanged(radiogroup group, int checkedid) { mview.move2dest(checkedid); } @override public void move2dest(int curid) { radiobutton radiobutton = (radiobutton) mgroup.getchildat(curid); radiobutton.setchecked(true); } }
布局文件
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <radiogroup android:id="@+id/radiogroup" android:layout_width="wrap_content" android:layout_height="wrap_content" > </radiogroup> <linearlayout android:id="@+id/body_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > </linearlayout> </linearlayout>
更多关于android相关内容感兴趣的读者可查看本站专题:《android基本组件用法总结》、《android开发入门与进阶教程》、《android布局layout技巧总结》、《android视图view技巧总结》、《android编程之activity操作技巧总结》、《android资源操作技巧汇总》及《android控件用法总结》
希望本文所述对大家android程序设计有所帮助。
推荐阅读