日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android 文字fly动画,超好看的下拉刷新动画Android代码实现

發(fā)布時間:2023/12/19 Android 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 文字fly动画,超好看的下拉刷新动画Android代码实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近看到了好多高端、大氣、上檔次的動畫效果,如果給你的項目中加上這些動畫,相信你的app一定很優(yōu)秀,今天給大家分析一下來自Yalantis的一個超好看的下拉刷新動畫。

首先我們看一下效果如何:

怎么樣?是不是很高大上?接下來我們看一下代碼:

一、首先我們需要自定義刷新的動態(tài)RefreshView(也就是下拉時候的頭)1.初始化頭所占用的Dimens

private void initiateDimens() {

mScreenWidth = mContext.getResources().getDisplayMetrics().widthPixels;

mJetTopOffset = mParent.getTotalDragDistance() * 0.5f;

mTop = -mParent.getTotalDragDistance();

}

2.為頭填充圖片,設置圖片的大小

分別為左邊的云彩,右邊的云彩,中間的云彩還有中間的飛機,飛機是帶有動畫的,下面會介紹飛機的動畫

private void createBitmaps() {

mLeftClouds = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.clouds_left);

mRightClouds = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.clouds_right);

mFrontClouds = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.clouds_center);

mJet = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.airplane);

mJetWidthCenter = mJet.getWidth() / 2;

mJetHeightCenter = mJet.getHeight() / 2;

mFrontCloudWidthCenter = mFrontClouds.getWidth() / 2;

mFrontCloudHeightCenter = mFrontClouds.getHeight() / 2;

mRightCloudsWidthCenter = mRightClouds.getWidth() / 2;

mRightCloudsHeightCenter = mRightClouds.getHeight() / 2;

mLeftCloudsWidthCenter = mLeftClouds.getWidth() / 2;

mLeftCloudsHeightCenter = mLeftClouds.getHeight() / 2;

}

3.然后我們來畫這個頭

public void draw(@NonNull Canvas canvas) {

final int saveCount = canvas.save();

// DRAW BACKGROUND.

canvas.drawColor(mContext.getResources().getColor(R.color.sky_background));

if (isRefreshing) {

// Set up new set of wind

while (mWinds.size() < WIND_SET_AMOUNT) {

float y = (float) (mParent.getTotalDragDistance() / (Math.random() * RANDOM_Y_COEFFICIENT));

float x = random(MIN_WIND_X_OFFSET, MAX_WIND_X_OFFSET);

// Magic with checking interval between winds

if (mWinds.size() > 1) {

y = 0;

while (y == 0) {

float tmp = (float) (mParent.getTotalDragDistance() / (Math.random() * RANDOM_Y_COEFFICIENT));

for (Map.Entry wind : mWinds.entrySet()) {

// We want that interval will be greater than fifth part of draggable distance

if (Math.abs(wind.getKey() - tmp) > mParent.getTotalDragDistance() / RANDOM_Y_COEFFICIENT) {

y = tmp;

} else {

y = 0;

break;

}

}

}

}

mWinds.put(y, x);

drawWind(canvas, y, x);

}

// Draw current set of wind

if (mWinds.size() >= WIND_SET_AMOUNT) {

for (Map.Entry wind : mWinds.entrySet()) {

drawWind(canvas, wind.getKey(), wind.getValue());

}

}

// We should to create new set of winds

if (mInverseDirection && mNewWindSet) {

mWinds.clear();

mNewWindSet = false;

mWindLineWidth = random(MIN_WIND_LINE_WIDTH, MAX_WIND_LINE_WIDTH);

}

// needed for checking direction

mLastAnimationTime = mLoadingAnimationTime;

}

drawJet(canvas);

drawSideClouds(canvas);

drawCenterClouds(canvas);

canvas.restoreToCount(saveCount);

}

/**

* Draw wind on loading animation

*

* @param canvas - area where we will draw

* @param y - y position fot one of lines

* @param xOffset - x offset for on of lines

*/

private void drawWind(Canvas canvas, float y, float xOffset) {

/* We should multiply current animation time with this coefficient for taking all screen width in time

Removing slowing of animation with dividing on {@LINK #SLOW_DOWN_ANIMATION_COEFFICIENT}

And we should don't forget about distance that should "fly" line that depend on screen of device and x offset

*/

float cof = (mScreenWidth + xOffset) / (LOADING_ANIMATION_COEFFICIENT / SLOW_DOWN_ANIMATION_COEFFICIENT);

float time = mLoadingAnimationTime;

// HORRIBLE HACK FOR REVERS ANIMATION THAT SHOULD WORK LIKE RESTART ANIMATION

if (mLastAnimationTime - mLoadingAnimationTime > 0) {

mInverseDirection = true;

// take time from 0 to end of animation time

time = (LOADING_ANIMATION_COEFFICIENT / SLOW_DOWN_ANIMATION_COEFFICIENT) - mLoadingAnimationTime;

} else {

mNewWindSet = true;

mInverseDirection = false;

}

// Taking current x position of drawing wind

// For fully disappearing of line we should subtract wind line width

float x = (mScreenWidth - (time * cof)) + xOffset - mWindLineWidth;

float xEnd = x + mWindLineWidth;

canvas.drawLine(x, y, xEnd, y, mWindPaint);

}

