Android UI开发: 横向ListView(HorizontalListView)及一个简单相册的完整实现 (附源码下载)

来源:互联网 发布:html可视化编程软件 编辑:程序博客网 时间:2024/04/25 08:37
package org.com.cctest.adapter;  02.  03.import java.util.ArrayList;  04.import java.util.List;  05.  06.import org.com.cctest.R;  07.import org.com.cctest.bean.VideoBean;  08.import android.content.Context;  09.import android.view.LayoutInflater;  10.import android.view.View;  11.import android.view.ViewGroup;  12.import android.widget.BaseAdapter;  13.import android.widget.ImageView;  14.import android.widget.TextView;  15.  16.public class HorizontalListViewAdapter extends BaseAdapter{  17.  18.    public HorizontalListViewAdapter(Context con){  19.        mInflater=LayoutInflater.from(con);  20.    }  21.    @Override  22.    public int getCount() {  23.        return 5;  24.    }  25.    private LayoutInflater mInflater;  26.    @Override  27.    public Object getItem(int position) {  28.        return position;  29.    }  30.    private ViewHolder vh    =new ViewHolder();  31.    private static class ViewHolder {  32.        private TextView time ;  33.        private TextView title ;  34.        private ImageView im;  35.    }  36.    @Override  37.    public long getItemId(int position) {  38.        return position;  39.    }  40.  41.    @Override  42.    public View getView(int position, View convertView, ViewGroup parent) {  43.        if(convertView==null){  44.            convertView = mInflater.inflate(R.layout.horizontallistview_item, null);  45.            vh.im=(ImageView)convertView.findViewById(R.id.iv_pic);  46.            vh.time=(TextView)convertView.findViewById(R.id.tv_time);  47.            vh.title=(TextView)convertView.findViewById(R.id.tv_name);  48.            convertView.setTag(vh);  49.        }else{  50.            vh=(ViewHolder)convertView.getTag();  51.        }  52.        vh.time.setText("00:00");  53.        vh.title.setText("XXXXXX");  54.        return convertView;  55.    }  56.}  

