본문 바로가기
프로그래밍/Android

(Android) ViewAnimation - UI 애니메이션 효과 적용하기

by LiveData 2018. 12. 21.
반응형

앱을 사용하면서 뭔가 정적인 화면만 보여주기 보다는


자연스럽게 움직이면서 사용자들에게 이해를 도와주는 애니메이션이 필수죠!


물론 xml을 이용하여 애니메이션을 만들 수 있지만...

(https://blog.naver.com/rjs5730/221239700311  - xml을 이용한 애니메이션)


라이브러리를 활용해서 더욱 편하게 만드실 수 있습니다!!




아래 보시면 샘플 예제 입니다. 


 

하단 원본코드 앱 참고




위의 그림과 같은 예제를 만들어 보려고 합니다.


물론 원본 코드와 비슷하지만 원본에는 ListView를 사용했지만 아래 예제에서는 RecyclerView를 사용해서 만들려고합니다.






VIewAnimation 예제




1. Gradle 추가하기


//RecyclerView (버전에 따라 다르게 추가해야한다.)
compile 'com.android.support:recyclerview-v7:27.1.1'

//ViewAnimation
compile 'com.daimajia.easing:library:2.0@aar'
compile 'com.daimajia.androidanimations:library:2.3@aar'



참고.


easing에 대해서 - 시간에 지남에 따라 속도라 천천히 줄거나 느리거나 하는 원리 

 : http://easings.net/ko


easing 을 활용한 예제(git)

 : https://github.com/daimajia/AnimationEasingFunctions



Q.  왜 뜬금없이 easing을 알아야 하나요?

 - 애니메이션의 원리와 추후 easing이라는 개념이 많이 등장합니다. (안드로이드 뿐만아니라 거의 모든 애니메이션에)

  




2. xml 구성하기


먼저 activity_main.xml 에서 애니메이션을 할 "hello world" text와 RecyclerView를 추가해줍니다.




activity_main.xml 코드



<?xml version="1.0" encoding="utf-8"?>
<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=".MainActivity">

<LinearLayout
android:id="@+id/wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:gravity="center"
android:layout_weight="1"
android:padding="30dp"
android:textSize="40sp"
android:id="@+id/hello_world"
android:text="hello world"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler_view"
android:layout_below="@+id/wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
 
</RelativeLayout>
 




RecyclerView에 들어갈 item의 layout을 만들어 줍니다.



recyclerview_item.xml



<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/list_item_text"
android:textSize="16sp"
android:gravity="left|center_vertical"
android:padding="10dp" />

 





3. MainActivity & Adapter


MainActivity에 RecyclerView의 선언과 Adapter연결, Touch이벤트를 만들어줍니다.




MainActivity 코드



import android.animation.Animator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.Toast;

import com.daimajia.androidanimations.library.Techniques;
import com.daimajia.androidanimations.library.YoYo;


public class MainActivity extends AppCompatActivity {

private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private YoYo.YoYoString rope;
private View target;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//Animation object 연결
target=findViewById(R.id.hello_world);

//recyclerView
recyclerView=(RecyclerView)findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

//Adapter
mAdapter=new RecyclerViewAdapter();
recyclerView.setAdapter(mAdapter);

//click event
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
if (rope != null) {
rope.stop( );
}
//클릭되는 technique을 실행
View child = rv.findChildViewUnder(e.getX(), e.getY());
int position=rv.getChildAdapterPosition(child);
Techniques technique=Techniques.values()[position];
rope = YoYo.with(technique)
.duration(1200)
.repeat(1)
.pivot(YoYo.CENTER_PIVOT, YoYo.CENTER_PIVOT)
.interpolate(new AccelerateDecelerateInterpolator())
.withListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {

}

@Override
public void onAnimationEnd(Animator animation) {
}

@Override
public void onAnimationCancel(Animator animation) {
Toast.makeText(getApplicationContext(), "canceled previous animation", Toast.LENGTH_SHORT).show();
}

@Override
public void onAnimationRepeat(Animator animation) {

}
})
.playOn(target);
return false;
}

@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {

}

@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

}
});
}
}



여기서 중요한 부분이 rope=YoYo.with(technique) 입니다.


technique로 미리 설정된 애니메이션을 사용하고


duration(1200) - 1.2초동안 애니메이션을 지속합니다.

repeat - 1이면 1회반복 (총 2회) , YoYo.INFINITE 면 무한 반복

pivot - 애니메이션의 좌표 설정

interpolate - 가속도 함수적용(AccelerateDecelerateInterpolator - 시작과끝은 감소 중간에서 증가)

withListener - 애니메이션의 이벤트


 

AccelerateDecelerateInterpolator 그래프






RecyclerView의 Adapter를 만들어줍니다.



RecyclerViewAdapter 코드



import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.daimajia.androidanimations.library.Techniques;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.SimpleViewHolder>{

private Techniques technique;

@NonNull
@Override
public SimpleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item,parent,false);
return new SimpleViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull final SimpleViewHolder holder, int position) {
technique= Techniques.values()[position];
holder.animText.setText(technique.name());
}

@Override
public int getItemCount() {
return technique.values().length;
}

public static class SimpleViewHolder extends RecyclerView.ViewHolder {

TextView animText;

public SimpleViewHolder(View itemView) {
super(itemView);
animText=(TextView)itemView.findViewById(R.id.list_item_text);

}
}
}



위 코드를 모두 완성하시면 상단 그림과 같은 애니메이션 동작을 직접 확인 하실 수 있습니다.




 

완성 예제 사진.






원본 코드

https://github.com/daimajia/AndroidViewAnimations


반응형