private void drawSideClouds(Canvas canvas) {

Matrix matrixLeftClouds = mMatrix;

Matrix matrixRightClouds = mAdditionalMatrix;

matrixLeftClouds.reset();

matrixRightClouds.reset();

// Drag percent will newer get more then 1 here

float dragPercent = Math.min(1f, Math.abs(mPercent));

boolean overdrag = false;

// But we check here for overdrag

if (mPercent > 1.0f) {

overdrag = true;

}

float scale;

float scalePercentDelta = dragPercent - SCALE_START_PERCENT;

if (scalePercentDelta > 0) {

float scalePercent = scalePercentDelta / (1.0f - SCALE_START_PERCENT);

scale = SIDE_CLOUDS_INITIAL_SCALE + (SIDE_CLOUDS_FINAL_SCALE - SIDE_CLOUDS_INITIAL_SCALE) * scalePercent;

} else {

scale = SIDE_CLOUDS_INITIAL_SCALE;

}

// Current y position of clouds

float dragYOffset = mParent.getTotalDragDistance() * (1.0f - dragPercent);

// Position where clouds fully visible on screen and we should drag them with content of listView

int cloudsVisiblePosition = mParent.getTotalDragDistance() / 2 - mLeftCloudsHeightCenter;

boolean needMoveCloudsWithContent = false;

if (dragYOffset < cloudsVisiblePosition) {

needMoveCloudsWithContent = true;

}

float offsetRightX = mScreenWidth - mRightClouds.getWidth();

float offsetRightY = (needMoveCloudsWithContent

? mParent.getTotalDragDistance() * dragPercent - mLeftClouds.getHeight()

: dragYOffset)

+ (overdrag ? mTop : 0);

float offsetLeftX = 0;

float offsetLeftY = (needMoveCloudsWithContent

? mParent.getTotalDragDistance() * dragPercent - mLeftClouds.getHeight()

: dragYOffset)

+ (overdrag ? mTop : 0);

// Magic with animation on loading process

if (isRefreshing) {

if (checkCurrentAnimationPart(AnimationPart.FIRST)) {

offsetLeftY += getAnimationPartValue(AnimationPart.FIRST) / Y_SIDE_CLOUDS_SLOW_DOWN_COF;

offsetRightX -= getAnimationPartValue(AnimationPart.FIRST) / X_SIDE_CLOUDS_SLOW_DOWN_COF;

} else if (checkCurrentAnimationPart(AnimationPart.SECOND)) {

offsetLeftY += getAnimationPartValue(AnimationPart.SECOND) / Y_SIDE_CLOUDS_SLOW_DOWN_COF;

offsetRightX -= getAnimationPartValue(AnimationPart.SECOND) / X_SIDE_CLOUDS_SLOW_DOWN_COF;

} else if (checkCurrentAnimationPart(AnimationPart.THIRD)) {

offsetLeftY -= getAnimationPartValue(AnimationPart.THIRD) / Y_SIDE_CLOUDS_SLOW_DOWN_COF;

offsetRightX += getAnimationPartValue(AnimationPart.THIRD) / X_SIDE_CLOUDS_SLOW_DOWN_COF;

} else if (checkCurrentAnimationPart(AnimationPart.FOURTH)) {

offsetLeftY -= getAnimationPartValue(AnimationPart.FOURTH) / X_SIDE_CLOUDS_SLOW_DOWN_COF;

offsetRightX += getAnimationPartValue(AnimationPart.FOURTH) / Y_SIDE_CLOUDS_SLOW_DOWN_COF;

}

}

matrixRightClouds.postScale(scale, scale, mRightCloudsWidthCenter, mRightCloudsHeightCenter);

matrixRightClouds.postTranslate(offsetRightX, offsetRightY);

matrixLeftClouds.postScale(scale, scale, mLeftCloudsWidthCenter, mLeftCloudsHeightCenter);

matrixLeftClouds.postTranslate(offsetLeftX, offsetLeftY);

canvas.drawBitmap(mLeftClouds, matrixLeftClouds, null);

canvas.drawBitmap(mRightClouds, matrixRightClouds, null);

}

