水平listview
来源:互联网 发布:java 单点登录 编辑:程序博客网 时间:2024/04/29 03:37
项目地址:https://codeload.github.com/kk-java/HorizontalListView/zip/master
import java.util.LinkedList;import java.util.Queue;import android.content.Context;import android.database.DataSetObserver;import android.graphics.Rect;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;/** * */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 OnItemLongClickListener mOnItemLongClicked;private boolean mDataChanged = false;public HorizontalListView(Context context, AttributeSet attrs){super(context, attrs);initView();}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);}@Overridepublic void setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener){mOnItemSelected = listener;}@Overridepublic void setOnItemClickListener(AdapterView.OnItemClickListener listener){mOnItemClicked = listener;}@Overridepublic void setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener){mOnItemLongClicked = listener;}private DataSetObserver mDataObserver = new DataSetObserver(){@Overridepublic void onChanged(){synchronized (HorizontalListView.this){mDataChanged = true;}invalidate();requestLayout();}@Overridepublic void onInvalidated(){reset();invalidate();requestLayout();}};@Overridepublic ListAdapter getAdapter(){return mAdapter;}@Overridepublic View getSelectedView(){// TODO: implementreturn null;}@Overridepublic void setAdapter(ListAdapter adapter){if (mAdapter != null){mAdapter.unregisterDataSetObserver(mDataObserver);}mAdapter = adapter;mAdapter.registerDataSetObserver(mDataObserver);reset();}private synchronized void reset(){initView();removeAllViewsInLayout();requestLayout();}@Overridepublic 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));}@Overrideprotected 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(){@Overridepublic 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 + child.getPaddingRight();}}}public synchronized void scrollTo(int x){mScroller.startScroll(mNextX, 0, x - mNextX, 0);requestLayout();}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev){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(){@Overridepublic boolean onDown(MotionEvent e){return HorizontalListView.this.onDown(e);}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY){return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY);}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY){synchronized (HorizontalListView.this){mNextX += (int) distanceX;}requestLayout();return true;}@Overridepublic boolean onSingleTapConfirmed(MotionEvent e){for (int i = 0; i < getChildCount(); i++){View child = getChildAt(i);if (isEventWithinView(e, child)){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;}@Overridepublic void onLongPress(MotionEvent e){int childCount = getChildCount();for (int i = 0; i < childCount; i++){View child = getChildAt(i);if (isEventWithinView(e, child)){if (mOnItemLongClicked != null){mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex+ 1 + i,mAdapter.getItemId(mLeftViewIndex + 1 + i));}break;}}}private boolean isEventWithinView(MotionEvent e, View child){Rect viewRect = new Rect();int[] childPosition = new int[2];child.getLocationOnScreen(childPosition);int left = childPosition[0];int right = left + child.getWidth();int top = childPosition[1];int bottom = top + child.getHeight();viewRect.set(left, top, right, bottom);return viewRect.contains((int) e.getRawX(), (int) e.getRawY());}};}
0 0
- 水平listview
- 水平ListView
- 水平listview
- 水平ListView
- Android 水平的ListView
- Android ListView 水平滑动
- 自定义水平ListView
- ListView的水平滑动
- react-native 水平ListView
- Android ListView item 水平滑动
- 水平方向滚动的listview
- Android 水平ListView的实现
- 自定义水平滑动的listview
- Android 水平numberpicker 以及水平listview的实现
- 实现水平ListView,并且解决水平ListView在ScrollView中Listview中出现的滑动冲突
- 类似于ListView的水平滚动View
- Android--ListView的item水平滑动效果
- listView水平滑动识别为单击事件
- Android学习之RecylerView完美实现瀑布流效果
- KMP算法
- 通过响应者链条完成控制器之间的跳转
- 例程6. MPU6050工程变量超出data区的解决办法 -- 慕司板IAP15
- TaskToApm源码
- 水平listview
- 算法杂货铺——分类算法之决策树(Decision tree)
- hdu2082 找单词 (母函数)
- MyBatis
- 20160403servlet学习笔记会话技术之cookie
- 依赖注入那些事儿
- 安卓中图片名称和id和drawable的互相关系
- hdu1521 排列组合(指数型母函数)
- 例程7. HMC5883工程说明 -- 慕司板IAP15