안 드 로 이 드 모방 왕 이 1 원 보물 쟁탈 클 라 이언 트 드 롭 다운 로 딩 애니메이션 효과(1)
원래 효 과 는(첫 번 째 부분)작은 태양 이 내 려 와 풀 고 튕 기 는 것 이다.
(두 번 째 부분)동전 하 나 를 더 떨 어 뜨 려 중축 회전 을 한다.
본 고가 실현 한 효 과 는 첫 번 째 부분 이 고 효과 시범 도 는 다음 과 같다.
Gif 그림 이 좀 끊 겨 보이 는데...사실 진짜 기계 의 시연 효 과 는 여전히 매우 유창 하 다.
다음 분석 실현 과정:
그 당시 에 시간 이 제한 되 어 있 었 기 때문에 드 롭 다운 새로 고침 구성 요소 에 쓰 지 않 았 고 단독 구성 요소 로 봉 하지 않 았 습 니 다.메 인 레이아웃 뒤에 View 를 써 서 해당 하 는 동작 을 실 현 했 습 니 다.봉 인 된 것 은 어렵 지 않 습 니 다.여 기 는 시간 이 걸 리 지 않 습 니 다.다음은 레이아웃 파일 입 니 다.
<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>
레이아웃 파일 미리 보기:투명 하 게 설정 되 어 있 기 때문에 아 이 템 이 없 는 상태 에서 뒤의 레이아웃 을 볼 수 있 습 니 다.
코드 구현:
드 롭 다운 리 셋 클래스 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);
}
/**
* @param 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);
}
/**
* @param view
*/
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);
}
/**
* @param topPadding
*/
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
/**
* @param ev
*/
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;
/**
* Created by nangua on 2016/8/28.
*/
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;
}
/**
* @author Administrator
*/
public interface IReflashListener {
void onReflash();
}
}
위 에서 말 한 것 은 소 편 이 여러분 에 게 소개 한 안 드 로 이 드 모방 왕 이 1 원 탈 보 클 라 이언 트 드 롭 다운 로 딩 애니메이션 효과(1)입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 저 에 게 메 시 지 를 남 겨 주세요.소 편 은 신속하게 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.