上上周写的一个demo,仿照网易一元夺宝的下拉刷新效果。
原效果是(第一部分)一个小太阳拉下来,然后松开回弹上去,
(第二部分)再掉下来一个硬币进行中轴旋转。
本文实现的效果的是第一部分的,效果演示图如下:
Gif图看起来比较卡顿。。。其实真机演示效果还是很流畅的。
下面分析实现过程:
当时因为时间有限没有写在下拉刷新的组件中,也没有封装成一个单独的组件,只是在主布局后面写了一个View然后实现相应的操作,进行封装并不难,这里就不花时间BB了,下面是布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".aty.MainActivity">
<location.haidian.com.wypulltoreflush.view.NGImgView
android:id="@+id/ngimg_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ImageView
android:id="@+id/img_main_sun"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:src="@drawable/ic_sun1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00123456"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="#FF4081">
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@android:color/darker_gray"></View>
<location.haidian.com.wypulltoreflush.view.NGReFlashListView
android:id="@+id/lv_main"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:cacheColorHint="#00000000"
/>
</LinearLayout>
</RelativeLayout>
布局文件预览:
因为设置了透明,所以这里在没有item的情况下是能看到后面的布局的。
代码实现:
通过下拉刷新类NGReFlashListView进行事件判断,然后通过回调把相应的事件传递给NGImageView中改变视图显示。
下面是两个类的源代码:
NGReFlashListView类:
package location.haidian.com.wypulltoreflush.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import location.haidian.com.wypulltoreflush.R;
public class NGReFlashListView extends ListView implements OnScrollListener {
private View header;
private int headerHeight;
private int firstVisibleItem;
private int scrollState;
private final int NONE = 0;
private final int PULL = 1;
private final int RELESE = 2;
private final int REFLASHING = 3;
public NGReFlashListView(Context context) {
super(context);
initView(context);
}
public NGReFlashListView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public NGReFlashListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
private void initView(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
header = inflater.inflate(R.layout.layout_heard, null);
measureView(header);
headerHeight = header.getMeasuredHeight();
topPadding(-headerHeight);
this.addHeaderView(header);
this.setOnScrollListener(this);
}
private void measureView(View view) {
ViewGroup.LayoutParams p = view.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);
int height;
int tempHeight = p.height;
if (tempHeight > 0) {
height = MeasureSpec.makeMeasureSpec(tempHeight,
MeasureSpec.EXACTLY);
} else {
height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
view.measure(width, height);
}
private void topPadding(int topPadding) {
header.setPadding(header.getPaddingLeft(), topPadding,
header.getPaddingRight(), header.getPaddingBottom());
header.invalidate();
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
this.firstVisibleItem = firstVisibleItem;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.scrollState = scrollState;
}
boolean isRemark;//初始化标识
int startY;
int state;
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (firstVisibleItem == 0) {
onRlvScrollListener.onScrollYChangged(0, 0);
isRemark = true;
startY = (int) ev.getY();
}
break;
case MotionEvent.ACTION_MOVE:
onMove(ev);
break;
case MotionEvent.ACTION_UP:
if (state == RELESE) {
onRlvScrollListener.onScrollYChangged(0, 3);
state = REFLASHING;
reflashViewByState();
//iReflashListener.onReflash();
} else if (state == PULL) {
state = NONE;
onRlvScrollListener.onScrollYChangged(0, 0);
isRemark = false;
reflashViewByState();
}
break;
}
return super.onTouchEvent(ev);
}
int space; //间距
int topPadding; //headview距离顶端的距离,初始-200
private void onMove(MotionEvent ev) {
if (!isRemark) {
return;
}
int tempY = (int) ev.getY();
space = tempY - startY;
if (space >= 230) {
space = 230;
}
topPadding = space - headerHeight;
onRlvScrollListener.onScrollYChangged(space, state);
switch (state) {
case NONE:
if (space > 0) {
state = PULL;
reflashViewByState();
}
break;
case PULL:
topPadding(topPadding);
if (space == headerHeight + 30
&& scrollState == SCROLL_STATE_TOUCH_SCROLL) {
state = RELESE;
reflashViewByState();
}
break;
case RELESE:
if (space < headerHeight + 30) {
state = PULL;
reflashViewByState();
} else if (space <= 0) {
state = NONE;
isRemark = false;
reflashViewByState();
}
break;
}
}
private void reflashViewByState() {
switch (state) {
case NONE:
//缓慢滑上去
topPadding(-headerHeight);
break;
case PULL:
break;
case RELESE:
break;
case REFLASHING:
break;
}
}
public void reflashComplete() {
state = NONE;
onRlvScrollListener.onScrollYChangged(0, state);
isRemark = false;
reflashViewByState();
}
//绘制背景的接口
public interface OnRlvScrollListener {
void onScrollYChangged(int Y, int state);
}
private OnRlvScrollListener onRlvScrollListener;
public void setOnRlvScrollListener(OnRlvScrollListener onRlvScrollListener) {
this.onRlvScrollListener = onRlvScrollListener;
}
}
NGImgView.java
实现比较简单,根据传来的回调状态改变进行小太阳和两只球球手以及手臂的绘制就可以了。
package location.haidian.com.wypulltoreflush.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
import location.haidian.com.wypulltoreflush.R;
public class NGImgView extends ImageView implements NGReFlashListView.OnRlvScrollListener {
private float scale;
private final int NONE = 0;
private final int PULL = 1;
private final int RELESE = 2;
private final int REFLASHING = 3;
public int state = 0;
private float WITH; //屏幕总宽
private float scrollY;
private Bitmap sun0;
public float time = 0;
public NGImgView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
private void initView() {
sun0 = ((BitmapDrawable) getResources().getDrawable(R.drawable.ic_sun0)).getBitmap();
scale = this.getResources().getDisplayMetrics().density;
}
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setAntiAlias(true);//抗锯齿
paint.setColor(Color.parseColor("#C4885A"));
Log.d("xiaojingyu","State:" + state);
if (state!=3) {
time = 0; //重置时间
//画两只球球手
canvas.drawCircle(WITH / 2 - 40 * scale, 55 * scale, 5 * scale, paint);
canvas.drawCircle(WITH / 2 + 40 * scale, 55 * scale, 5 * scale, paint);
//画笑脸
canvas.drawBitmap(sun0,
null,
new RectF(WITH / 2 - 50,
55 * scale + scrollY - (scrollY / 230) * 50,
WITH / 2 + 50,
55 * scale + scrollY - (scrollY / 230) * 50 + 100),
null
);
//画手臂
paint.setStrokeWidth(1);
canvas.drawLine(WITH / 2 - 40 * scale, 55 * scale,
WITH / 2 - 50, 55 * scale + scrollY,
paint
);
canvas.drawLine(WITH / 2 + 40 * scale, 55 * scale,
WITH / 2 + 50, 55 * scale + scrollY,
paint
);
} else if (state == 3) {
//1秒钟拉上去,2秒钟旋转
//第一秒
if (time < 30) {
time += 1;
//画两只球球手
canvas.drawCircle(WITH / 2 - 40 * scale, 55 * scale, 5 * scale, paint);
canvas.drawCircle(WITH / 2 + 40 * scale, 55 * scale, 5 * scale, paint);
//画笑脸
canvas.drawBitmap(sun0,
null,
new RectF(WITH / 2 - 50,
55 * scale + 180 - (time / 30) * 230,
WITH / 2 + 50,
55 * scale + 280 - (time / 30) * 230),
null
);
//画手臂
paint.setStrokeWidth(1);
canvas.drawLine(WITH / 2 - 40 * scale, 55 * scale,
WITH / 2 - 50,
55 * scale + 230 - (time / 30) * 230,
paint
);
canvas.drawLine(WITH / 2 + 40 * scale, 55 * scale,
WITH / 2 + 50,
55 * scale + 230 - (time / 30) * 230,
paint
);
postInvalidateDelayed(1);
} else {
if (!isBeginMainAnimation) {
isBeginMainAnimation = true;
iReflashListener.onReflash();
}
}
}
super.onDraw(canvas);
}
public static boolean isBeginMainAnimation = false;
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
WITH = this.getWidth();
}
@Override
public void onScrollYChangged(int Y, int state) {
this.state = state;
switch (state) {
case NONE:
break;
case PULL:
//下拉
scrollY = Y;
break;
case RELESE:
break;
case REFLASHING:
break;
}
}
private IReflashListener iReflashListener; //回调接口
public void setInterface(IReflashListener iReflashListener) {
this.iReflashListener = iReflashListener;
}
public interface IReflashListener {
void onReflash();
}
}
以上所述是小编给大家介绍的Android仿网易一元夺宝客户端下拉加载动画效果(一),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程网网站的支持!
您可能感兴趣的文章:android ListView结合xutils3仿微信实现下拉加载更多Android ListView实现下拉加载功能Android实现仿慕课网下拉加载动画Android中使用RecyclerView实现下拉刷新和上拉加载Android下拉刷新上拉加载控件(适用于所有View)Android RecyclerView实现下拉刷新和上拉加载android开发教程之实现listview下拉刷新和上拉刷新效果Android实现上拉加载更多以及下拉刷新功能(ListView)Android RecyclerView 上拉加载更多及下拉刷新功能的实现方法PullToRefreshListView实现多条目加载上拉刷新和下拉加载