http://blog.csdn.net/yanzi1225627/article/details/21294553
package org.com.cctest.listview;  02.  03./* 04. * HorizontalListView.java v1.5 05. * 06. *  07. * The MIT License 08. * Copyright (c) 2011 Paul Soucy (paul@dev-smart.com) 09. *  10. * Permission is hereby granted, free of charge, to any person obtaining a copy 11. * of this software and associated documentation files (the "Software"), to deal 12. * in the Software without restriction, including without limitation the rights 13. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14. * copies of the Software, and to permit persons to whom the Software is 15. * furnished to do so, subject to the following conditions: 16. *  17. * The above copyright notice and this permission notice shall be included in 18. * all copies or substantial portions of the Software. 19. *  20. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26. * THE SOFTWARE. 27. * 28. */  29.  30.  31.import java.util.LinkedList;  32.import java.util.Queue;  33.  34.import android.content.Context;  35.import android.database.DataSetObserver;  36.import android.graphics.Rect;  37.import android.util.AttributeSet;  38.import android.view.GestureDetector;  39.import android.view.GestureDetector.OnGestureListener;  40.import android.view.MotionEvent;  41.import android.view.View;  42.import android.widget.AdapterView;  43.import android.widget.ListAdapter;  44.import android.widget.Scroller;  45.  46.public class HorizontalListView extends AdapterView<ListAdapter> {  47.  48.    public boolean mAlwaysOverrideTouch = true;  49.    protected ListAdapter mAdapter;  50.    private int mLeftViewIndex = -1;  51.    private int mRightViewIndex = 0;  52.    protected int mCurrentX;  53.    protected int mNextX;  54.    private int mMaxX = Integer.MAX_VALUE;  55.    private int mDisplayOffset = 0;  56.    protected Scroller mScroller;  57.    private GestureDetector mGesture;  58.    private Queue<View> mRemovedViewQueue = new LinkedList<View>();  59.    private OnItemSelectedListener mOnItemSelected;  60.    private OnItemClickListener mOnItemClicked;  61.    private OnItemLongClickListener mOnItemLongClicked;  62.    private boolean mDataChanged = false;  63.      64.  65.    public HorizontalListView(Context context, AttributeSet attrs) {  66.        super(context, attrs);  67.        initView();  68.    }  69.      70.    private synchronized void initView() {  71.        mLeftViewIndex = -1;  72.        mRightViewIndex = 0;  73.        mDisplayOffset = 0;  74.        mCurrentX = 0;  75.        mNextX = 0;  76.        mMaxX = Integer.MAX_VALUE;  77.        mScroller = new Scroller(getContext());  78.        mGesture = new GestureDetector(getContext(), mOnGesture);  79.    }  80.      81.    @Override  82.    public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener) {  83.        mOnItemSelected = listener;  84.    }  85.      86.    @Override  87.    public void setOnItemClickListener(AdapterView.OnItemClickListener listener){  88.        mOnItemClicked = listener;  89.    }  90.      91.    @Override  92.    public void setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener) {  93.        mOnItemLongClicked = listener;  94.    }  95.  96.    private DataSetObserver mDataObserver = new DataSetObserver() {  97.  98.        @Override  99.        public void onChanged() {  100.            synchronized(HorizontalListView.this){  101.                mDataChanged = true;  102.            }  103.            invalidate();  104.            requestLayout();  105.        }  106.  107.        @Override  108.        public void onInvalidated() {  109.            reset();  110.            invalidate();  111.            requestLayout();  112.        }  113.          114.    };  115.  116.    @Override  117.    public ListAdapter getAdapter() {  118.        return mAdapter;  119.    }  120.  121.    @Override  122.    public View getSelectedView() {  123.        //TODO: implement  124.        return null;  125.    }  126.  127.    @Override  128.    public void setAdapter(ListAdapter adapter) {  129.        if(mAdapter != null) {  130.            mAdapter.unregisterDataSetObserver(mDataObserver);  131.        }  132.        mAdapter = adapter;  133.        mAdapter.registerDataSetObserver(mDataObserver);  134.        reset();  135.    }  136.      137.    private synchronized void reset(){  138.        initView();  139.        removeAllViewsInLayout();  140.        requestLayout();  141.    }  142.  143.    @Override  144.    public void setSelection(int position) {  145.        //TODO: implement  146.    }  147.      148.    private void addAndMeasureChild(final View child, int viewPos) {  149.        LayoutParams params = child.getLayoutParams();  150.        if(params == null) {  151.            params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);  152.        }  153.  154.        addViewInLayout(child, viewPos, params, true);  155.        child.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),  156.                MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));  157.    }  158.      159.      160.  161.    @Override  162.    protected synchronized void onLayout(boolean changed, int left, int top, int right, int bottom) {  163.        super.onLayout(changed, left, top, right, bottom);  164.  165.        if(mAdapter == null){  166.            return;  167.        }  168.          169.        if(mDataChanged){  170.            int oldCurrentX = mCurrentX;  171.            initView();  172.            removeAllViewsInLayout();  173.            mNextX = oldCurrentX;  174.            mDataChanged = false;  175.        }  176.  177.        if(mScroller.computeScrollOffset()){  178.            int scrollx = mScroller.getCurrX();  179.            mNextX = scrollx;  180.        }  181.          182.        if(mNextX <= 0){  183.            mNextX = 0;  184.            mScroller.forceFinished(true);  185.        }  186.        if(mNextX >= mMaxX) {  187.            mNextX = mMaxX;  188.            mScroller.forceFinished(true);  189.        }  190.          191.        int dx = mCurrentX - mNextX;  192.          193.        removeNonVisibleItems(dx);  194.        fillList(dx);  195.        positionItems(dx);  196.          197.        mCurrentX = mNextX;  198.          199.        if(!mScroller.isFinished()){  200.            post(new Runnable(){  201.                @Override  202.                public void run() {  203.                    requestLayout();  204.                }  205.            });  206.              207.        }  208.    }  209.      210.    private void fillList(final int dx) {  211.        int edge = 0;  212.        View child = getChildAt(getChildCount()-1);  213.        if(child != null) {  214.            edge = child.getRight();  215.        }  216.        fillListRight(edge, dx);  217.          218.        edge = 0;  219.        child = getChildAt(0);  220.        if(child != null) {  221.            edge = child.getLeft();  222.        }  223.        fillListLeft(edge, dx);  224.          225.          226.    }  227.      228.    private void fillListRight(int rightEdge, final int dx) {  229.        while(rightEdge + dx < getWidth() && mRightViewIndex < mAdapter.getCount()) {  230.              231.            View child = mAdapter.getView(mRightViewIndex, mRemovedViewQueue.poll(), this);  232.            addAndMeasureChild(child, -1);  233.            rightEdge += child.getMeasuredWidth();  234.              235.            if(mRightViewIndex == mAdapter.getCount()-1) {  236.                mMaxX = mCurrentX + rightEdge - getWidth();  237.            }  238.              239.            if (mMaxX < 0) {  240.                mMaxX = 0;  241.            }  242.            mRightViewIndex++;  243.        }  244.          245.    }  246.      247.    private void fillListLeft(int leftEdge, final int dx) {  248.        while(leftEdge + dx > 0 && mLeftViewIndex >= 0) {  249.            View child = mAdapter.getView(mLeftViewIndex, mRemovedViewQueue.poll(), this);  250.            addAndMeasureChild(child, 0);  251.            leftEdge -= child.getMeasuredWidth();  252.            mLeftViewIndex--;  253.            mDisplayOffset -= child.getMeasuredWidth();  254.        }  255.    }  256.      257.    private void removeNonVisibleItems(final int dx) {  258.        View child = getChildAt(0);  259.        while(child != null && child.getRight() + dx <= 0) {  260.            mDisplayOffset += child.getMeasuredWidth();  261.            mRemovedViewQueue.offer(child);  262.            removeViewInLayout(child);  263.            mLeftViewIndex++;  264.            child = getChildAt(0);  265.              266.        }  267.          268.        child = getChildAt(getChildCount()-1);  269.        while(child != null && child.getLeft() + dx >= getWidth()) {  270.            mRemovedViewQueue.offer(child);  271.            removeViewInLayout(child);  272.            mRightViewIndex--;  273.            child = getChildAt(getChildCount()-1);  274.        }  275.    }  276.      277.    private void positionItems(final int dx) {  278.        if(getChildCount() > 0){  279.            mDisplayOffset += dx;  280.            int left = mDisplayOffset;  281.            for(int i=0;i<getChildCount();i++){  282.                View child = getChildAt(i);  283.                int childWidth = child.getMeasuredWidth();  284.                child.layout(left, 0, left + childWidth, child.getMeasuredHeight());  285.                left += childWidth + child.getPaddingRight();  286.            }  287.        }  288.    }  289.      290.    public synchronized void scrollTo(int x) {  291.        mScroller.startScroll(mNextX, 0, x - mNextX, 0);  292.        requestLayout();  293.    }  294.      295.    @Override  296.    public boolean dispatchTouchEvent(MotionEvent ev) {  297.        boolean handled = super.dispatchTouchEvent(ev);  298.        handled |= mGesture.onTouchEvent(ev);  299.        return handled;  300.    }  301.      302.    protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  303.                float velocityY) {  304.        synchronized(HorizontalListView.this){  305.            mScroller.fling(mNextX, 0, (int)-velocityX, 0, 0, mMaxX, 0, 0);  306.        }  307.        requestLayout();  308.          309.        return true;  310.    }  311.      312.    protected boolean onDown(MotionEvent e) {  313.        mScroller.forceFinished(true);  314.        return true;  315.    }  316.      317.    private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() {  318.  319.        @Override  320.        public boolean onDown(MotionEvent e) {  321.            return HorizontalListView.this.onDown(e);  322.        }  323.  324.        @Override  325.        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  326.                float velocityY) {  327.            return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY);  328.        }  329.  330.        @Override  331.        public boolean onScroll(MotionEvent e1, MotionEvent e2,  332.                float distanceX, float distanceY) {  333.              334.            synchronized(HorizontalListView.this){  335.                mNextX += (int)distanceX;  336.            }  337.            requestLayout();  338.              339.            return true;  340.        }  341.  342.        @Override  343.        public boolean onSingleTapConfirmed(MotionEvent e) {  344.            for(int i=0;i<getChildCount();i++){  345.                View child = getChildAt(i);  346.                if (isEventWithinView(e, child)) {  347.                    if(mOnItemClicked != null){  348.                        mOnItemClicked.onItemClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));  349.                    }  350.                    if(mOnItemSelected != null){  351.                        mOnItemSelected.onItemSelected(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));  352.                    }  353.                    break;  354.                }  355.                  356.            }  357.            return true;  358.        }  359.          360.        @Override  361.        public void onLongPress(MotionEvent e) {  362.            int childCount = getChildCount();  363.            for (int i = 0; i < childCount; i++) {  364.                View child = getChildAt(i);  365.                if (isEventWithinView(e, child)) {  366.                    if (mOnItemLongClicked != null) {  367.                        mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));  368.                    }  369.                    break;  370.                }  371.  372.            }  373.        }  374.  375.        private boolean isEventWithinView(MotionEvent e, View child) {  376.            Rect viewRect = new Rect();  377.            int[] childPosition = new int[2];  378.            child.getLocationOnScreen(childPosition);  379.            int left = childPosition[0];  380.            int right = left + child.getWidth();  381.            int top = childPosition[1];  382.            int bottom = top + child.getHeight();  383.            viewRect.set(left, top, right, bottom);  384.            return viewRect.contains((int) e.getRawX(), (int) e.getRawY());  385.        }  386.    };  387.  388.      389.  390.}  

0 0