




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】android如何實現(xiàn)仿iphone滾輪控件顯示效果
這篇文章主要為大家展示了“android如何實現(xiàn)仿iphone滾輪控件顯示效果”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓在下帶領(lǐng)大家一起研究并學(xué)習(xí)一下“android如何實現(xiàn)仿iphone滾輪控件顯示效果”這篇文章吧。具體內(nèi)容如下在論壇里看到的,自己弄個效果:這個滾動的WheelView
/*
*
Android
Wheel
Control.
*
/p/android-wheel/
*
*
Copyright
2010
Yuri
Kanivets
*
*
Licensed
under
the
Apache
License,
Version
2.0
(the
"License");
*
you
may
not
use
this
file
except
in
compliance
with
the
License.
*
You
may
obtain
a
copy
of
the
License
at
*
*
/licenses/LICENSE-2.0
*
*
Unless
required
by
applicable
law
or
agreed
to
in
writing,
software
*
distributed
under
the
License
is
distributed
on
an
"AS
IS"
BASIS,
*
WITHOUT
WARRANTIES
OR
CONDITIONS
OF
ANY
KIND,
either
express
or
implied.
*
See
the
License
for
the
specific
language
governing
permissions
and
*
limitations
under
the
License.
*/
package
kankan.wheel.widget;
import
java.util.LinkedList;
import
java.util.List;
import
android.content.Context;
import
android.graphics.Canvas;
import
android.graphics.Paint;
import
android.graphics.Rect;
import
android.graphics.drawable.Drawable;
import
android.graphics.drawable.GradientDrawable;
import
android.graphics.drawable.GradientDrawable.Orientation;
import
android.os.Handler;
import
android.os.Message;
import
android.text.Layout;
import
android.text.StaticLayout;
import
android.text.TextPaint;
import
android.util.AttributeSet;
import
android.util.FloatMath;
import
android.view.GestureDetector;
import
android.view.GestureDetector.SimpleOnGestureListener;
import
android.view.MotionEvent;
import
android.view.View;
import
android.view.animation.Interpolator;
import
android.widget.Scroller;
import
com.shao.pwd.R;
/**
*
Numeric
wheel
view.
*
*
@author
Yuri
Kanivets
*/
public
class
WheelView
extends
View
{
/**
Scrolling
duration
*/
private
static
final
int
SCROLLING_DURATION
=
400;
/**
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[]
{
0xFF111111,
0x00AAAAAA,
0x00AAAAAA
};
/**
Additional
items
height
(is
added
to
standard
text
item
height)
*/
private
static
final
int
ADDITIONAL_ITEM_HEIGHT
=
15;
/**
Text
size
*/
private
static
final
int
TEXT_SIZE
=
24;
/**
Top
and
bottom
items
offset
(to
hide
that)
*/
private
static
final
int
ITEM_OFFSET
=
TEXT_SIZE
/
5;
/**
Additional
width
for
items
layout
*/
private
static
final
int
ADDITIONAL_ITEMS_SPACE
=
10;
/**
Label
offset
*/
private
static
final
int
LABEL_OFFSET
=
8;
/**
Left
and
right
padding
value
*/
private
static
final
int
PADDING
=
10;
/**
Default
count
of
visible
items
*/
private
static
final
int
DEF_VISIBLE_ITEMS
=
5;
//
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
labelLayout;
private
StaticLayout
valueLayout;
//
Label
&
background
private
String
label;
private
Drawable
centerDrawable;
//
Shadows
drawables
private
GradientDrawable
topShadow;
private
GradientDrawable
bottomShadow;
//
Scrolling
private
boolean
isScrollingPerformed;
private
int
scrollingOffset;
//
Scrolling
animation
private
GestureDetector
gestureDetector;
private
Scroller
scroller;
private
int
lastScrollY;
//
Cyclic
boolean
isCyclic
=
false;
//
Listeners
private
List<OnWheelChangedListener>
changingListeners
=
new
LinkedList<OnWheelChangedListener>();
private
List<OnWheelScrollListener>
scrollingListeners
=
new
LinkedList<OnWheelScrollListener>();
/**
*
Constructor
*/
public
WheelView(Context
context,
AttributeSet
attrs,
int
defStyle)
{
super(context,
attrs,
defStyle);
initData(context);
}
/**
*
Constructor
*/
public
WheelView(Context
context,
AttributeSet
attrs)
{
super(context,
attrs);
initData(context);
}
/**
*
Constructor
*/
public
WheelView(Context
context)
{
super(context);
initData(context);
}
/**
*
Initializes
class
data
*
@param
context
the
context
*/
private
void
initData(Context
context)
{
gestureDetector
=
new
GestureDetector(context,
gestureListener);
gestureDetector.setIsLongpressEnabled(false);
scroller
=
new
Scroller(context);
}
/**
*
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)
{
if
(label
==
null
||
!label.equals(newLabel))
{
label
=
newLabel;
labelLayout
=
null;
invalidate();
}
}
/**
*
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.onChanged(this,
oldValue,
newValue);
}
}
/**
*
Adds
wheel
scrolling
listener
*
@param
listener
the
listener
*/
public
void
addScrollingListener(OnWheelScrollListener
listener)
{
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()
{
itemsLayout
=
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.density
=
getResources().getDisplayMetrics().density;
itemsPaint.setTextSize(TEXT_SIZE);
}
if
(valuePaint
==
null)
{
valuePaint
=
new
TextPaint(Paint.ANTI_ALIAS_FLAG
|
Paint.FAKE_BOLD_TEXT_FLAG
|
Paint.DITHER_FLAG);
//valuePaint.density
=
getResources().getDisplayMetrics().density;
valuePaint.setTextSize(TEXT_SIZE);
valuePaint.setShadowLayer(0.1f,
0,
0.1f,
0xFFC0C0C0);
}
if
(centerDrawable
==
null)
{
centerDrawable
=
getContext().getResources().getDrawable(R.drawable.wheel_val);
}
if
(topShadow
==
null)
{
topShadow
=
new
GradientDrawable(Orientation.TOP_BOTTOM,
SHADOWS_COLORS);
}
if
(bottomShadow
==
null)
{
bottomShadow
=
new
GradientDrawable(Orientation.BOTTOM_TOP,
SHADOWS_COLORS);
}
setBackgroundResource(R.drawable.wheel_bg);
}
/**
*
Calculates
desired
height
for
layout
*
*
@param
layout
*
the
source
layout
*
@return
the
desired
layout
height
*/
private
int
getDesiredHeight(Layout
layout)
{
if
(layout
==
null)
{
return
0;
}
int
desired
=
getItemHeight()
*
visibleItems
-
ITEM_OFFSET
*
2
-
ADDITIONAL_ITEM_HEIGHT;
//
Check
against
our
minimum
height
desired
=
Math.max(desired,
getSuggestedMinimumHeight());
return
desired;
}
/**
*
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++)
{
if
(useCurrentValue
||
i
!=
currentItem)
{
String
text
=
getTextItem(i);
if
(text
!=
null)
{
itemsText.append(text);
}
}
if
(i
<
currentItem
+
addItems)
{
itemsText.append("\n");
}
}
return
itemsText.toString();
}
/**
*
Returns
the
max
item
length
that
can
be
present
*
@return
the
max
length
*/
private
int
getMaxTextLength()
{
WheelAdapter
adapter
=
getAdapter();
if
(adapter
==
null)
{
return
0;
}
int
adapterLength
=
adapter.getMaximumLength();
if
(adapterLength
>
0)
{
return
adapterLength;
}
String
maxText
=
null;
int
addItems
=
visibleItems
/
2;
for
(int
i
=
Math.max(currentItem
-
addItems,
0);
i
<
Math.min(currentItem
+
visibleItems,
adapter.getItemsCount());
i++)
{
String
text
=
adapter.getItem(i);
if
(text
!=
null
&&
(maxText
==
null
||
maxText.length()
<
text.length()))
{
maxText
=
text;
}
}
return
maxText
!=
null
?
maxText.length()
:
0;
}
/**
*
Returns
height
of
wheel
item
*
@return
the
item
height
*/
private
int
getItemHeight()
{
if
(itemHeight
!=
0)
{
return
itemHeight;
}
else
if
(itemsLayout
!=
null
&&
itemsLayout.getLineCount()
>
2)
{
itemHeight
=
itemsLayout.getLineTop(2)
-
itemsLayout.getLineTop(1);
return
itemHeight;
}
return
getHeight()
/
visibleItems;
}
/**
*
Calculates
control
width
and
creates
text
layouts
*
@param
widthSize
the
input
layout
width
*
@param
mode
the
layout
mode
*
@return
the
calculated
control
width
*/
private
int
calculateLayoutWidth(int
widthSize,
int
mode)
{
initResourcesIfNecessary();
int
width
=
widthSize;
int
maxLength
=
getMaxTextLength();
if
(maxLength
>
0)
{
float
textWidth
=
FloatMath.ceil(Layout.getDesiredWidth("0",
itemsPaint));
itemsWidth
=
(int)
(maxLength
*
textWidth);
}
else
{
itemsWidth
=
0;
}
itemsWidth
+=
ADDITIONAL_ITEMS_SPACE;
//
make
it
some
more
labelWidth
=
0;
if
(label
!=
null
&&
label.length()
>
0)
{
labelWidth
=
(int)
FloatMath.ceil(Layout.getDesiredWidth(label,
valuePaint));
}
boolean
recalculate
=
false;
if
(mode
==
MeasureSpec.EXACTLY)
{
width
=
widthSize;
recalculate
=
true;
}
else
{
width
=
itemsWidth
+
labelWidth
+
2
*
PADDING;
if
(labelWidth
>
0)
{
width
+=
LABEL_OFFSET;
}
//
Check
against
our
minimum
width
width
=
Math.max(width,
getSuggestedMinimumWidth());
if
(mode
==
MeasureSpec.AT_MOST
&&
widthSize
<
width)
{
width
=
widthSize;
recalculate
=
true;
}
}
if
(recalculate)
{
//
recalculate
width
int
pureWidth
=
width
-
LABEL_OFFSET
-
2
*
PADDING;
if
(pureWidth
<=
0)
{
itemsWidth
=
labelWidth
=
0;
}
if
(labelWidth
>
0)
{
double
newWidthItems
=
(double)
itemsWidth
*
pureWidth
/
(itemsWidth
+
labelWidth);
itemsWidth
=
(int)
newWidthItems;
labelWidth
=
pureWidth
-
itemsWidth;
}
else
{
itemsWidth
=
pureWidth
+
LABEL_OFFSET;
//
no
label
}
}
if
(itemsWidth
>
0)
{
createLayouts(itemsWidth,
labelWidth);
}
return
width;
}
/**
*
Creates
layouts
*
@param
widthItems
width
of
items
layout
*
@param
widthLabel
width
of
label
layout
*/
private
void
createLayouts(int
widthItems,
int
widthLabel)
{
if
(itemsLayout
==
null
||
itemsLayout.getWidth()
>
widthItems)
{
itemsLayout
=
new
StaticLayout(buildText(isScrollingPerformed),
itemsPaint,
widthItems,
widthLabel
>
0
?
Layout.Alignment.ALIGN_OPPOSITE
:
Layout.Alignment.ALIGN_CENTER,
1,
ADDITIONAL_ITEM_HEIGHT,
false);
}
else
{
itemsLayout.increaseWidthTo(widthItems);
}
if
(!isScrollingPerformed
&&
(valueLayout
==
null
||
valueLayout.getWidth()
>
widthItems))
{
String
text
=
getAdapter()
!=
null
?
getAdapter().getItem(currentItem)
:
null;
valueLayout
=
new
StaticLayout(text
!=
null
?
text
:
"",
valuePaint,
widthItems,
widthLabel
>
0
?
Layout.Alignment.ALIGN_OPPOSITE
:
Layout.Alignment.ALIGN_CENTER,
1,
ADDITIONAL_ITEM_HEIGHT,
false);
}
else
if
(isScrollingPerformed)
{
valueLayout
=
null;
}
else
{
valueLayout.increaseWidthTo(widthItems);
}
if
(widthLabel
>
0)
{
if
(labelLayout
==
null
||
labelLayout.getWidth()
>
widthLabel)
{
labelLayout
=
new
StaticLayout(label,
valuePaint,
widthLabel,
Layout.Alignment.ALIGN_NORMAL,
1,
ADDITIONAL_ITEM_HEIGHT,
false);
}
else
{
labelLayout.increaseWidthTo(widthLabel);
}
}
}
@Override
protected
void
onMeasure(int
widthMeasureSpec,
int
heightMeasureSpec)
{
int
widthMode
=
MeasureSpec.getMode(widthMeasureSpec);
int
heightMode
=
MeasureSpec.getMode(heightMeasureSpec);
int
widthSize
=
MeasureSpec.getSize(widthMeasureSpec);
int
heightSize
=
MeasureSpec.getSize(heightMeasureSpec);
int
width
=
calculateLayoutWidth(widthSize,
widthMode);
int
height;
if
(heightMode
==
MeasureSpec.EXACTLY)
{
height
=
heightSize;
}
else
{
height
=
getDesiredHeight(itemsLayout);
if
(heightMode
==
MeasureSpec.AT_MOST)
{
height
=
Math.min(height,
heightSize);
}
}
setMeasuredDimension(width,
height);
}
@Override
protected
void
onDraw(Canvas
canvas)
{
super.onDraw(canvas);
if
(itemsLayout
==
null)
{
if
(itemsWidth
==
0)
{
calculateLayoutWidth(getWidth(),
MeasureSpec.EXACTLY);
}
else
{
createLayouts(itemsWidth,
labelWidth);
}
}
if
(itemsWidth
>
0)
{
canvas.save();
//
Skip
padding
space
and
hide
a
part
of
top
and
bottom
items
canvas.translate(PADDING,
-ITEM_OFFSET);
drawItems(canvas);
drawValue(canvas);
canvas.restore();
}
drawCenterRect(canvas);
drawShadows(canvas);
}
/**
*
Draws
shadows
on
top
and
bottom
of
control
*
@param
canvas
the
canvas
for
drawing
*/
private
void
drawShadows(Canvas
canvas)
{
topShadow.setBounds(0,
0,
getWidth(),
getHeight()
/
visibleItems);
topShadow.draw(canvas);
bottomShadow.setBounds(0,
getHeight()
-
getHeight()
/
visibleItems,
getWidth(),
getHeight());
bottomShadow.draw(canvas);
}
/**
*
Draws
value
and
label
layout
*
@param
canvas
the
canvas
for
drawing
*/
private
void
drawValue(Canvas
canvas)
{
valuePaint.setColor(VALUE_TEXT_COLOR);
valuePaint.drawableState
=
getDrawableState();
Rect
bounds
=
new
Rect();
itemsLayout.getLineBounds(visibleItems
/
2,
bounds);
//
draw
label
if
(labelLayout
!=
null)
{
canvas.save();
canvas.translate(itemsLayout.getWidth()
+
LABEL_OFFSET,
bounds.top);
labelLayout.draw(canvas);
canvas.restore();
}
//
draw
current
value
if
(valueLayout
!=
null)
{
canvas.save();
canvas.translate(0,
bounds.top
+
scrollingOffset);
valueLayout.draw(canvas);
canvas.restore();
}
}
/**
*
Draws
items
*
@param
canvas
the
canvas
for
drawing
*/
private
void
drawItems(Canvas
canvas)
{
canvas.save();
int
top
=
itemsLayout.getLineTop(1);
canvas.translate(0,
-
top
+
scrollingOffset);
itemsPaint.setColor(ITEMS_TEXT_COLOR);
itemsPaint.drawableState
=
getDrawableState();
itemsLayout.draw(canvas);
canvas.restore();
}
/**
*
Draws
rect
for
current
value
*
@param
canvas
the
canvas
for
drawing
*/
private
void
drawCenterRect(Canvas
canvas)
{
int
center
=
getHeight()
/
2;
int
offset
=
getItemHeight()
/
2;
centerDrawable.setBounds(0,
center
-
offset,
getWidth(),
center
+
offset);
centerDrawable.draw(canvas);
}
@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
(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;
}
};
//
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)
{
puteScrollOffset();
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();
}
}主布局文件
<?xml
version="1.0"
encoding="utf-8"?>
<LinearLayout
xmlns:android="/apk/res/android"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/layout_bg"
android:layout_width="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:textStyle="bold"
android:text="Please
enter
PIN"/>
<LinearLayout
android:layout_marginTop="24dp"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<kankan.wheel.widget.WheelView
android:id="@+id/passw_1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
<kankan.wheel.widget.WheelView
android:id="@+id/passw_2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
<kankan.wheel.widget.WheelView
android:id="@+id/passw_3"
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 42567.4-2025工業(yè)過程測量變送器試驗的參比條件和程序第4部分:物位變送器的特定程序
- 別墅果樹出售合同范本
- 勘查標(biāo)準(zhǔn)合同范本
- 上海古董拍賣合同范本
- 信托轉(zhuǎn)讓合同范本
- 單位與單位入股合同范本
- 鄉(xiāng)村道路跨寬施工合同范本
- 加工企業(yè)入股合同范本
- 單位施工合同范例
- 包裝盒印刷廠合同范本
- 食品經(jīng)營安全管理制度目錄
- 南通大學(xué)開題報告模版
- 醫(yī)院急救中心勞務(wù)外包采購項目評標(biāo)辦法(評分細(xì)則表)
- JTG H12-2015 公路隧道養(yǎng)護技術(shù)規(guī)范
- 2024天津工業(yè)職業(yè)學(xué)院教師招聘考試筆試試題
- QCT1067.5-2023汽車電線束和電器設(shè)備用連接器第5部分:設(shè)備連接器(插座)的型式和尺寸
- 石灰石開采項目可行性分析報告
- 2024年高考?xì)v史總復(fù)習(xí)中外歷史大事年表
- 合金固態(tài)相變?nèi)捉虒W(xué)課件
- 追求理解的教學(xué)設(shè)計
- 《研學(xué)旅行課程設(shè)計》課件-1研學(xué)課程資源選擇
評論
0/150
提交評論