亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android中實現水平滑動(橫向滑動)ListView示例

2020-04-11 11:31:45
字體:
來源:轉載
供稿:網友

水平的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,          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();  }  @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, 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) {      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;    }    @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, 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());    }  };}

適配器 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;  }}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩av快播网址| 欧美大片在线影院| 青草青草久热精品视频在线观看| 欧美日韩亚洲高清| 色妞在线综合亚洲欧美| 91成人在线播放| 久久久久999| 日韩成人av网| 国产精品亚洲美女av网站| 中文字幕日韩欧美| 亚洲黄页视频免费观看| 69**夜色精品国产69乱| 国产精品成人v| 中文字幕日韩欧美精品在线观看| 国产91在线高潮白浆在线观看| 国产精品久久久久久av福利软件| 成人在线视频福利| 欧美一级大片视频| 日韩一级裸体免费视频| 久久久国产成人精品| 日韩在线观看免费高清| 91国语精品自产拍在线观看性色| 欧美性精品220| 久久成人在线视频| 欧美日韩电影在线观看| 久久九九国产精品怡红院| 国产aaa精品| 亚洲精品美女久久久| 欧美在线一区二区三区四| 久久久久久国产免费| 亚洲日韩欧美视频一区| 亚洲中国色老太| 日韩av免费在线看| 亚洲夜晚福利在线观看| 8050国产精品久久久久久| 国产不卡一区二区在线播放| 欧美巨大黑人极品精男| 国产成人精品网站| 午夜精品久久17c| 久久天天躁日日躁| 国产精品视频久久久久| 欧美不卡视频一区发布| 久久久伊人日本| 欧美精品久久久久久久免费观看| 青草青草久热精品视频在线观看| 色琪琪综合男人的天堂aⅴ视频| 日韩视频―中文字幕| 永久免费毛片在线播放不卡| 91精品国产91久久久久| 欧美最猛性xxxxx(亚洲精品)| 国产精品专区第二| 91久久精品国产91性色| 日韩欧美一区二区三区久久| 91夜夜揉人人捏人人添红杏| 久久精品美女视频网站| 日韩成人在线视频观看| 91精品国产高清自在线| 丁香五六月婷婷久久激情| 国产丝袜精品视频| 欧美性在线视频| 激情亚洲一区二区三区四区| 日韩精品视频在线| 国产欧美精品日韩精品| 国产91色在线免费| 亚洲自拍偷拍色片视频| 亚洲国产精品中文| 国产精品国产三级国产aⅴ9色| 欧美电影第一页| 亚洲欧美在线播放| 亚洲国产精品人人爽夜夜爽| 国产视频自拍一区| 日韩在线观看精品| 在线观看欧美日韩国产| 欧美视频国产精品| 亚洲欧美在线免费观看| 亚洲激情在线观看视频免费| 狠狠色狠狠色综合日日小说| 韩国v欧美v日本v亚洲| 国内伊人久久久久久网站视频| 欧美激情综合色综合啪啪五月| 久久久午夜视频| 亚洲国产精品小视频| 日韩在线播放视频| 日韩av电影在线网| 国产精品自产拍在线观看中文| 日韩av电影中文字幕| 日韩精品在线视频| 久久久久久久久亚洲| 日韩高清不卡av| 国外成人免费在线播放| 亚洲精品动漫久久久久| 国产精品露脸av在线| www.久久久久| 国产精品成av人在线视午夜片| 国产精品v日韩精品| 精品一区二区三区四区| 91国产精品视频在线| 国产精品精品久久久久久| 日韩电影免费观看在线观看| 国产精品视频yy9099| 亚洲综合精品伊人久久| 国产精品高潮视频| 久久久久久综合网天天| 综合国产在线视频| 在线观看国产欧美| 最近更新的2019中文字幕| 日韩美女视频免费看| 亚洲精品视频中文字幕| 一区二区成人精品| 在线播放国产一区二区三区| 国产日韩欧美91| 91在线无精精品一区二区| 亚洲精品美女在线| 亚洲欧洲av一区二区| 91av视频在线播放| 国产欧美va欧美va香蕉在| 久久高清视频免费| 日韩视频免费中文字幕| 97国产精品视频人人做人人爱| 精品美女永久免费视频| 欧美性生交大片免网| 亚洲精品福利在线观看| 国产精品久久久久久久久久久新郎| 久久成人综合视频| 日韩中文字幕在线| 两个人的视频www国产精品| 精品国产电影一区| 久久男人资源视频| 成人网在线免费观看| 亚洲影院高清在线| 亚洲精品免费一区二区三区| 午夜欧美大片免费观看| 亚洲网站在线播放| 欧美日韩国产123| 欧美在线中文字幕| 日韩在线观看免费全| 97视频在线看| 国产视频精品va久久久久久| 国产精品入口免费视频一| 97av在线视频| 中文字幕亚洲欧美日韩在线不卡| 久久久久久国产精品美女| 国产在线观看91精品一区| 岛国精品视频在线播放| 国产一区二区三区日韩欧美| 亚洲国产精品热久久| 欧美有码在线视频| 51视频国产精品一区二区| 国产精品第2页| 成人精品久久一区二区三区| 久久夜色精品国产| 亚洲国产精品人久久电影| 色爱精品视频一区| 久久人人爽人人爽人人片av高请| 久久频这里精品99香蕉| 国产精品视频久久久久| 亚洲色无码播放| 色午夜这里只有精品| 中文字幕精品久久久久| 亚洲欧美国产精品va在线观看| 亚洲欧洲第一视频| 国产视频自拍一区| 午夜精品久久久99热福利| 亚洲一品av免费观看|