【移动应用开发技术】Android中怎么利用 ListView实现下拉顶部图片变大效果_第1页
【移动应用开发技术】Android中怎么利用 ListView实现下拉顶部图片变大效果_第2页
【移动应用开发技术】Android中怎么利用 ListView实现下拉顶部图片变大效果_第3页
【移动应用开发技术】Android中怎么利用 ListView实现下拉顶部图片变大效果_第4页
【移动应用开发技术】Android中怎么利用 ListView实现下拉顶部图片变大效果_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】Android中怎么利用ListView实现下拉顶部图片变大效果

Android中怎么利用ListView实现下拉顶部图片变大效果,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。变量说明这里变量包含了:自定义返回动画加速度、自定义动画线程、头部图片view,最后的y坐标,做好的比例,做大的比例等。private

static

final

String

TAG

=

"PullToZoomListView";

private

static

final

int

INVALID_VALUE

=

-1;//重置值

//自定义加速度动画

private

static

final

Interpolator

sInterpolator

=

new

Interpolator()

{

public

float

getInterpolation(float

interpolator)

{

float

f

=

interpolator

-

1.0F;

return

1.0F

+

f

*

(f

*

(f

*

(f

*

f)));

}

};

private

int

mActivePointerId

=

INVALID_VALUE;//当前手指的Id

private

FrameLayout

mHeaderContainer;//头部

private

int

mHeaderHeight;//头部图片的高度

private

ImageView

mHeaderImage;//头部图片

float

mLastMotionY

=

INVALID_VALUE;//最后y坐标

float

mLastScale

=

INVALID_VALUE;//最后的比例

float

mMaxScale

=

INVALID_VALUE;//最大的比例

private

OnScrollListener

mOnScrollListener;//滑动监听

private

ScalingRunnalable

mScalingRunnalable;//动画线程

private

int

mScreenHeight;//屏幕高度

private

ImageView

mShadow;//阴影遮罩自定义View初始化:设置了头部的头部和遮罩并且设置了监听。/**

*

初始化

*

@param

paramContext

*/

private

void

init(Context

paramContext)

{

DisplayMetrics

metrics

=

new

DisplayMetrics();

((Activity)

paramContext).getWindowManager().getDefaultDisplay().getMetrics(metrics);

this.mScreenHeight

=

metrics.heightPixels;//屏幕高度赋值

this.mHeaderContainer

=

new

FrameLayout(paramContext);//头部

this.mHeaderImage

=

new

ImageView(paramContext);//头部图片

int

screenWidth

=

metrics.widthPixels;//屏幕宽度

//设置头部View的样式

设置屏幕宽度,最大样式高度为屏幕高度的9/16

setHeaderViewSize(screenWidth,

(int)

(9.0F

*

(screenWidth

/

16.0F)));

this.mShadow

=

new

ImageView(paramContext);//遮罩

FrameLayout.LayoutParams

layoutParams

=

new

FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,

ViewGroup.LayoutParams.MATCH_PARENT);

layoutParams.gravity

=

Gravity.CENTER;

this.mShadow.setLayoutParams(layoutParams);//设置遮罩样式

//头部添加View

this.mHeaderContainer.addView(this.mHeaderImage);

this.mHeaderContainer.addView(this.mShadow);

//添加头部

addHeaderView(this.mHeaderContainer);

//初始化返回动画

this.mScalingRunnalable

=

new

ScalingRunnalable();

//设置监听

super.setOnScrollListener(this);

}开启动画:判断当前的头部布局底部的位置–是否大于图片的初始化高度。/**

*

开启动画

*/

private

void

endScraling()

{

if

(this.mHeaderContainer.getBottom()

>=

this.mHeaderHeight)

{

Log.d(TAG,

"this.mScalingRunnalable.startAnimation(200L)");

this.mScalingRunnalable.startAnimation(200L);

}

}多指触碰时将第0个手指赋值。/**

*

多点触碰的时候按下,当第0个有手指抬起,再次有手指按下后,将按下的事件的手指指针作为当前手指指针

*

*

@param

motionEvent

*/

private

void

onSecondaryPointerUp(MotionEvent

motionEvent)

