当前位置:操作系统 > 安卓/Android >>

Android自定义垂直滚动自动选择日期控件

   项目中需要一个日期选择控件,该日期选择控件是垂直滚动,停止滚动时需要校正日期数字位置,自动选择离中心位置最近的数字。效果如下:
 
 
 
     利用继承LinearLayout实现,模仿Android带数据的控件的一般做法,加入适配器接口,选择事件监听接口,另外简单实现了子View的缓存,对应这样简单应用的情况下,应该是可以的,本人只用过TextView来做子控件,其他适配尚未测试,不知道效果如何。可能有其他的应用场景,分享给各位,可以修改或应用于你自己的项目。
 
 
下面贴代码,有点长O(∩_∩)O~:
 
 
/** 
 * 内容垂直滚动的一个控件,内容子项项垂直滚动后,将自动把当前离中心最近的项回滚至中心位置。 
 * 可根据{@link #getSelectedItem()} 获取当前选择的项,另外可添加选中事件监听器 
 * {@link #setOnItemSelectedListener(OnItemSelectedListener)} 
 *  
 * This component may contains several sub items, and the items are able to 
 * scroll up and down, by once released the scroll bar, the closest item will 
 * roll back to the center of component. use {@link #getSelectedItem()} to  
 * get the current selected item, and you can always use  
 * {@link #setOnItemSelectedListener(OnItemSelectedListener)} to do something 
 * after the item is selected. 
 *  
 * @date 2013/09/26 
 * @author Wison 
 * 
 */  
public class VerticalScrollAutoSelector extends LinearLayout {  
  
    private ScrollView mContentScrollView;  
    private OnItemSelectedListener mOnItemSelectedListener;  
      
    private AutoSelectorAdapter mAdapter;  
    private LinearLayout mItemsContainer;  
    private ViewGroup.LayoutParams mItemLayoutParams;  
    private TextView mStartBlankView;  
    private TextView mEndBlankView;  
    private List<View> mCachedSubViewList = new ArrayList<View>();  
      
    private int[] mItemViewsScrollYArr;  
    private Point mTouchedPoint = new Point();  
    private ScrollPointChecker mScrollPointChecker;  
    private int mSelectedPosition = -1;  
      
    public VerticalScrollAutoSelector(Context context) {  
        this(context, null);  
    }  
  
    @SuppressWarnings("deprecation")  
    public VerticalScrollAutoSelector(Context context, AttributeSet attrs) {  
        super(context, attrs);  
          
        mContentScrollView = new ScrollView(context);  
        LinearLayout.LayoutParams linearLP = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);  
        mContentScrollView.setLayoutParams(linearLP);  
        mContentScrollView.setVerticalScrollBarEnabled(false);  
        addView(mContentScrollView);  
          
        mStartBlankView = new TextView(context);  
        mEndBlankView = new TextView(context);  
        mItemLayoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);  
        mItemsContainer = new LinearLayout(context);  
        mItemsContainer.setOrientation(LinearLayout.VERTICAL);  
        mItemsContainer.setGravity(Gravity.CENTER);  
        mItemsContainer.setLayoutParams(mItemLayoutParams);  
        mContentScrollView.addView(mItemsContainer);  
        mContentScrollView.setOnTouchListener(new ScrollViewOnTouchListener());  
    }  
      
    /** 
     * Register a callback to be invoked when an item in this VerticalScrollAutoSelector has been selected. 
     * @param listener The callback that will run 
     */  
    public void setOnItemSelectedListener(OnItemSelectedListener listener) {  
        mOnItemSelectedListener = listener;  
    }  
      
    /** 
     * Sets the data behind this VerticalScrollAutoSelector. 
     * @param adapter 
     */  
    public void setAdapter(AutoSelectorAdapter adapter) {  
        mAdapter = adapter;  
        mSelectedPosition = -1;  
        mItemViewsScrollYArr = null;  
        mItemsContainer.removeAllViews();  
        if (mAdapter == null || mAdapter.getCount() <= 0) {  
            return;  
        }  
          
        if (getHeight() == 0) {  
            // Waiting for component initialization finished  
            postDelayed(new Thread() {  
                @Override  
                public void run() {  
                    attachAdapter();  
                }  
            }, 1);  
        } else {  
            attachAdapter();  
        }  
    }  
      
    private void attachAdapter() {  
        if (getHeight() == 0) {  
            // try again!  
            setAdapter(mAdapter);  
            return;  
        }  
          
        final int itemCount = mAdapter.getCount();  
        int itemGroup = mAdapter.getItemsCountPerGroup();  
        if (itemGroup < 3) {  
            itemGroup = 3;  
        }  
  
        final float height = getHeight();  
          
        final int itemHeight = (int) (height / itemGroup);  
        int additionHeight = (int) (height - itemHeight * itemGroup);  
          
        int itemPosition = 0;  
        final int totalItems = itemCount + 2;  
          
        for (int i = 0; i < totalItems; i++) {  
              
            if (i == 0 || i == totalItems - 1) {  
                TextView tv = (i == 0 ? mStartBlankView : mEndBlankView);  
                mItemLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;  
                mItemLayoutParams.height = (--additionHeight >= 0) ? itemHeight + 1 : itemHeight;  
                tv.setLayoutParams(mItemLayoutParams);  
                mItemsContainer.addView(tv);  
            } else {  
                View convertView = null;  
                boolean isCached = true;  
                if (itemPosition < mCachedSubViewList.size()) {  
                    convertView = mCachedSubViewList.get(itemPosition);  
                } else {  
                    isCached = false;  
                }  
                  
                View view = mAdapter.getView(itemPosition, convertView, this);  
                view.setId(mAdapter.getItemId(itemPosition));  
                mItemLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;  
                mItemLayoutParams.height = (--additionHeight >= 0) ? itemHeight + 1 : itemHeight;  
                view.setLayoutParams(mItemLayoutParams);  
                mItemsContainer.addView(view);  
                  
                if (!isCached) {  
                    mCachedSubViewList.add(itemPosition, view);  
                } else {  
                    if (view != convertView) {  
                        mCachedSubViewList.remove(itemPosition);  
                        mCachedSubViewList.add(itemPosition, view);  
                    }  
                }  
                itemPosition++;  
            }  
        }  
    }   
      
      
    /** 
     * Returns the adapter currently in use in this VerticalScrollAutoSelector. 
     * @return 
     */  
    public AutoSelectorAdapter getAdapter() {  
        return mAdapter;  
    }  
      
    /** 
     * Get the selected item. 
     * @return 
     */  
    public Object getSelectedItem() {  
        if (mAdapter == null || mSelectedPosition < 0) return null;   
        return mAdapter.getItem(mSelectedPosition);  
    }  
      
      
    private class ScrollViewOnTouchListener implements OnTouchListener {  
          
        @Override  
        public boolean onTouch(View v, MotionEvent event) {  
            if (mAdapter == null || mAdapter.getCount() < 1) {  
                return false;  
            }  
              
            switch (event.getAction()) {  
            case MotionEvent.ACTION_DOWN:  
                if (mItemViewsScrollYArr == null) {  
                    int maxY = getMaxScrollY();  
                      
                    final int itemsCount = getAdapter().getCount();  
                    mItemViewsScrollYArr = new int[itemsCount];  
                    mItemViewsScrollYArr[0] = 0;  
补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,