无限循环的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
原创粉丝点击