无限循环的HorizontalScrollview
来源:互联网 发布:栈实现链表反转java 编辑:程序博客网 时间:2024/04/29 02:36
前几天有同学要我帮忙写一个无限循环的scrollview,恰好之前看过一篇博文,是讲自定义scrollview实现多个view存在的scrollview滚动,就把原作者的代码修改了一下,变成了可以无限循环左右滑动的scrollview,交差啦。。
原博客地址http://blog.csdn.net/lmj623565791/article/details/38140505
主要的修改是在自定义scrollview的部分,其余部分可以完全参考上面的博客,建议先看完上面的文章再来读这篇博客,废话少说,上代码:
主要的修改是在loadNext()和loadPre();因为实现的目的是无限循环滑动,原文中的很多预留接口和监听都删掉了,需要的同学可以自己参照添加。
public class MyHorizontalScrollView extends HorizontalScrollView implements
View.OnClickListener {
private OnItemClickListener mOnClickListener;
private LinearLayout mContainer;
/** * 子元素的宽度 */private int mChildWidth;/** * 子元素的高度 */private int mChildHeight;/** * 当前最后一张图片的index */private int mCurrentIndex;/** * 当前第一张图片的下标 */private int mFristIndex;/** * 当前第一个View */private View mFirstView;/** * 数据适配器 */// private HorizontalScrollViewAdapter mAdapter;/** * 每屏幕最多显示的个数 */private int mCountOneScreen;/** * 屏幕的宽度 */private int mScreenWitdh;/** * 保存View与位置的键值对 */private HorizontalScrollViewAdapter mAdapter;private Map<View, Integer> mViewPos = new HashMap<View, Integer>();public interface OnItemClickListener { void onClick(View view, int pos);}public MyHorizontalScrollView(Context context, AttributeSet attrs) { super(context, attrs); WindowManager wm = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); mScreenWitdh = outMetrics.widthPixels;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mContainer = (LinearLayout) getChildAt(0);}public void initView(HorizontalScrollViewAdapter mAdapter) { this.mAdapter = mAdapter; mContainer = (LinearLayout) getChildAt(0); View v = mAdapter.getView(0, null, mContainer); ; mContainer.addView(v);// why add if (mChildWidth == 0 && mChildHeight == 0) { int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); v.measure(w, h); mChildHeight = v.getMeasuredHeight(); mChildWidth = v.getMeasuredWidth(); mCountOneScreen = mScreenWitdh / mChildWidth + 2; } initFirstScreenView(mCountOneScreen);}private void initFirstScreenView(int mCountOneScreen2) { mContainer = (LinearLayout) getChildAt(0); mContainer.removeAllViews(); mViewPos.clear(); for (int i = 0; i < mCountOneScreen; i++) { View v = mAdapter.getView(i, null, mContainer); v.setOnClickListener(this); mContainer.addView(v); mViewPos.put(v, i); mCurrentIndex = i; }}@Overridepublic boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_MOVE: int scrollX = getScrollX(); if (scrollX >= mChildWidth) { loadNext(); } if (scrollX == 0) { loadPre(); } break; } return super.onTouchEvent(ev);}private void loadNext() { View v; scrollTo(0, 0); mViewPos.remove(mContainer.getChildAt(0)); mContainer.removeViewAt(0); if (mCurrentIndex == mAdapter.getCount() - 1) { v = mAdapter.getView(0, null, mContainer); mCurrentIndex = 0; } else { v = mAdapter.getView(++mCurrentIndex, null, mContainer); } v.setOnClickListener(this); mContainer.addView(v); mViewPos.put(v, mCurrentIndex); mFristIndex++;}private void loadPre() { int oldViewPos = mContainer.getChildCount() - 1; if (mFristIndex == 0) { mViewPos.remove(mContainer.getChildAt(oldViewPos)); mContainer.removeViewAt(oldViewPos); View view = mAdapter.getView(mAdapter.getCount() - 1, null, mContainer); mViewPos.put(view, mAdapter.getCount() - 1); mContainer.addView(view, 0); view.setOnClickListener(this); // 水平滚动位置向左移动view的宽度个像素 scrollTo(mChildWidth, 0); mFristIndex = mAdapter.getCount() - 1; } else { int index = mCurrentIndex - mCountOneScreen; if (index >= 0) { mViewPos.remove(mContainer.getChildAt(oldViewPos)); mContainer.removeViewAt(oldViewPos); View view = mAdapter.getView(index, null, mContainer); mViewPos.put(view, index); mContainer.addView(view, 0); view.setOnClickListener(this); // 水平滚动位置向左移动view的宽度个像素 scrollTo(mChildWidth, 0); mFristIndex--; } else { mViewPos.remove(mContainer.getChildAt(oldViewPos)); mContainer.removeViewAt(oldViewPos); View view = mAdapter.getView(index + mAdapter.getCount(), null, mContainer); mViewPos.put(view, index + mAdapter.getCount()); mContainer.addView(view, 0); view.setOnClickListener(this); // 水平滚动位置向左移动view的宽度个像素 scrollTo(mChildWidth, 0); // 当前位置--,当前第一个显示的下标-- mFristIndex--; } } mCurrentIndex = mViewPos .get(mContainer.getChildAt(mCountOneScreen - 1));}@Overridepublic void onClick(View v) { if (mOnClickListener != null) { mOnClickListener.onClick(v, mViewPos.get(v)); }}
}
最终效果
图片发不上来,最后的效果就是一个包含了很多控件的scrollview,可以实现左右无限滑动
0 0
- 无限循环的HorizontalScrollview
- 无限循环的ViewPager
- 无限循环的计时器
- 无限循环的LinearLayout
- 无限循环的Viewpager
- for结构的无限循环
- 无限循环的一种表示
- 终止无限循环的线程
- 无限循环小数的循环节
- viewpager的无限循环方法
- 无限循环的图片浏览器
- 无限循环的图片轮播器
- 轮播图的伪无限循环
- ViewPage的无限循环(五)
- viewpager无限循环的问题
- 删除无限循环的文件夹。
- 循环的中断与无限循环
- 无限循环
- Win7系统下安装配置Apache+PHP+MySQL(LAMP)环境
- Scala-5 - 2 - Lecture 4.2 - Objects Everywhere (19_07)
- nyoj.1092 数字分隔(二)【水题】 2015/03/14
- 流水账 - 对某脚本优化的记录
- Quartz.NET学习系列(六)--- 中断任务
- 无限循环的HorizontalScrollview
- c++用参数返回堆上的空间
- Codeforces 294D
- POJ 1258 Agri-Net (kruskal求最小生成树)
- C++之静态联编和动态联编
- EXEC
- SSH学习问题总结之Dispatcher initialization failedUnable to load configuration
- 黑马程序员-OC学习笔记-----self指针、点语法、构造方法、类别
- 组合数学