水平的ListVIEw-horizontallistVIEw的使用
AndroID中ListVIEw默认的是竖直方向的滑动,由于项目的需求,需要ListVIEw是水平滑动的。有很多的方式可以实现,但是比较好的一种方式就是自己封装一个控件,使用方式和ListVIEw的使用方式是一样的。需要完善的地方:获取到的图片大小没有处理。在界面上展示的是图片的原大小。为了更好的展示效果,应该压缩成统一的尺寸。
horizontallistVIEw.java 代码如下:
/** * 横向的ListVIEw * * * @author scd * */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); } @OverrIDe public voID setonItemSelectedListener( AdapterVIEw.OnItemSelectedListener Listener) { mOnItemSelected = Listener; } @OverrIDe public voID setonItemClickListener(AdapterVIEw.OnItemClickListener Listener) { mOnItemClicked = Listener; } @OverrIDe public voID setonItemLongClickListener( AdapterVIEw.OnItemLongClickListener Listener) { mOnItemLongClicked = 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() { @OverrIDe 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,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,left + chilDWIDth,child.getMeasuredHeight()); left += chilDWIDth + child.getpaddingRight(); } } } public synchronized voID scrollTo(int x) { mScroller.startScroll(mNextX,x - mNextX,0); requestLayout(); } @OverrIDe public 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,(int) -veLocityX,mMaxX,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,float veLocityY) { return horizontallistVIEw.this .onFling(e1,e2,veLocityX,veLocityY); } @OverrIDe public boolean onScroll(MotionEvent e1,float distanceX,float distanceY) { synchronized (horizontallistVIEw.this) { mNextX += (int) distanceX; } requestLayout(); return true; } @OverrIDe public 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,mAdapter.getItemID(mleftVIEwIndex + 1 + i)); } break; } } return true; } @OverrIDe public 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,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,bottom); return vIEwRect.contains((int) e.getRawX(),(int) e.getRawY()); } };}
适配器 horizontallistVIEwAdapter .java如下:
public class horizontallistVIEwAdapter extends BaseAdapter { /** 上下文 */ private Context mContext; /** 图像数据源 */ private ArrayList<Map<String,Integer>> mImageList; /** 数据源 */ private ArrayList<Map<String,Integer>> mTextList; /** Image */ private static String IMAGE = "ic_"; private Map<String,Integer> mMap = null; /** 构造方法 */ public horizontallistVIEwAdapter(Context context) { this.mContext = context; initData(); } /** 初始化数据 */ public voID initData() { mImageList = new ArrayList<Map<String,Integer>>(); /* * 反射技术 */ Class<?> imageClzz = R.drawable.class; R.drawable instance = new R.drawable(); // 取得drawable类中所有的字段 FIEld[] fIElds = imageClzz.getDeclaredFIElds(); for (FIEld fIEld : fIElds) { // 获得字段的名字 String name = fIEld.getname(); if (name != null && name.startsWith(IMAGE)) { try { mMap = new HashMap<String,Integer>(); mMap.put(IMAGE,(Integer) fIEld.get(instance)); mImageList.add(mMap); } catch (illegalaccessexception e) { e.printstacktrace(); } } } } @OverrIDe public int getCount() { return mImageList.size(); } @OverrIDe public Map<String,Integer> getItem(int position) { return mImageList == null ? null : mImageList.get(position); } @OverrIDe public long getItemID(int position) { return position; } @OverrIDe public VIEw getVIEw(int position,VIEw convertVIEw,VIEwGroup parent) { VIEwHolder holder; if (convertVIEw == null) { holder = new VIEwHolder(); convertVIEw = LayoutInflater.from(mContext).inflate( R.layout.horizontal_List_item,null); holder.mImage = (ImageVIEw) convertVIEw .findVIEwByID(R.ID.iv_List_item); holder.mTitle = (TextVIEw) convertVIEw .findVIEwByID(R.ID.tv_List_item); convertVIEw.setTag(holder); } else { holder = (VIEwHolder) convertVIEw.getTag(); } if (position == mSelectIndex) { convertVIEw.setSelected(true); } else { convertVIEw.setSelected(false); } holder.mImage.setimageResource(getItem(position).get(IMAGE)); return convertVIEw; } private class VIEwHolder { /** 图像 */ private ImageVIEw mImage; }}总结
以上是内存溢出为你收集整理的Android中实现水平滑动(横向滑动)ListView示例全部内容,希望文章能够帮你解决Android中实现水平滑动(横向滑动)ListView示例所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)