{

Log.d(TAG,

"onSecondaryPointerUp

motionEvent.getPointerId(0)

=

"

+

motionEvent.getPointerId(0));

Log.d(TAG,

"onSecondaryPointerUp

this.mActivePointerId

=

"

+

this.mActivePointerId);

if

(motionEvent.getPointerId(0)

==

this.mActivePointerId)

{

this.mLastMotionY

=

motionEvent.getY(0);

this.mActivePointerId

=

motionEvent.getPointerId(0);

}

Log.d(TAG,

"onSecondaryPointerUp

mLastMotionY

=

"

+

mLastMotionY);

Log.d(TAG,

"onSecondaryPointerUp

mActivePointerId

=

"

+

mActivePointerId);

}重置所有的数据/**

*

重置所有数据

*/

private

void

reset()

{

this.mActivePointerId

=

INVALID_VALUE;

this.mLastMotionY

=

INVALID_VALUE;

this.mMaxScale

=

INVALID_VALUE;

this.mLastScale

=

INVALID_VALUE;

}向上滚动时修改布局样式@Override

public

void

onScroll(AbsListView

view,

int

firstVisibleItem,

int

visibleItemCount,

int

totalItemCount)

{

Log.d(TAG,

"onScroll");

float

bottomSpacing

=

this.mHeaderHeight

-

this.mHeaderContainer.getBottom();

Log.d(TAG,

"onScroll

bottomSpacing

=

"

+

bottomSpacing);

if

((bottomSpacing

>

0.0F)

&&

(bottomSpacing

<

this.mHeaderHeight))

{//如果是向上滑动

int

toUpScroll

=

(int)

(0.65D

*

bottomSpacing);

this.mHeaderImage.scrollTo(0,

-toUpScroll);

Log.d(TAG,

"onScroll

向上滑动

toUpScroll

=

"

+

toUpScroll);

}

else

if

(this.mHeaderImage.getScrollY()

!=

0)

{

Log.d(TAG,

"onScroll

this.mHeaderImage.getScrollY()

=

"

+

this.mHeaderImage.getScrollY());

this.mHeaderImage.scrollTo(0,

0);

}

if

(this.mOnScrollListener

!=

null)

{

this.mOnScrollListener.onScroll(view,

firstVisibleItem,

visibleItemCount,

totalItemCount);

}

}不同事件处理,修改布局样式@Override

public

boolean

onTouchEvent(MotionEvent

motionEvent)