private void drawCenterClouds(Canvas canvas) {

Matrix matrix = mMatrix;

matrix.reset();

float dragPercent = Math.min(1f, Math.abs(mPercent));

float scale;

float overdragPercent = 0;

boolean overdrag = false;

if (mPercent > 1.0f) {

overdrag = true;

// Here we want know about how mach percent of over drag we done

overdragPercent = Math.abs(1.0f - mPercent);

}

float scalePercentDelta = dragPercent - SCALE_START_PERCENT;

if (scalePercentDelta > 0) {

float scalePercent = scalePercentDelta / (1.0f - SCALE_START_PERCENT);

scale = CENTER_CLOUDS_INITIAL_SCALE + (CENTER_CLOUDS_FINAL_SCALE - CENTER_CLOUDS_INITIAL_SCALE) * scalePercent;

} else {

scale = CENTER_CLOUDS_INITIAL_SCALE;

}

float parallaxPercent = 0;

boolean parallax = false;

// Current y position of clouds

float dragYOffset = mParent.getTotalDragDistance() * dragPercent;

// Position when should start parallax scrolling

int startParallaxHeight = mParent.getTotalDragDistance() - mFrontCloudHeightCenter;

if (dragYOffset > startParallaxHeight) {

parallax = true;

parallaxPercent = dragYOffset - startParallaxHeight;

}

float offsetX = (mScreenWidth / 2) - mFrontCloudWidthCenter;

float offsetY = dragYOffset

- (parallax ? mFrontCloudHeightCenter + parallaxPercent : mFrontCloudHeightCenter)

+ (overdrag ? mTop : 0);

float sx = overdrag ? scale + overdragPercent / 4 : scale;

float sy = overdrag ? scale + overdragPercent / 2 : scale;

if (isRefreshing && !overdrag) {

if (checkCurrentAnimationPart(AnimationPart.FIRST)) {

sx = scale - (getAnimationPartValue(AnimationPart.FIRST) / LOADING_ANIMATION_COEFFICIENT) / 8;

} else if (checkCurrentAnimationPart(AnimationPart.SECOND)) {

sx = scale - (getAnimationPartValue(AnimationPart.SECOND) / LOADING_ANIMATION_COEFFICIENT) / 8;

} else if (checkCurrentAnimationPart(AnimationPart.THIRD)) {

sx = scale + (getAnimationPartValue(AnimationPart.THIRD) / LOADING_ANIMATION_COEFFICIENT) / 6;

} else if (checkCurrentAnimationPart(AnimationPart.FOURTH)) {

sx = scale + (getAnimationPartValue(AnimationPart.FOURTH) / LOADING_ANIMATION_COEFFICIENT) / 6;

}

sy = sx;

}

matrix.postScale(sx, sy, mFrontCloudWidthCenter, mFrontCloudHeightCenter);

matrix.postTranslate(offsetX, offsetY);

canvas.drawBitmap(mFrontClouds, matrix, null);

}

private void drawJet(Canvas canvas) {

Matrix matrix = mMatrix;

matrix.reset();

float dragPercent = mPercent;

float rotateAngle = 0;

// Check overdrag

if (dragPercent > 1.0f && !mEndOfRefreshing) {

rotateAngle = (dragPercent % 1) * 10;

dragPercent = 1.0f;

}

float offsetX = ((mScreenWidth * dragPercent) / 2) - mJetWidthCenter;

float offsetY = mJetTopOffset

+ (mParent.getTotalDragDistance() / 2)

* (1.0f - dragPercent)

- mJetHeightCenter;

if (isRefreshing) {

if (checkCurrentAnimationPart(AnimationPart.FIRST)) {

offsetY -= getAnimationPartValue(AnimationPart.FIRST);

} else if (checkCurrentAnimationPart(AnimationPart.SECOND)) {

offsetY -= getAnimationPartValue(AnimationPart.SECOND);

} else if (checkCurrentAnimationPart(AnimationPart.THIRD)) {

offsetY += getAnimationPartValue(AnimationPart.THIRD);

} else if (checkCurrentAnimationPart(AnimationPart.FOURTH)) {

offsetY += getAnimationPartValue(AnimationPart.FOURTH);

}

}

matrix.setTranslate(offsetX, offsetY);

if (dragPercent == 1.0f) {

matrix.preRotate(rotateAngle, mJetWidthCenter, mJetHeightCenter);

}

canvas.drawBitmap(mJet, matrix, null);

}

動畫效果已經(jīng)畫好了,下面我們來看看怎么結合下拉刷新來調用吧?

二、我們還需要自定義一個PullToRefreshView(下拉刷新)1.我們的PullToRefreshView這里需要繼承ViewGroup

