a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 系統 > 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在线官网 | 国产成人a亚洲精品 | 国产精品久久久久久久久久久久久久久久久 | 成人免费观看cn | 午夜精品久久久 | 国产成人精品一区二 | 99爱免费观看国语 | 在线免费观看羞羞视频 | 国产高清不卡一区二区三区 | 欧美一区二区三区免费 | 欧美三级免费观看 | av水蜜桃 | 一区综合 | 久久亚洲国产视频 | av直接看 | 欧美午夜精品久久久久免费视 | 精品国产一区二区三区在线观看 | 中国免费看的片 | 国产日韩在线视频 | 成人av影片在线观看 | 久久成人综合 | 欧美日本韩国一区二区 | 久久综合影院 | 国产精品二区三区 | 中文字幕一区二区三区在线视频 | www.久久.com | 欧美精品免费在线观看 | 久久久久国产一级毛片高清版小说 | 欧美一区二区三 | 国产精品久久久久久久久久东京 | 欧美午夜精品一区二区三区电影 | 一区二区在线免费观看 | 在线欧美一区 | 天天爽天天草 | 麻豆视频国产 | 日韩aⅴ一区二区三区 | 草草网| 国产精品久久精品 | 欧美一性一交 | 三级视频在线观看 |