【移動應(yīng)用開發(fā)技術(shù)】使用Android怎么構(gòu)造一個滾輪控件_第1頁
【移動應(yīng)用開發(fā)技術(shù)】使用Android怎么構(gòu)造一個滾輪控件_第2頁
【移動應(yīng)用開發(fā)技術(shù)】使用Android怎么構(gòu)造一個滾輪控件_第3頁
【移動應(yīng)用開發(fā)技術(shù)】使用Android怎么構(gòu)造一個滾輪控件_第4頁
【移動應(yīng)用開發(fā)技術(shù)】使用Android怎么構(gòu)造一個滾輪控件_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

【移動應(yīng)用開發(fā)技術(shù)】使用Android怎么構(gòu)造一個滾輪控件

這篇文章將為大家詳細(xì)講解有關(guān)使用Android怎么構(gòu)造一個滾輪控件,文章內(nèi)容質(zhì)量較高,因此在下分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。自定義控件無非是measure,draw,layout三個過程,如果要支持手勢動作,那么就再加上touch。measure測量過程比較簡單,以文本大小所需要的尺寸,再加上padding。@Override

protected

void

onMeasure(int

widthMeasureSpec,

int

heightMeasureSpec)

{

super.onMeasure(widthMeasureSpec,

heightMeasureSpec);

int

wantWith

=

getPaddingLeft()

+

getPaddingRight();

int

wantHeight

=

getPaddingTop()

+

getPaddingBottom();

calculateTextSize();

wantWith

+=

mTextRect.width();

//可見

item

數(shù)量計算文本尺寸

if

(mVisibilityCount

>

0)

{

wantHeight

+=

mTextRect.height()

*

mVisibilityCount;

}

else

{

wantHeight

+=

mTextRect.height()

*

DEFALUT_VISIBILITY_COUNT;

}

setMeasuredDimension(

resolveSize(wantWith,

widthMeasureSpec),

resolveSize(wantHeight,

heightMeasureSpec)

);

mNeedCalculate

=

true;

}draw繪制過程是通過canvas的位移去繪制不同位置的部件,包括文本內(nèi)容和選擇框之類的,這里可能需要注意下的地方是,不要一次性把所有文本繪制出來,只需要繪制可見文本即可。@Override

protected

void

onDraw(Canvas

canvas)

{

super.onDraw(canvas);

if

(hasDataSource())

{

//

省略

//

這里計算下需要繪制的數(shù)量,+2

只是確保不會出現(xiàn)空白

final

int

drawCount

=

mContentRect.height()

/

mTextRect.height()

+

2;

int

invisibleCount

=

0;

int

dy

=

-mDistanceY;

//

省略

//

通過

translate

繪制文本

for

(int

i

=

0;

(i

<

drawCount

&&

mDataSources.size()

>

(invisibleCount

+

i));

i++)

{

final

int

position

=

invisibleCount

+

i;

String

text

=

mDataSources.get(position);

if

(i

>

0)

{

canvas.translate(0,

mTextRect.height());

}

final

PointF

pointF

=

calculateTextGravity(text);

mTextPaint.setTextSize(mTextSize);

if

(position

==

selctPosition)

{

mTextPaint.setColor(mSelectedTextColor);

}

else

{

mTextPaint.setColor(mNormalTextColor);

}

canvas.drawText(text,

pointF.x,

pointF.y,

mTextPaint);

}

canvas.restoreToCount(saveCount);

}

//

繪制選擇框

int

saveCount

=

canvas.save();

mDrawPaint.setColor(mSelectedLineColor);

canvas.translate(mContentRect.left,

mContentRect.top);

canvas.drawLine(

mSelctedRect.left,

mSelctedRect.top,

mSelctedRect.right,

mSelctedRect.top,

mDrawPaint

);

canvas.drawLine(

mSelctedRect.left,

mSelctedRect.bottom,

mSelctedRect.right,

mSelctedRect.bottom,

mDrawPaint

);

canvas.restoreToCount(saveCount);

}layout因為這個控件是繼承于View,所以不需要處理onLayout。touch如果對touchevent分發(fā)流程熟悉的話,那么很多處理可以說是模版代碼,可以參考NestedScrollView、ScrollView。在onInterceptTouchEvent中,判斷是否開始進(jìn)行拖動手勢,保存到變量(mIsBeingDragged)中://

多指處理

final

int

pointerIndex

=

ev.findPointerIndex(activePointerId);

if

(pointerIndex

==

-1)