我們先把剛才定義的刷新時的動畫加進來

private RefreshView mRefreshView;

private ImageView mRefreshImageView;mRefreshImageView = new ImageView(context);

mRefreshView = new RefreshView(getContext(), this);

mRefreshImageView.setImageDrawable(mRefreshView);

addView(mRefreshImageView);

2.然后我們設置OntouchEvent()事件

@Override

public boolean onTouchEvent(@NonNull MotionEvent ev) {

if (!mIsBeingDragged) {

return super.onTouchEvent(ev);

}

final int action = MotionEventCompat.getActionMasked(ev);

switch (action) {

case MotionEvent.ACTION_MOVE: {

final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);

if (pointerIndex < 0) {

return false;

}

final float y = MotionEventCompat.getY(ev, pointerIndex);

final float yDiff = y - mInitialMotionY;

final float scrollTop = yDiff * DRAG_RATE;

mCurrentDragPercent = scrollTop / mTotalDragDistance;

if (mCurrentDragPercent < 0) {

return false;

}

float boundedDragPercent = Math.min(1f, Math.abs(mCurrentDragPercent));

float extraOS = Math.abs(scrollTop) - mTotalDragDistance;

float slingshotDist = mTotalDragDistance;

float tensionSlingshotPercent = Math.max(0,

Math.min(extraOS, slingshotDist * 2) / slingshotDist);

float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow(

(tensionSlingshotPercent / 4), 2)) * 2f;

float extraMove = (slingshotDist) * tensionPercent / 2;

int targetY = (int) ((slingshotDist * boundedDragPercent) + extraMove);

mRefreshView.setPercent(mCurrentDragPercent);

setTargetOffsetTop(targetY - mCurrentOffsetTop, true);

break;

}

case MotionEventCompat.ACTION_POINTER_DOWN:

final int index = MotionEventCompat.getActionIndex(ev);

mActivePointerId = MotionEventCompat.getPointerId(ev, index);

break;

case MotionEventCompat.ACTION_POINTER_UP:

onSecondaryPointerUp(ev);

break;

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL: {

if (mActivePointerId == INVALID_POINTER) {

return false;

}

final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);

final float y = MotionEventCompat.getY(ev, pointerIndex);

final float overScrollTop = (y - mInitialMotionY) * DRAG_RATE;

mIsBeingDragged = false;

if (overScrollTop > mTotalDragDistance) {

setRefreshing(true, true);

} else {

mRefreshing = false;

animateOffsetToPosition(mAnimateToStartPosition);

}

mActivePointerId = INVALID_POINTER;

return false;

}

}

return true;

}

三、最后我們看怎樣在Activity中使用這個下拉刷新控件1.先看一下布局文件

這里是我們的下拉刷新空間嵌套著我們的ListView,然后我們再給ListView填充數(shù)據(jù)即可

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".PullToRefreshActivity">

android:id="@+id/pull_to_refresh"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/list_view"

android:divider="@null"

android:dividerHeight="0dp"

android:fadingEdge="none"

android:layout_width="match_parent"

android:layout_height="match_parent" />

2.為ListView填充數(shù)據(jù)

為了我們的效果比較好看,這里我們給ListView的每一個item填充不同的顏色,看起來會比較高大上。

Map map;

List> sampleList = new ArrayList>();

int[] colors = {

R.color.saffron,

R.color.eggplant,

R.color.sienna};

int[] tripNames = {

R.string.trip_to_india,

R.string.trip_to_italy,

R.string.trip_to_indonesia};

for (int i = 0; i < tripNames.length; i++) {

map = new HashMap();

map.put(SampleAdapter.KEY_NAME, tripNames[i]);

map.put(SampleAdapter.KEY_COLOR, colors[i]);

sampleList.add(map);

}

ListView listView = (ListView) findViewById(R.id.list_view);

listView.setAdapter(new SampleAdapter(this, R.layout.list_item, sampleList));

3.最后,我們再設置一下下拉刷新的監(jiān)聽事件就OK了

mPullToRefreshView = (PullToRefreshView) findViewById(R.id.pull_to_refresh);

mPullToRefreshView.setOnRefreshListener(new PullToRefreshView.OnRefreshListener() {

@Override

public void onRefresh() {

mPullToRefreshView.postDelayed(new Runnable() {

@Override

public void run() {

mPullToRefreshView.setRefreshing(false);

}

}, REFRESH_DELAY);

}

});

怎么樣?有沒有很高大上啊?

大家可以動手實踐一下,希望對大家的學習有所幫助。

總結

以上是生活随笔為你收集整理的android 文字fly动画,超好看的下拉刷新动画Android代码实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。