qq_27665781
2016-01-06 08:39
采纳率: 53.9%
浏览 4.7k

Android horizontalscrollview滑动到最后面

图片说明
怎么样让horizontalscrollview 显示最后一个数据,就是让horizontalscrollview滑动到最后面。因为我后面还有两个选项

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • ProXin 2016-01-06 09:12
    已采纳
     package com.app.client.ui;
    
    import java.util.LinkedList;
    import java.util.Queue;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.database.DataSetObserver;
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.support.v4.view.ViewPager;
    import android.util.AttributeSet;
    import android.view.GestureDetector;
    import android.view.GestureDetector.OnGestureListener;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ListAdapter;
    import android.widget.Scroller;
    
    import com.ykx.app.client.R;
    
    public class HorizontalListView extends AdapterView<ListAdapter> {
    
        public boolean mAlwaysOverrideTouch = true;
        protected ListAdapter mAdapter;
        private int mLeftViewIndex = -1;
        private int mRightViewIndex = 0;
        protected int mCurrentX;
        protected int mNextX;
        private int mMaxX = Integer.MAX_VALUE;
        private int mDisplayOffset = 0;
        protected Scroller mScroller;
        private GestureDetector mGesture;
        private Queue<View> mRemovedViewQueue = new LinkedList<View>();
        private OnItemSelectedListener mOnItemSelected;
        private OnItemClickListener mOnItemClicked;
        private boolean mDataChanged = false;
        private Drawable mDivider;
        private Object mDividerWidth;
    
        private ViewPager mVp;
    
        public HorizontalListView(Context context, AttributeSet attrs) {
            super(context, attrs);
            retrieveXmlConfiguration(context, attrs);
            initView();
        }
    
        public void setViewPager(ViewPager vp) {
            mVp = vp;
        }
    
        private void retrieveXmlConfiguration(Context context, AttributeSet attrs) {
            if (attrs != null) {
                TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HorizontalListView);
    
                // Get the provided drawable from the XML
                final Drawable d = a.getDrawable(R.styleable.HorizontalListView_android_divider);
                if (d != null) {
                    // If a drawable is provided to use as the divider then use its
                    // intrinsic width for the divider width
                    setDivider(d);
                }
    
                // If a width is explicitly specified then use that width
                final int dividerWidth = a.getDimensionPixelSize(R.styleable.HorizontalListView_dividerWidth, 0);
                if (dividerWidth != 0) {
                    setDividerWidth(dividerWidth);
                }
    
                a.recycle();
            }
    
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // TODO Auto-generated method stub
            if (mVp != null)
                mVp.requestDisallowInterceptTouchEvent(true);
            return super.onTouchEvent(event);
        }
    
        public boolean onTouch(MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                if (mVp != null)
                    mVp.requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (mVp != null)
                    mVp.requestDisallowInterceptTouchEvent(false);
                break;
            }
            return super.onTouchEvent(event);
        }
    
        private void setDivider(Drawable divider) {
            mDivider = divider;
    
            if (divider != null) {
                setDividerWidth(divider.getIntrinsicWidth());
            } else {
                setDividerWidth(0);
            }
        }
    
        private void setDividerWidth(int width) {
            mDividerWidth = width;
    
            requestLayout();
            invalidate();
        }
    
        private synchronized void initView() {
            mLeftViewIndex = -1;
            mRightViewIndex = 0;
            mDisplayOffset = 0;
            mCurrentX = 0;
            mNextX = 0;
            mMaxX = Integer.MAX_VALUE;
            mScroller = new Scroller(getContext());
            mGesture = new GestureDetector(getContext(), mOnGesture);
        }
    
        @Override
        public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener) {
            mOnItemSelected = listener;
        }
    
        @Override
        public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
            mOnItemClicked = listener;
        }
    
        private DataSetObserver mDataObserver = new DataSetObserver() {
    
            @Override
            public void onChanged() {
                synchronized (HorizontalListView.this) {
                    mDataChanged = true;
                }
                invalidate();
                requestLayout();
            }
    
            @Override
            public void onInvalidated() {
                reset();
                invalidate();
                requestLayout();
            }
    
        };
    
        @Override
        public ListAdapter getAdapter() {
            return mAdapter;
        }
    
        @Override
        public View getSelectedView() {
            // TODO: implement
            return null;
        }
    
        @Override
        public void setAdapter(ListAdapter adapter) {
            if (mAdapter != null) {
                mAdapter.unregisterDataSetObserver(mDataObserver);
            }
            mAdapter = adapter;
            mAdapter.registerDataSetObserver(mDataObserver);
            reset();
        }
    
        private synchronized void reset() {
            initView();
            removeAllViewsInLayout();
            requestLayout();
        }
    
        @Override
        public void setSelection(int position) {
            // TODO: implement
        }
    
        private void addAndMeasureChild(final View child, int viewPos) {
            LayoutParams params = child.getLayoutParams();
            if (params == null) {
                params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
            }
    
            addViewInLayout(child, viewPos, params, true);
            child.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
        }
    
        @Override
        protected synchronized void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
    
            if (mAdapter == null) {
                return;
            }
    
            if (mDataChanged) {
                int oldCurrentX = mCurrentX;
                initView();
                removeAllViewsInLayout();
                mNextX = oldCurrentX;
                mDataChanged = false;
            }
    
            if (mScroller.computeScrollOffset()) {
                int scrollx = mScroller.getCurrX();
                mNextX = scrollx;
            }
    
            if (mNextX <= 0) {
                mNextX = 0;
                mScroller.forceFinished(true);
            }
            if (mNextX >= mMaxX) {
                mNextX = mMaxX;
                mScroller.forceFinished(true);
            }
    
            int dx = mCurrentX - mNextX;
    
            removeNonVisibleItems(dx);
            fillList(dx);
            positionItems(dx);
    
            mCurrentX = mNextX;
    
            if (!mScroller.isFinished()) {
                post(new Runnable() {
                    public void run() {
                        requestLayout();
                    }
                });
    
            }
        }
    
        private void fillList(final int dx) {
            int edge = 0;
            View child = getChildAt(getChildCount() - 1);
            if (child != null) {
                edge = child.getRight();
            }
            fillListRight(edge, dx);
    
            edge = 0;
            child = getChildAt(0);
            if (child != null) {
                edge = child.getLeft();
            }
            fillListLeft(edge, dx);
    
        }
    
        private void fillListRight(int rightEdge, final int dx) {
            while (rightEdge + dx < getWidth() && mRightViewIndex < mAdapter.getCount()) {
    
                View child = mAdapter.getView(mRightViewIndex, mRemovedViewQueue.poll(), this);
                addAndMeasureChild(child, -1);
                rightEdge += child.getMeasuredWidth();
    
                if (mRightViewIndex == mAdapter.getCount() - 1) {
                    mMaxX = mCurrentX + rightEdge - getWidth();
                }
                if (mMaxX < 0) {
                    mMaxX = 0;
                }
                mRightViewIndex++;
            }
    
        }
    
        private void fillListLeft(int leftEdge, final int dx) {
            while (leftEdge + dx > 0 && mLeftViewIndex >= 0) {
                View child = mAdapter.getView(mLeftViewIndex, mRemovedViewQueue.poll(), this);
                addAndMeasureChild(child, 0);
                leftEdge -= child.getMeasuredWidth();
                mLeftViewIndex--;
                mDisplayOffset -= child.getMeasuredWidth();
            }
        }
    
        private void removeNonVisibleItems(final int dx) {
            View child = getChildAt(0);
            while (child != null && child.getRight() + dx <= 0) {
                mDisplayOffset += child.getMeasuredWidth();
                mRemovedViewQueue.offer(child);
                removeViewInLayout(child);
                mLeftViewIndex++;
                child = getChildAt(0);
    
            }
    
            child = getChildAt(getChildCount() - 1);
            while (child != null && child.getLeft() + dx >= getWidth()) {
                mRemovedViewQueue.offer(child);
                removeViewInLayout(child);
                mRightViewIndex--;
                child = getChildAt(getChildCount() - 1);
            }
        }
    
        private void positionItems(final int dx) {
            if (getChildCount() > 0) {
                mDisplayOffset += dx;
                int left = mDisplayOffset;
                for (int i = 0; i < getChildCount(); i++) {
                    View child = getChildAt(i);
                    int childWidth = child.getMeasuredWidth();
                    child.layout(left, 0, left + childWidth, child.getMeasuredHeight());
                    left += childWidth;
                }
            }
        }
    
        public synchronized void scrollTo(int x) {
            mScroller.startScroll(mNextX, 0, x - mNextX, 0);
            requestLayout();
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            // TODO Auto-generated method stub
            if (mVp != null)
                mVp.requestDisallowInterceptTouchEvent(true);
            return super.onInterceptTouchEvent(ev);
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            if (mVp != null)
                mVp.requestDisallowInterceptTouchEvent(true);
            boolean handled = super.dispatchTouchEvent(ev);
            handled |= mGesture.onTouchEvent(ev);
            return handled;
        }
    
        protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            synchronized (HorizontalListView.this) {
                mScroller.fling(mNextX, 0, (int) -velocityX, 0, 0, mMaxX, 0, 0);
            }
            requestLayout();
    
            return true;
        }
    
        protected boolean onDown(MotionEvent e) {
            mScroller.forceFinished(true);
            return true;
        }
    
        private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() {
    
            @Override
            public boolean onDown(MotionEvent e) {
                return HorizontalListView.this.onDown(e);
            }
    
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY);
            }
    
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    
                synchronized (HorizontalListView.this) {
                    mNextX += (int) distanceX;
                }
                requestLayout();
    
                return true;
            }
    
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                Rect viewRect = new Rect();
                for (int i = 0; i < getChildCount(); i++) {
                    View child = getChildAt(i);
                    int left = child.getLeft();
                    int right = child.getRight();
                    int top = child.getTop();
                    int bottom = child.getBottom();
                    viewRect.set(left, top, right, bottom);
                    if (viewRect.contains((int) e.getX(), (int) e.getY())) {
                        if (mOnItemClicked != null) {
                            mOnItemClicked.onItemClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
                        }
                        if (mOnItemSelected != null) {
                            mOnItemSelected.onItemSelected(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
                        }
                        break;
                    }
    
                }
                return true;
            }
    
        };
    
    }
    
    
    已采纳该答案
    打赏 评论
  • ProXin 2016-01-06 09:10

    我用的这个自定义的是好的

     public class MyTRecyclerView extends RecyclerView implements OnScrollListener {
    
        /**
         * 记录当前第一个View
         */
        private View curView;
    
        private OnItemScrollChangeListener2 listener;
    
        public void setOnItemScrollChangeListener2(
                OnItemScrollChangeListener2 listener) {
            this.listener = listener;
        }
    
        public interface OnItemScrollChangeListener2 {
            void onChange(View view, int position);
        }
    
        public MyTRecyclerView(Context context, AttributeSet attrs) {
            super(context, attrs);
            // TODO Auto-generated constructor stub
            this.setOnScrollListener(this);
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            super.onLayout(changed, l, t, r, b);
    
            curView = getChildAt(0);
    
            //if (listener != null) {
            if (listener != null&&curView != null) {
                listener.onChange(curView,getChildPosition(curView));
            }
        }
    
        /**
         * 
         * 滚动时,判断当前第一个View是否发生变化,发生才回调
         */
        @Override
        public void onScrolled(int arg0, int arg1) {
            View newView = getChildAt(0);
            if (listener != null) {
                if (newView != null && newView != curView) {
                    curView = newView;
                    listener.onChange(curView,getChildPosition(curView));
                }
            }
        }
    
        @Override
        public void onScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub
    
        }
    
    }
    
    

    你试试啊

    打赏 评论

相关推荐 更多相似问题