{

Log.e(TAG,

"Invalid

pointerId="

+

activePointerId

+

"

in

onInterceptTouchEvent");

break;

}

final

int

y

=

(int)

ev.getY(pointerIndex);

final

int

yDiff

=

Math.abs(y

-

mLastMotionY);

if

(yDiff

>

mTouchSlop

&&

(getNestedScrollAxes()

&

SCROLL_AXIS_VERTICAL)

==

0)

{

//

開始拖動

mIsBeingDragged

=

true;

mLastMotionY

=

y;

initVelocityTrackerIfNotExists();

mVelocityTracker.addMovement(ev);

mNestedYOffset

=

0;

if

(mScrollStrictSpan

==

null)

{

mScrollStrictSpan

=

StrictMode.enterCriticalSpan("ScrollView-scroll");

}

final

ViewParent

parent

=

getParent();

if

(parent

!=

null)

{

//

禁止父控件攔截事件分發(fā)

parent.requestDisallowInterceptTouchEvent(true);

}

}在onTouchEvent中對ACTION_MOVR進(jìn)行拖動的處理,如果支持嵌套滾動,那么會預(yù)先進(jìn)行嵌套滾動的分發(fā)。如果支持陰影效果,那么使用EdgeEffect。//

onInterceptTouchEvent

一樣進(jìn)行拖動手勢開始的判斷

if

(!mIsBeingDragged

&&

Math.abs(deltaY)

>

mTouchSlop)

{

final

ViewParent

parent

=

getParent();

if

(parent

!=

null)

{

parent.requestDisallowInterceptTouchEvent(true);

}

mIsBeingDragged

=

true;

if

(deltaY

>

0)

{

deltaY

-=

mTouchSlop;

}

else

{

deltaY

+=

mTouchSlop;

}

}

if

(mIsBeingDragged)

{

//

拖動處理

//

Scroll

to

follow

the

motion

event

mLastMotionY

=

y

-

mScrollOffset[1];

final

int

oldY

=

mScrollY;

final

int

range

=

getScrollRange();

final

int

overscrollMode

=

getOverScrollMode();

boolean

canOverscroll

=

overscrollMode

==

OVER_SCROLL_ALWAYS

||

(overscrollMode

==

OVER_SCROLL_IF_CONTENT_SCROLLS

&&

range

>

0);

//

Calling

overScrollBy

will

call

onOverScrolled,

which

//

calls

onScrollChanged

if

applicable.

//

滾動處理,overScrollBy

中會處理嵌套滾動預(yù)先分發(fā)

if

(overScrollBy(0,

deltaY,

0,

mScrollY,

0,

range,

0,

mOverscrollDistance,

true)

&&

!hasNestedScrollingParent())

{

//

Break

our

velocity

if

we

hit

a

scroll

barrier.

mVelocityTracker.clear();

}

final

int

scrolledDeltaY

=

mScrollY

-

oldY;

final

int

unconsumedY

=

deltaY

-

scrolledDeltaY;

//

嵌套滾動

if

(dispatchNestedScroll(0,

scrolledDeltaY,

0,

unconsumedY,

mScrollOffset))

{

mLastMotionY

-=

mScrollOffset[1];

vtev.offsetLocation(0,

mScrollOffset[1]);

mNestedYOffset

+=

mScrollOffset[1];

}

else

if

(canOverscroll)

{

final

int

pulledToY

=

oldY

+

deltaY;

//

拖動陰影效果

if

(pulledToY

<

0)

{

mEdgeGlowTop.onPull((float)

deltaY

/

getHeight(),

ev.getX(activePointerIndex)

/

getWidth());

if

(!mEdgeGlowBottom.isFinished())

{

mEdgeGlowBottom.onRelease();

}

}

else

if

(pulledToY

>

range)

{

mEdgeGlowBottom.onPull((float)

deltaY

/

getHeight(),

1.f

-

ev.getX(activePointerIndex)

/

getWidth());

if

(!mEdgeGlowTop.isFinished())

{

mEdgeGlowTop.onRelease();

}

}

if

(mEdgeGlowTop

!=

null

&&

(!mEdgeGlowTop.isFinished()

||

!mEdgeGlowBottom.isFinished()))

{

postInvalidateOnAnimation();

}

}

}支持滾動手勢的控件,一般都會支持fling手勢,可以理解為慣性滾動。這也是模版代碼,在onTouchEvent中對ACTION_UP中對拖動速度進(jìn)行分析。case

MotionEvent.ACTION_UP:

if

(mIsBeingDragged)

{

final

VelocityTracker

velocityTracker

=

mVelocityTracker;

velocityTputeCurrentVelocity(1000,

mMaximumVelocity);

//

獲取拖動速度

int

initialVelocity

=

(int)

velocityTracker.getYVelocity(mActivePointerId);

if

((Math.abs(initialVelocity)

>

mMinimumVelocity))

{

//

可以進(jìn)行

fling

操作

flingWithNestedDispatch(-initialVelocity);

}

else

if

(mScroller.springBack(mScrollX,

mScrollY,

0,

0,

0,

getScrollRange()))

{

postInvalidateOnAnimation();

}

mActivePointerId

=

INVALID_POINTER;

endDrag();

}

break;具體的代碼可以在ScrollView中閱讀?;氐轿覍崿F(xiàn)的自定義控件來,對touchevent的處理代碼可以說是和系統(tǒng)控件的處理沒有什么兩樣,在獲取到拖動的距離后,根據(jù)這個值繪制不同位置的可見區(qū)域。這里多了兩個處理是:第一拖動結(jié)束后,進(jìn)行復(fù)位處理。拖動結(jié)束后,選擇框如果停留在兩個item之間,那么根據(jù)和兩個item的距離進(jìn)行比較,選擇更近的item。private

void

correctionDistanceY()

{

if

(mDistanceY

%

mTextRect.height()

!=

0)

{

int

position

=

mDis

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論