안 드 로 이 드 바 이 두 배달 사용자 정의 드 롭 다운 리 셋 효과
실현 효 과 를 살 펴 보 자.
애니메이션
우리 먼저 안 드 로 이 드 의 애니메이션 을 봅 시다.
Android 의 애니메이션 은 세 가지 로 나 뉜 다.
Tween 애니메이션 은 회전,이동,크기 조정 등 효 과 를 제공 합 니 다.
알파 C 페 이 드 아웃
Scale C 크기 조정 효과
Roate C 회전 효과
번역 C 평이 효과
Frame 애니메이션(프레임 애니메이션),이러한 애니메이션 은 Drawable 시퀀스 를 만 들 고 지 정 된 시간 에 따라 하나씩 표시 할 수 있 습 니 다.
Property 애니메이션(속성 애니메이션),Android 3.0 이후 에 도 입 된 속성 애니메이션 은 대상 의 실제 속성 을 변경 합 니 다.
분석 하 다.
우 리 는 바 이 두 배달 의 드 롭 다운 새로 고침 의 머리 는 자전 거 를 탄 택배 기사 가 길에서 질주 하 는 것 을 볼 수 있다.우리 가 아래 의 애니메이션 을 얻 은 것 을 분석 해 보 자.
배경 그림 의 이동 애니메이션
태양의 자전 애니메이션
두 개의 작은 바퀴 의 자전 애니메이션
이것 은 매우 간단 합 니 다.그 다음 에 우 리 는 바 이 두 밖의 이미지 자원 파일 에서 이 몇 장의 사진 을 찾 았 습 니 다.(바 이 두 배달 의 apk 를 다운로드 하여 직접 압축 을 풀 면 됩 니 다)
드 롭 다운 리 셋 헤더 파일 정의:headview.xml
여기 주의:배경 그림 두 장의 ImageView 를 정의 한 것 은 배경의 이동 애니메이션 효 과 를 실현 하기 위해 서 입 니 다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_back1"
android:src="@drawable/pull_back"
android:layout_width="match_parent"
android:layout_height="100dp" />
<ImageView
android:id="@+id/iv_back2"
android:src="@drawable/pull_back"
android:layout_width="match_parent"
android:layout_height="100dp" />
<RelativeLayout
android:id="@+id/main"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_marginTop="45dp"
android:id="@+id/iv_rider"
android:background="@drawable/pull_rider"
android:layout_width="50dp"
android:layout_height="50dp" />
<ImageView
android:id="@+id/wheel1"
android:layout_marginLeft="10dp"
android:layout_marginTop="90dp"
android:background="@drawable/pull_wheel"
android:layout_width="15dp"
android:layout_height="15dp" />
<ImageView
android:id="@+id/wheel2"
android:layout_marginLeft="40dp"
android:layout_marginTop="90dp"
android:background="@drawable/pull_wheel"
android:layout_width="15dp"
android:layout_height="15dp" />
</RelativeLayout>
<ImageView
android:id="@+id/ivsun"
android:layout_marginTop="20dp"
android:layout_toRightOf="@+id/main"
android:background="@drawable/pull_sun"
android:layout_width="30dp"
android:layout_height="30dp" />
</RelativeLayout>
다음은 애니메이션 효 과 를 정의 합 니 다.배경 그림 의 이동 효과:
두 개의 animation xml 파일 을 실현 합 니 다.하나의 시작 위 치 는 100%이 고 끝 위 치 는 0%입 니 다.repeat 속성 을 반복 으로 설정 합 니 다.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromXDelta="100%p" android:toXDelta="0%p"
android:repeatMode="restart"
android:interpolator="@android:anim/linear_interpolator"
android:repeatCount="infinite"
android:duration="5000" />
</set>
다른 시작 위 치 는 0%,끝 위 치 는-100%입 니 다.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromXDelta="0%p" android:toXDelta="-100%p"
android:repeatMode="restart"
android:interpolator="@android:anim/linear_interpolator"
android:repeatCount="infinite"
android:duration="5000" />
</set>
태양 중심 회전 애니메이션:0-360 도 에서 순환 회전 을 시작 하여 회전 하 는 데 사용 되 는 시간 은 1s 이 고 회전 중심 거 리 는 view 의 왼쪽 정점 상단 가장자리 가 50%의 거리,즉 중심 이다.
다음은 구체 적 인 속성:
android:from Degrees 시작 각도 도수
안 드 로 이 드:toDegrees 가 끝 난 각도 도 수 는 시계 반대 방향 을 나타 내 고 정 수 는 시계 반대 방향 을 나타 낸다.10 바퀴 돌 면 안 드 로 이 드:from Degrees 보다 3600 크 면 됩 니 다.
android:pivotx 회전 중심의 X 좌표
부동 소수점 이나 백분율.부동 소수점 은 Object 의 왼쪽 가장자리 에 비해 5 와 같다.백분율 은 Object 의 왼쪽 가장자리 에 비해 5%를 나타 낸다.다른 백분율 은 부모 용기 의 왼쪽 가장자리,예 를 들 어 5%p 를 나타 낸다.보통 50%로 설정 하면 Object 센터 에서
안 드 로 이 드:pivoty 회전 중심 Y 좌표
부동 소수점 이나 백분율.부동 소수점 은 Object 의 상단 가장자리 에 비해 5 와 같다 는 것 을 나타 낸다.백분율 은 Object 의 상단 가장자리 에 비해 5%를 나타 낸다.다른 백분율 은 부모 용기 의 상단 가장자리,예 를 들 어 5%p 를 나타 낸다.보통 50%로 설정 하면 Object 센터 에서
android:duration 은 android:from Degrees 에서 android:toDegrees 로 돌아 가 는 데 걸 리 는 시간 을 표시 합 니 다.단 위 는 밀리초 입 니 다.속 도 를 계산 하 는 데 쓸 수 있다.
android:interpolator 는 변화 율 을 표시 하지만 운행 속 도 는 아 닙 니 다.하나의 삽입 속성 으로 애니메이션 효 과 를 가속,감속,반복,반등 등 으로 설정 할 수 있 습 니 다.기본 값 은 시작 과 끝 이 느 리 고 중간 이 빠 르 고,
android:startOffset 는 start 함 수 를 호출 한 후에 실행 시작 시간 을 기다 리 고 단 위 는 밀리초 입 니 다.10 이면 10ms 를 표시 한 후에 실행 을 시작 합 니 다.
android:repeatCount 중복 횟수,기본 값 0,int 여야 합 니 다.-1 로 멈 추 지 않 음 을 표시 할 수 있 습 니 다.
안 드 로 이 드:repeat 모드 가 반복 되 는 모드 입 니 다.기본 값 은 restart 입 니 다.즉,다시 시작 하 는 것 입 니 다.reverse 즉 끝 에서 앞으로 다시 실행 할 수 있 습 니 다.android:repeat Count 가 0 이상 이거 나 infinite 일 때 유효 합 니 다.
android:detachWallpaper 는 벽지 에서 실행 할 지 여 부 를 표시 합 니 다.
android:zAdjustment 는 animated 의 내용 이 실 행 될 때 z 축 에 있 는 위 치 를 표시 합 니 다.기본 값 은 normal 입 니 다.
normal 내용 현재 z 축 순서 유지
top 실행 시 맨 위 에 표시
bottom 실행 시 맨 밑 에 표시
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:duration="1000"
android:repeatCount="-1"
android:pivotX="50%"
android:pivotY="50%" />
</set>
바퀴 애니메이션 도 마찬가지 로 코드 를 차지 하지 않 습 니 다.애니메이션 정의 가 끝 났 습 니 다.우 리 는 드 롭 다운 리 셋 목록 을 정의 하기 시 작 했 습 니 다.드 롭 다운 리 셋 은 인터넷 에 많 습 니 다.상세 하 게 말 하지 않 고 간단하게 개조 하고 리 셋 상태 에 따라 애니메이션 을 닫 으 면 됩 니 다.
주석 이 상세 하 게 쓰 여 있 습 니 다.코드 를 보 세 요.
package com.hankkin.baidugoingrefreshlayout;
import android.widget.AbsListView;
import android.widget.ListView;
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.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.RelativeLayout;
/**
* Created by Hankkin on 16/4/10.
*/
public class BaiDuRefreshListView extends ListView implements AbsListView.OnScrollListener{
private static final int DONE = 0; //
private static final int PULL_TO_REFRESH = 1; //
private static final int RELEASE_TO_REFRESH = 2; //
private static final int REFRESHING = 3; //
private static final int RATIO = 3;
private RelativeLayout headView; //
private int headViewHeight; //
private float startY; // Y
private float offsetY; //Y
private OnBaiduRefreshListener mOnRefreshListener; //
private int state; //
private int mFirstVisibleItem; // item
private boolean isRecord; //
private boolean isEnd; //
private boolean isRefreable; //
private ImageView ivWheel1,ivWheel2; //
private ImageView ivRider; //
private ImageView ivSun,ivBack1,ivBack2; // 、 1、 2
private Animation wheelAnimation,sunAnimation; // 、
private Animation backAnimation1,backAnimation2; //
public BaiDuRefreshListView(Context context) {
super(context);
init(context);
}
public BaiDuRefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public BaiDuRefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public interface OnBaiduRefreshListener{
void onRefresh();
}
/**
* , listview
* @param onRefreshListener
*/
public void setOnBaiduRefreshListener(OnBaiduRefreshListener onRefreshListener){
mOnRefreshListener = onRefreshListener;
isRefreable = true;
}
/**
* , , headerView
*/
public void setOnRefreshComplete(){
// isEnd true,
isEnd = true;
state = DONE;
changeHeaderByState(state);
}
private void init(Context context) {
// view OverScroll
setOverScrollMode(OVER_SCROLL_NEVER);
setOnScrollListener(this);
//
headView = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.headview,this,false);
//
measureView(headView);
// ListView
addHeaderView(headView);
// ListView
headViewHeight = headView.getMeasuredHeight();
headView.setPadding(0, -headViewHeight, 0, 0);
//
ivRider = (ImageView) headView.findViewById(R.id.iv_rider);
ivSun = (ImageView) headView.findViewById(R.id.ivsun);
ivWheel1 = (ImageView) headView.findViewById(R.id.wheel1);
ivWheel2 = (ImageView) headView.findViewById(R.id.wheel2);
ivBack1 = (ImageView) headView.findViewById(R.id.iv_back1);
ivBack2 = (ImageView) headView.findViewById(R.id.iv_back2);
//
wheelAnimation = AnimationUtils.loadAnimation(context, R.anim.tip);
sunAnimation = AnimationUtils.loadAnimation(context, R.anim.tip1);
backAnimation1 = AnimationUtils.loadAnimation(context, R.anim.a);
backAnimation2 = AnimationUtils.loadAnimation(context, R.anim.b);
state = DONE;
isEnd = true;
isRefreable = false;
}
@Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
mFirstVisibleItem = firstVisibleItem;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (isEnd) {// , , , onRefreshComplete
if (isRefreable) {// setOnMeiTuanListener true
switch (ev.getAction()){
//
case MotionEvent.ACTION_DOWN:
// listview y
if (mFirstVisibleItem == 0 && !isRecord) {
// isRecord true, y
isRecord = true;
// y startY y
startY = ev.getY();
}
break;
//
case MotionEvent.ACTION_MOVE:
// y , startY offsetY
float tempY = ev.getY();
// listview y
if (mFirstVisibleItem == 0 && !isRecord) {
isRecord = true;
startY = tempY;
}
// , y
if (state!=REFRESHING && isRecord ) {
// y
offsetY = tempY - startY;
//
float currentHeight = (-headViewHeight+offsetY/3);
// headerView 0 1
float currentProgress = 1+currentHeight/headViewHeight;
// 1 , 1,
if (currentProgress>=1) {
currentProgress = 1;
}
// , y
if (state == RELEASE_TO_REFRESH && isRecord) {
setSelection(0);
// headerView
if (-headViewHeight+offsetY/RATIO<0) {
//
state = PULL_TO_REFRESH;
// headerView,
changeHeaderByState(state);
// y 0, headerView
}else if (offsetY<=0) {
// done
state = DONE;
stopAnim();
// headerView,
changeHeaderByState(state);
}
}
// y
if (state == PULL_TO_REFRESH && isRecord) {
setSelection(0);
// headerView
if (-headViewHeight+offsetY/RATIO>=0) {
//
state = RELEASE_TO_REFRESH;
// headerView,
changeHeaderByState(state);
// y 0, headerView
}else if (offsetY<=0) {
// done
state = DONE;
// headerView,
changeHeaderByState(state);
}
}
// done y
if (state == DONE && isRecord) {
// 0
if (offsetY>=0) {
//
state = PULL_TO_REFRESH;
changeHeaderByState(state);
}
}
//
if (state == PULL_TO_REFRESH) {
// headerView padding
headView.setPadding(0,(int)(-headViewHeight+offsetY/RATIO) ,0,0);
}
//
if (state == RELEASE_TO_REFRESH) {
// headerView padding
headView.setPadding(0,(int)(-headViewHeight+offsetY/RATIO) ,0, 0);
}
}
break;
//
case MotionEvent.ACTION_UP:
//
if (state == PULL_TO_REFRESH) {
// headerView
this.smoothScrollBy((int)(-headViewHeight+offsetY/RATIO)+headViewHeight, 500);
// headerView
changeHeaderByState(state);
}
//
if (state == RELEASE_TO_REFRESH) {
// headerView
this.smoothScrollBy((int)(-headViewHeight+offsetY/RATIO), 500);
//
state = REFRESHING;
// onRefresh
mOnRefreshListener.onRefresh();
// headerView
changeHeaderByState(state);
}
// , y isRecord false,
isRecord = false;
break;
}
}
}
return super.onTouchEvent(ev);
}
/**
* headerView
* @param state
*/
private void changeHeaderByState(int state){
switch (state) {
case DONE://
// headerView padding
headView.setPadding(0, -headViewHeight, 0, 0);
startAnim();
break;
case RELEASE_TO_REFRESH://
break;
case PULL_TO_REFRESH://
startAnim();
break;
case REFRESHING://
break;
default:
break;
}
}
/**
* View
* @param child
*/
private void measureView(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
/**
*
*/
public void startAnim(){
ivBack1.startAnimation(backAnimation1);
ivBack2.startAnimation(backAnimation2);
ivSun.startAnimation(sunAnimation);
ivWheel1.startAnimation(wheelAnimation);
ivWheel2.startAnimation(wheelAnimation);
}
/**
*
*/
public void stopAnim(){
ivBack1.clearAnimation();
ivBack2.clearAnimation();
ivSun.clearAnimation();
ivWheel1.clearAnimation();
ivWheel2.clearAnimation();
}
}
자,사용자 정의 드 롭 다운 리 셋 애니메이션 을 우 리 는 실현 할 수 있 습 니 다.사실은 간단 합 니 다.모든 드 롭 다운 리 셋 애니메이션 은 이렇게 이 루어 집 니 다.소스 코드 는 Github 에 올 렸 습 니 다.https://github.com/Hankkin/BaiduGoingRefreshLayout
스타 한테 부탁 해.불합리한 점 이 있 으 면 많은 지적 과 함께 발전 하 시기 바 랍 니 다.
안 드 로 이 드 바 이 두 배달 사용자 정의 드 롭 다운 리 셋 효과 에 대해 서 는 여기까지 소개 해 드 리 겠 습 니 다.도움 이 되 셨 으 면 좋 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.