今天开源一个时间滑轮组件,在网上有各种开源比如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布局文件
*
*
*
*
*
*
*/
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(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(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(HOUR_STRING));
wheel_hours.setCyclic(true);
wheel_hours.setTag("hours");
wheel_minute = (WheelView) mottom.findViewById(R.id.fast_mintue);
wheel_minute.setAdapter(new ArrayWheelAdapter(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 changingListeners = new LinkedList();
private List scrollingListeners = new LinkedList();
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);
}
}