{

switch

(motionEvent.getAction()

&

MotionEvent.ACTION_MASK)

{

case

MotionEvent.ACTION_OUTSIDE:

case

MotionEvent.ACTION_DOWN:

if

(!this.mScalingRunnalable.mIsFinished)

{

this.mScalingRunnalable.abortAnimation();

}

this.mLastMotionY

=

motionEvent.getY();

//获取第一个手指指针的ID

this.mActivePointerId

=

motionEvent.getPointerId(0);

this.mMaxScale

=

(this.mScreenHeight

/

this.mHeaderHeight);

this.mLastScale

=

(this.mHeaderContainer.getBottom()

/

this.mHeaderHeight);

Log.d(TAG,

"onTouchEvent

ACTION_DOWN

mLastMotionY

=

"

+

mLastMotionY);

Log.d(TAG,

"onTouchEvent

ACTION_DOWN

mActivePointerId

=

"

+

mActivePointerId);

Log.d(TAG,

"onTouchEvent

ACTION_DOWN

mMaxScale

=

"

+

mMaxScale);

Log.d(TAG,

"onTouchEvent

ACTION_DOWN

mLastScale

=

"

+

mLastScale);

break;

case

MotionEvent.ACTION_MOVE:

Log.d(TAG,

"onTouchEvent

ACTION_MOVE

mActivePointerId"

+

mActivePointerId);

//获取当前id的手机指针

int

pointer

=

motionEvent.findPointerIndex(this.mActivePointerId);

//判断指针不为空

if

(pointer

==

INVALID_VALUE)

{

Log.e(TAG,

"Invalid

pointerId="

+

this.mActivePointerId

+

"

in

onTouchEvent");

}

else

{

//如果开始没有赋值,则需要赋值

if

(this.mLastMotionY

==

INVALID_VALUE)

{

this.mLastMotionY

=

motionEvent.getY(pointer);

}

if

(this.mHeaderContainer.getBottom()

>=

this.mHeaderHeight)

{

//获取头部样式

ViewGroup.LayoutParams

headerParams

=

this.mHeaderContainer.getLayoutParams();

float

currentScale

=

((motionEvent.getY(pointer)

-

this.mLastMotionY

+

this.mHeaderContainer.getBottom())

/

this.mHeaderHeight

-

this.mLastScale)

/

2.0F

+

this.mLastScale;

if

((this.mLastScale

<=

1.0D)

&&

(currentScale

<

this.mLastScale))

{

//最后比例小于默认并且当前的比例要小于上次的比例,则修改头部的高度

headerParams.height

=

this.mHeaderHeight;

this.mHeaderContainer.setLayoutParams(headerParams);

return

super.onTouchEvent(motionEvent);

}

else

{

//否则,将当前的比例赋值为最后一次的比例

this.mLastScale

=

Math.min(Math.max(currentScale,

1.0F),

this.mMaxScale);

headerParams.height

=

((int)

(this.mHeaderHeight

*

this.mLastScale));

//判断修改后的高度小于屏幕的高度

if

(headerParams.height

<

this.mScreenHeight)

{

this.mHeaderContainer.setLayoutParams(headerParams);

}

//记录最后的y坐标

this.mLastMotionY

=

motionEvent.getY(pointer);

return

true;

}

}

this.mLastMotionY

=

motionEvent.getY(pointer);

}

break;

case

MotionEvent.ACTION_UP:

Log.d(TAG,

"onTouchEvent

ACTION_UP

重置");

//重置

reset();

//当手指起来的时候,结算拉伸,判断是否开启动画

endScraling();

break;

case

MotionEvent.ACTION_CANCEL:

int

actionIndex

=

motionEvent.getActionIndex();//获取当前最上层的指针

this.mLastMotionY

=

motionEvent.getY(actionIndex);//获取最后的y坐标

this.mActivePointerId

=

motionEvent.getPointerId(actionIndex);//获取最上层指针的手指

Log.d(TAG,

"onTouchEvent

ACTION_CANCEL

actionIndex

=

"

+

actionIndex

+

"

mLastMotionY

=

"

+

mLastMotionY

+

"

mActivePointerId

=

"

+

mActivePointerId);

break;

case

MotionEvent.ACTION_POINTER_DOWN:

//当第二个手指按下或者放开触发这个事件

onSecondaryPointerUp(motionEvent);

this.mLastMotionY

=

motionEvent.getY(motionEvent.findPointerIndex(this.mActivePointerId));

Log.d(TAG,

"onTouchEvent_Po

ACTION_POINTER_DOWN

mLastMotionY

=

"

+

mLastMotionY);

break;

case

MotionEvent.ACTION_POINTER_UP:

//当第二个手指按下或者放开

Log.d(TAG,

"onTouchEvent_Po

ACTION_POINTER_UP

");

break;

}

return

super.onTouchEvent(motionEvent);

}向上返回时的动画/**

*

向上返回的动画

*/

class

ScalingRunnalable

implements

Runnable

{

long

mDuration;//持续时间

boolean

mIsFinished

=

true;//是否结束

float

mScale;//比例

long

mStartTime;//开始时间

ScalingRunnalable()

{

}

/**

*

中止动画

*/

public

void

abortAnimation()

{

this.mIsFinished

=

true;

}

/**

*

是否中止

*

*

@return

*/

public

boolean

isFinished()

{

return

this.mIsFinished;

}

public

void

run()

{

Log.d(TAG,

"ScalingRunnalable

mIsFinished

=

"

+

this.mIsFinished

+

"

this.mScale

=

"

+

this.mScale);

float

currentScale;

ViewGroup.LayoutParams

mHeaderContainerParams;//头部样式

//判断是否中止和已经滑动超过的默认大小

if

((!this.mIsFinished)

&&

(this.mScale

>

1.0D))

{

float

currentTime

=

((float)

SystemClock.currentThreadTimeMillis()

-

(float)

this.mStartTime)

/

(float)

this.mDuration;

currentScale

=

this.mScale

-

(this.mScale

-

1.0F)

*

PullToZoomListView.sInterpolator.getInterpolation(currentTime);

Log.d(TAG,

"ScalingRunnalable

currentTime

=

"

+

currentTime

+

"

currentScale

=

"

+

currentScale);

mHeaderContainerParams

=

PullToZoomListView.this.mHeaderContainer.getLayoutParams();

if

(currentScale

>

1.0F)

{

Log.d(TAG,

"ScalingRunnalable

currentScale

>

1.0

--

修改头部高度");

mHeaderContainerParams.height

=

PullToZoomListView.this.mHeaderHeight;

mHeaderContai

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论