今天开源一个时间滑轮组件,在网上有各种开源比如wheel和其它改写,多多少少不够实用和缺陷。
该项目地址位于:https://github.com/apple317/displayview。
demo实现后效果图如上
1. 导入DisplayView(简称SDK)
下载最新版sdk的zip包,解压将其中的download释放到本地目录,Eclipse用户右键您的工程根目录,选择Properties -> Java Build Path -> Libraries, 然后点击 Add External JARs... 选择指向download 的路径,点击OK,即导入成功。
下载最新版SDK的zip包,将其中的libs 文件夹合并到本地工程libs子目录下
Eclipse用户右键工程根目录,选择Properties -> Java Build Path -> Libraries,然后点击Add External JARs... 选择指向jar的路径,点击OK,即导入成功。
注意。
2.代码接入详解使用说明:
在下载代码后,里面有参考代码,代码都有注释和调用详解,先讲解例子中RemFast调用类如何编写。
public class RemFast extends Activity { private LayoutInflater mInflater; private Context mcontext; private boolean wheelScrolled = false; // private DomobAdView mAdview320x50; private WheelView wheel_hours; private WheelView wheel_minute; private String remenderTime; private WheelView wheel_month; private WheelView wheel_day; private int beforeMonth = -1; private LinearLayout interGELinearLayout; public static final String[] HOUR_STRING = { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23" }; public static final String[] MINTUE_STRING = { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59" }; public static final String[] DAY_STRING = { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31" }; public static final String[] MONTH_STRING = { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12" }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_wheel); mcontext = this; mInflater = LayoutInflater.from(mcontext); createHead(); } /** * layout_remfast布局文件 * * * <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/lay_content" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp" > <!-- 布局添加一个滑轮视图--> <com.apple.disview.WheelView android:id="@+id/fast_month" android:layout_width="0dip" android:layout_height="100dp" android:layout_gravity="center_vertical" android:layout_weight="1.0" /> <com.apple.disview.WheelView android:id="@+id/fast_day" android:layout_width="0dip" android:layout_height="100dp" android:layout_gravity="center_vertical" android:layout_weight="1.0" /> <com.apple.disview.WheelView android:id="@+id/fast_hours" android:layout_width="0dip" android:layout_height="100dp" android:layout_gravity="center_vertical" android:layout_weight="1.0" /> <com.apple.disview.WheelView android:id="@+id/fast_mintue" android:layout_width="0dip" android:layout_height="100dp" android:layout_gravity="center_vertical" android:layout_weight="1.0" /> </LinearLayout> </LinearLayout> * * * */ private void createHead() { LinearLayout laymottom = (LinearLayout) findViewById(R.id.four_mottom); //创建一个滑轮子视图类 View mottom = mInflater.inflate(R.layout.layout_remfast, null); //初始化一个滑轮视图对象 wheel_month = (WheelView) mottom.findViewById(R.id.fast_month); //设置滑轮标记 wheel_month.setTag("month"); //设置滑轮数据集 wheel_month.setAdapter(new ArrayWheelAdapter<String>(MONTH_STRING)); //设置滑轮当前所在值 wheel_month.setCurrentItem(wheel_month.getCurrentVal("02")); //设置滑轮是否可以循环滑动 wheel_month.setCyclic(true); //设置滑轮标题 wheel_month.setLabel("月"); //添加滑轮变化监听事件 wheel_month.addChangingListener(wheelChangeListener); //添加滑轮滚动变化监听事件 wheel_month.addScrollingListener(wheelScrolledListener, null); wheel_day = (WheelView) mottom.findViewById(R.id.fast_day); wheel_day.setAdapter(new ArrayWheelAdapter<String>(DAY_STRING)); wheel_day.setCurrentItem(3); wheel_day.setLabel("天"); wheel_day.setTag("day"); wheel_day.setCyclic(true); wheel_day.addChangingListener(wheelChangeListener); wheel_day.addScrollingListener(wheelScrolledListener, null); wheel_hours = (WheelView) mottom.findViewById(R.id.fast_hours); wheel_hours.setAdapter(new ArrayWheelAdapter<String>(HOUR_STRING)); wheel_hours.setCyclic(true); wheel_hours.setTag("hours"); wheel_minute = (WheelView) mottom.findViewById(R.id.fast_mintue); wheel_minute.setAdapter(new ArrayWheelAdapter<String>(MINTUE_STRING)); wheel_minute.setCyclic(true); wheel_minute.setTag("minute"); wheel_minute.setLabel("分钟"); wheel_hours.setLabel("小时"); wheel_hours.setCurrentItem(1); wheel_minute.setCurrentItem(2); wheel_minute.addScrollingListener(wheelScrolledListener, null); wheel_minute.addChangingListener(wheelChangeListener); wheel_minute.addScrollingListener(wheelScrolledListener, null); wheel_hours.addChangingListener(wheelChangeListener); wheel_hours.addScrollingListener(wheelScrolledListener, null); wheel_hours.setleftCheck(true); wheel_minute.setleftCheck(true); wheel_day.setleftCheck(true); laymottom.addView(mottom); } OnWheelScrollListener wheelScrolledListener = new OnWheelScrollListener() { public void onScrollingStarted(WheelView wheel) { wheelScrolled = true; } @Override public void onScrollingFinished(WheelView wheel) { // TODO Auto-generated method stub String tag = wheel.getTag().toString(); wheelScrolled = false; } }; // Wheel changed listener private OnWheelChangedListener wheelChangeListener = new OnWheelChangedListener() { @Override public void onLayChanged(WheelView wheel, int oldValue, int newValue, LinearLayout layout) { // TODO Auto-generated method stub } }; }
4.WheelView组件核心代码详解如下:
WheelView实现核心原理就是创建一个视图View,通过监听手势和滑动事件得到滑动距离,并绘画StaticLayout视图显示日期值。
public class WheelView extends View { /** Scrolling duration */ private static final int SCROLLING_DURATION = 500; /** Minimum delta for scrolling */ private static final int MIN_DELTA_FOR_SCROLLING = 1; /** Current value & label text color */ private static final int VALUE_TEXT_COLOR = 0xF0000000; /** Items text color */ private static final int ITEMS_TEXT_COLOR = 0xFF000000; /** Top and bottom shadows colors */ private static final int[] SHADOWS_COLORS = new int[] { 0xFFfffbf7, 0xFFffebda, 0xFFffebd9 }; private static final int[] HSHADOWS_COLORS = new int[] { 0xFFe6e4e4, 0xFF7d7c7c, 0x5e5d5d }; private static final int[] BSHADOWS_COLORS = new int[] { 0x5e5d5d, 0xFF7d7c7c, 0xFFe6e4e4 }; /** Additional items height (is added to standard text item height) */ /** Text size */ private static float TEXT_SIZE = 24;// 24 /** Default count of visible items */ private static final int DEF_VISIBLE_ITEMS = 3; // Wheel Values private WheelAdapter adapter = null; private int currentItem = 0; // Widths private int itemsWidth = 0; private int labelWidth = 0; // Count of visible items private int visibleItems = DEF_VISIBLE_ITEMS; // Item height private int itemHeight = 0; // Text paints private TextPaint itemsPaint; private TextPaint valuePaint; // Layouts // private StaticLayout itemsLayout; private StaticLayout valueLayout; private StaticLayout srightLayout; private StaticLayout sleftLayout; // Label & background private String label; // Scrolling private boolean isScrollingPerformed; private int scrollingOffset; // Scrolling animation private GestureDetector gestureDetector; private Scroller scroller; private int lastScrollY; // Cyclic boolean isCyclic = true; // Listeners private List<OnWheelChangedListener> changingListeners = new LinkedList<OnWheelChangedListener>(); private List<OnWheelScrollListener> scrollingListeners = new LinkedList<OnWheelScrollListener>(); private Context mcontext; private onWheelClickListener wClick; private LinearLayout mlayout; private LinearLayout leftLayout; // type view private WheelView wview; private boolean single = false; private int mWidth; private int mHeight; private boolean leftCheck = false; /** * Constructor */ public WheelView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mcontext = context; initData(context); wview = this; } /** * Constructor */ public WheelView(Context context, AttributeSet attrs) { super(context, attrs); mcontext = context; initData(context); wview = this; } /** * Constructor */ public WheelView(Context context) { super(context); mcontext = context; initData(context); wview = this; } /** * Initializes class data * * @param context * the context */ private void initData(Context context) { gestureDetector = new GestureDetector(context, gestureListener); gestureDetector.setIsLongpressEnabled(false); scroller = new Scroller(context); } @Override protected void onFinishInflate() { // TODO Auto-generated method stub super.onFinishInflate(); // Log.i("ZYN", "--->getHeight()"+getHeight()); // } /** * Gets wheel adapter * * @return the adapter */ public WheelAdapter getAdapter() { return adapter; } /** * Sets wheel adapter * * @param adapter * the new wheel adapter */ public void setAdapter(WheelAdapter adapter) { this.adapter = adapter; invalidateLayouts(); invalidate(); } /** * Set the the specified scrolling interpolator * * @param interpolator * the interpolator */ public void setInterpolator(Interpolator interpolator) { scroller.forceFinished(true); scroller = new Scroller(getContext(), interpolator); } /** * Gets count of visible items * * @return the count of visible items */ public int getVisibleItems() { return visibleItems; } /** * Sets count of visible items * * @param count * the new count */ public void setVisibleItems(int count) { visibleItems = count; invalidate(); } /** * Gets label * * @return the label */ public String getLabel() { return label; } /** * Sets label * * @param newLabel * the label to set */ public void setLabel(String newLabel) { label = newLabel; } /** * Adds wheel changing listener * * @param listener * the listener */ public void addChangingListener(OnWheelChangedListener listener) { changingListeners.add(listener); } /** * Removes wheel changing listener * * @param listener * the listener */ public void removeChangingListener(OnWheelChangedListener listener) { changingListeners.remove(listener); } /** * Notifies changing listeners * * @param oldValue * the old wheel value * @param newValue * the new wheel value */ protected void notifyChangingListeners(int oldValue, int newValue) { for (OnWheelChangedListener listener : changingListeners) { listener.onLayChanged(this, oldValue, newValue, mlayout); } } /** * Adds wheel scrolling listener * * @param listener * the listener */ public void addScrollingListener(OnWheelScrollListener listener, GestureScrollView gs) { if (gs != null) gs.setGesture(gestureDetector); scrollingListeners.add(listener); } /** * Removes wheel scrolling listener * * @param listener * the listener */ public void removeScrollingListener(OnWheelScrollListener listener) { scrollingListeners.remove(listener); } /** * Notifies listeners about starting scrolling */ protected void notifyScrollingListenersAboutStart() { for (OnWheelScrollListener listener : scrollingListeners) { listener.onScrollingStarted(this); } } /** * Notifies listeners about ending scrolling */ protected void notifyScrollingListenersAboutEnd() { for (OnWheelScrollListener listener : scrollingListeners) { listener.onScrollingFinished(this); } } /** * Gets current value * * @return the current value */ public int getCurrentItem() { return currentItem; } /** * Sets the current item. Does nothing when index is wrong. * * @param index * the item index * @param animated * the animation flag */ public void setCurrentItem(int index, boolean animated) { if (adapter == null || adapter.getItemsCount() == 0) { return; // throw? } if (index < 0 || index >= adapter.getItemsCount()) { if (isCyclic) { while (index < 0) { index += adapter.getItemsCount(); } index %= adapter.getItemsCount(); } else { return; // throw? } } if (index != currentItem) { if (animated) { scroll(index - currentItem, SCROLLING_DURATION); } else { invalidateLayouts(); int old = currentItem; currentItem = index; notifyChangingListeners(old, currentItem); invalidate(); } } } /** * Sets the current item w/o animation. Does nothing when index is wrong. * * @param index * the item index */ public void setCurrentItem(int index) { setCurrentItem(index, false); } /** * Tests if wheel is cyclic. That means before the 1st item there is shown * the last one * * @return true if wheel is cyclic */ public boolean isCyclic() { return isCyclic; } /** * Set wheel cyclic flag * * @param isCyclic * the flag to set */ public void setCyclic(boolean isCyclic) { this.isCyclic = isCyclic; invalidate(); invalidateLayouts(); } /** * Invalidates layouts */ private void invalidateLayouts() { valueLayout = null; valueLayout = null; scrollingOffset = 0; } /** * Initializes resources */ private void initResourcesIfNecessary() { if (itemsPaint == null) { itemsPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.FAKE_BOLD_TEXT_FLAG); itemsPaint.setTextSize(TEXT_SIZE); itemsPaint.setTextAlign(Align.CENTER); } if (valuePaint == null) { valuePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.FAKE_BOLD_TEXT_FLAG | Paint.DITHER_FLAG); valuePaint.setTextSize(TEXT_SIZE); valuePaint.setShadowLayer(0.1f, 0, 0.1f, 0xFFC0C0C0); valuePaint.setTextAlign(Align.CENTER); } // setBackgroundResource(R.color.font_white); } /** * Returns text item by index * * @param index * the item index * @return the item or null */ private String getTextItem(int index) { if (adapter == null || adapter.getItemsCount() == 0) { return null; } int count = adapter.getItemsCount(); if ((index < 0 || index >= count) && !isCyclic) { return null; } else { while (index < 0) { index = count + index; } } index %= count; return adapter.getItem(index); } /** * Builds text depending on current value * * @param useCurrentValue * @return the text */ private String buildText(boolean useCurrentValue) { StringBuilder itemsText = new StringBuilder(); int addItems = visibleItems / 2 + 1; for (int i = currentItem - addItems; i <= currentItem + addItems; i++) { String text = getTextItem(i); if (text != null) { itemsText.append(text); } if (i < currentItem + addItems) { itemsText.append("\n"); } } return itemsText.toString(); } /** * Returns height of wheel item * * @return the item height */ private int getItemHeight() { if (itemHeight != 0) { return itemHeight; } else if (valueLayout != null && valueLayout.getLineCount() > 2) { itemHeight = valueLayout.getLineTop(2) - valueLayout.getLineTop(1); return itemHeight; } return getHeight() / visibleItems; } public int getCurrentVal(String itemVal) { int current = 0; for (int i = 0; i < adapter.getItemsCount(); i++) { if (getTextItem(i).equals(itemVal)) current = i; } return current; } /** * Creates layouts * * @param widthItems * width of items layout * @param widthLabel * width of label layout */ private void createLayouts() { String text = getAdapter() != null ? getAdapter().getItem(currentItem) : null; int itemHeight = (int) (mHeight / DEF_VISIBLE_ITEMS / 2 - TEXT_SIZE / 2); if (single) { sleftLayout = new StaticLayout("", valuePaint, 0, Layout.Alignment.ALIGN_CENTER, 1, 0.0F, false); valueLayout = new StaticLayout(buildText(isScrollingPerformed), valuePaint, this.getWidth() * 2 / 3, Layout.Alignment.ALIGN_NORMAL, 1, itemHeight * 2 - 4, false); srightLayout = new StaticLayout(label == null ? "" : label, valuePaint, this.getWidth() / 3, Layout.Alignment.ALIGN_CENTER, 1, itemHeight * 2 - 4, false); } else { sleftLayout = new StaticLayout("", valuePaint, this.getWidth() / 3, Layout.Alignment.ALIGN_CENTER, 1, 0.0F, false); valueLayout = new StaticLayout(buildText(isScrollingPerformed), valuePaint, this.getWidth() / 3, Layout.Alignment.ALIGN_NORMAL, 1, itemHeight * 2 - 4, false); srightLayout = new StaticLayout(label == null ? "" : label, valuePaint, this.getWidth() / 3, Layout.Alignment.ALIGN_CENTER, 1, itemHeight * 2 - 4, false); } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); initResourcesIfNecessary(); createLayouts(); drawValue(canvas); canvas.restore(); Rect r = new Rect(); Shader mShader = new LinearGradient(0, 0, 100, 100, SHADOWS_COLORS, new float[] { 0, 0.5f, 1.0f }, Shader.TileMode.CLAMP); Shader hCheckShader = new LinearGradient(0, 0, 100, 100, HSHADOWS_COLORS, new float[] { 0, 0.5f, 1.0f }, Shader.TileMode.CLAMP); Shader bCheckShader = new LinearGradient(0, 0, 100, 100, BSHADOWS_COLORS, new float[] { 0, 0.5f, 1.0f }, Shader.TileMode.CLAMP); Paint p = new Paint(); p.setAntiAlias(true); p.setShader(mShader); p.setAlpha(127); r.left = 0; r.top = mHeight / 3; r.right = r.left + this.getWidth(); r.bottom = mHeight / 3 + r.top; canvas.drawRect(r, p); if (leftCheck) { p.setShader(hCheckShader); p.setStyle(Paint.Style.FILL); Rect rCheck = new Rect(); rCheck.left = 0; rCheck.top = 0; rCheck.right = 1; rCheck.bottom = (r.bottom + mHeight / 3) / 2; canvas.drawRect(rCheck, p); p.setShader(bCheckShader); Rect bCheck = new Rect(); bCheck.left = 0; bCheck.top = (r.bottom + mHeight / 3) / 2; bCheck.right = 1; bCheck.bottom = r.bottom + mHeight / 3; canvas.drawRect(bCheck, p); // Paint rline = new Paint(); // rline.setStyle(Paint.Style.STROKE); // rline.setTextSkewX((float) 3.0); // rline.setColor(0xFFffd5b0); // canvas.drawLine(0,0,0,r.bottom+mHeight/3, rline);// } Paint pline = new Paint(); pline.setColor(0xFFffd5b0); pline.setStyle(Paint.Style.FILL); pline.setTextSkewX((float) 3.0); canvas.drawLine(0, r.top, r.right, r.top, pline); canvas.drawLine(0, r.bottom, r.right, r.bottom, pline);// canvas.drawLine(0, r.top, 0, r.bottom, pline);// canvas.drawLine(r.right, r.top, r.right, r.bottom, pline);// } /** * Draws value and label layout * * @param canvas * the canvas for drawing */ private void drawValue(Canvas canvas) { canvas.save(); valuePaint.setColor(VALUE_TEXT_COLOR); valuePaint.drawableState = getDrawableState(); int itemHeight = (int) (mHeight / DEF_VISIBLE_ITEMS / 2 - TEXT_SIZE / 2); Rect bounds = new Rect(); if (single) { if (sleftLayout != null) { canvas.save(); canvas.translate(0, bounds.top); sleftLayout.draw(canvas); canvas.restore(); } // // draw label if (srightLayout != null) { canvas.save(); canvas.translate((this.getWidth() / 3) * 2, itemHeight * 3 + TEXT_SIZE); srightLayout.draw(canvas); canvas.restore(); } // draw current value if (valueLayout != null) { canvas.save(); int top = valueLayout.getLineTop(1); //通过游标平移高度 //其实每次滑动后都会通过View重新绘画走到这里。 canvas.translate(this.getWidth() / 3 + (valueLayout.getWidth() / 11) * 2, -top + scrollingOffset + itemHeight); itemsPaint.setColor(ITEMS_TEXT_COLOR); itemsPaint.drawableState = getDrawableState(); valueLayout.draw(canvas); canvas.restore(); } } else { if (sleftLayout != null) { canvas.save(); canvas.translate(this.getWidth() / 4, bounds.top); sleftLayout.draw(canvas); canvas.restore(); } // draw label if (srightLayout != null) { canvas.save(); canvas.translate((this.getWidth() / 3) * 2, itemHeight * 3 + TEXT_SIZE); srightLayout.draw(canvas); canvas.restore(); } // draw current value if (valueLayout != null) { canvas.save(); int top = valueLayout.getLineTop(1); canvas.translate(this.getWidth() / 3 + (valueLayout.getWidth() / 11) * 5, -top + scrollingOffset + itemHeight); itemsPaint.setColor(ITEMS_TEXT_COLOR); itemsPaint.drawableState = getDrawableState(); valueLayout.draw(canvas); canvas.restore(); } } } @Override public boolean onTouchEvent(MotionEvent event) { WheelAdapter adapter = getAdapter(); if (adapter == null) { return true; } if (!gestureDetector.onTouchEvent(event) && event.getAction() == MotionEvent.ACTION_UP) justify(); return true; } /** * Scrolls the wheel * * @param delta * the scrolling value */ private void doScroll(int delta) { scrollingOffset += delta; int count = scrollingOffset / getItemHeight(); int pos = currentItem - count; if (isCyclic && adapter.getItemsCount() > 0) { // fix position by rotating while (pos < 0) { pos += adapter.getItemsCount(); } pos %= adapter.getItemsCount(); } else if (isScrollingPerformed) { // if (pos < 0) { count = currentItem; pos = 0; } else if (pos >= adapter.getItemsCount()) { count = currentItem - adapter.getItemsCount() + 1; pos = adapter.getItemsCount() - 1; } } else { // fix position pos = Math.max(pos, 0); pos = Math.min(pos, adapter.getItemsCount() - 1); } int offset = scrollingOffset; if (pos != currentItem) { setCurrentItem(pos, false); } else { invalidate(); } // update offset scrollingOffset = offset - count * getItemHeight(); if (scrollingOffset > getHeight()) { scrollingOffset = scrollingOffset % getHeight() + getHeight(); } } // gesture listener private SimpleOnGestureListener gestureListener = new SimpleOnGestureListener() { public boolean onDown(MotionEvent e) { if (wview.getTag() != null && wClick != null) wClick.onClick(wview.getTag()); if (isScrollingPerformed) { scroller.forceFinished(true); clearMessages(); return true; } return false; } public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { startScrolling(); doScroll((int) -distanceY); return true; } public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { lastScrollY = currentItem * getItemHeight() + scrollingOffset; int maxY = isCyclic ? 0x7FFFFFFF : adapter.getItemsCount() * getItemHeight(); int minY = isCyclic ? -maxY : 0; scroller.fling(0, lastScrollY, 0, (int) -velocityY / 2, 0, 0, minY, maxY); setNextMessage(MESSAGE_SCROLL); return true; } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return super.onSingleTapUp(e); } }; // Messages private final int MESSAGE_SCROLL = 0; private final int MESSAGE_JUSTIFY = 1; /** * Set next message to queue. Clears queue before. * * @param message * the message to set */ private void setNextMessage(int message) { clearMessages(); animationHandler.sendEmptyMessage(message); } /** * Clears messages from queue */ private void clearMessages() { animationHandler.removeMessages(MESSAGE_SCROLL); animationHandler.removeMessages(MESSAGE_JUSTIFY); } // animation handler private Handler animationHandler = new Handler() { public void handleMessage(Message msg) { scroller.computeScrollOffset(); int currY = scroller.getCurrY(); int delta = lastScrollY - currY; lastScrollY = currY; if (delta != 0) { doScroll(delta); } // scrolling is not finished when it comes to final Y // so, finish it manually if (Math.abs(currY - scroller.getFinalY()) < MIN_DELTA_FOR_SCROLLING) { currY = scroller.getFinalY(); scroller.forceFinished(true); } if (!scroller.isFinished()) { animationHandler.sendEmptyMessage(msg.what); } else if (msg.what == MESSAGE_SCROLL) { justify(); } else { finishScrolling(); } } }; /** * Justifies wheel */ private void justify() { if (adapter == null) { return; } lastScrollY = 0; int offset = scrollingOffset; int itemHeight = getItemHeight(); boolean needToIncrease = offset > 0 ? currentItem < adapter .getItemsCount() : currentItem > 0; if ((isCyclic || needToIncrease) && Math.abs((float) offset) > (float) itemHeight / 2) { if (offset < 0) offset += itemHeight + MIN_DELTA_FOR_SCROLLING; else offset -= itemHeight + MIN_DELTA_FOR_SCROLLING; } if (Math.abs(offset) > MIN_DELTA_FOR_SCROLLING) { scroller.startScroll(0, 0, 0, offset, SCROLLING_DURATION); setNextMessage(MESSAGE_JUSTIFY); } else { finishScrolling(); } } /** * Starts scrolling */ private void startScrolling() { if (!isScrollingPerformed) { isScrollingPerformed = true; notifyScrollingListenersAboutStart(); } } /** * Finishes scrolling */ void finishScrolling() { if (isScrollingPerformed) { notifyScrollingListenersAboutEnd(); isScrollingPerformed = false; } invalidateLayouts(); invalidate(); } /** * Scroll the wheel * * @param itemsToSkip * items to scroll * @param time * scrolling duration */ public void scroll(int itemsToScroll, int time) { scroller.forceFinished(true); lastScrollY = scrollingOffset; int offset = itemsToScroll * getItemHeight(); scroller.startScroll(0, lastScrollY, 0, offset - lastScrollY, time); setNextMessage(MESSAGE_SCROLL); startScrolling(); } public void setWheelClick(onWheelClickListener l) { wClick = l; } public void setSingle() { single = true; } public void setViewHeight(int height) { mHeight = height; } public void setleftCheck(boolean mleftCheck) { leftCheck = mleftCheck; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); final int heightSize = MeasureSpec.getSize(heightMeasureSpec); final int widthSize = MeasureSpec.getSize(widthMeasureSpec); mHeight =heightSize; setMeasuredDimension(widthSize, heightSize); } }