Android 신축 탄력 분포 메뉴 효과 구현 예시
=군말 이 많 지 않 은 지,낡은 규칙 인지,먼저 실현 의 효과 도 를 살 펴 보 자.
=위의 그림 에서 메뉴 팝 업 효 과 를 직선 형 으로 설정 하고 마지막 팝 업 이나 집합 점 은 아래 빨간색 단추 에 있 습 니 다.
그것 의 실현 원 리 는 애니메이션 을 설정 하 는 동시에 애니메이션 의 삽입 기(interpolator)를 이용 하여 탄력 을 실현 하 는 것 이다.주로 Overshoot Interpolator 와 Anticipate Overshoot Interpolator 를 사용 하여 이 두 개의 삽입 기 를 간단하게 소개 합 니 다.
먼저 MainActivity 의 코드 를 알 아 보 겠 습 니 다.다음 과 같 습 니 다.
package com.spring.menu.activity;
import com.spring.menu.R;
import com.spring.menu.animation.SpringAnimation;
import com.spring.menu.animation.EnlargeAnimationOut;
import com.spring.menu.animation.ShrinkAnimationOut;
import com.spring.menu.animation.ZoomAnimation;
import com.spring.menu.utility.DeviceUtility;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.AnticipateInterpolator;
import android.widget.RelativeLayout;
/**
* Android
* @Description: Android
* @File: MainActivity.java
* @Package com.spring.menu.activity
* @Author Hanyonglu
* @Date 2012-10-25 09:41:31
* @Version V1.0
*/
public class MainActivity extends Activity {
private boolean areMenusShowing;
private ViewGroup menusWrapper;
private View imageViewPlus;
private View shrinkRelativeLayout;
private RelativeLayout layoutMain;
//
private Animation animRotateClockwise;
//
private Animation animRotateAntiClockwise;
private Class<?>[] intentActivity = {
SecondActivity.class,ThreeActivity.class,FourActivity.class,
SecondActivity.class,ThreeActivity.class,FourActivity.class};
private int[] mainResources = {
R.drawable.bg_main_1,R.drawable.bg_main_2,
R.drawable.bg_main_3,R.drawable.bg_main_4,
R.drawable.bg_main_1,R.drawable.bg_main_4};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//
initViews();
}
//
private void initViews(){
imageViewPlus = findViewById(R.id.imageview_plus);
menusWrapper = (ViewGroup) findViewById(R.id.menus_wrapper);
shrinkRelativeLayout = findViewById(R.id.relativelayout_shrink);
layoutMain = (RelativeLayout) findViewById(R.id.layout_content);
animRotateClockwise = AnimationUtils.loadAnimation(
this,R.anim.rotate_clockwise);
animRotateAntiClockwise = AnimationUtils.loadAnimation(
this,R.anim.rotate_anticlockwise);
shrinkRelativeLayout.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
showLinearMenus();
}
});
for (int i = 0; i < menusWrapper.getChildCount(); i++) {
menusWrapper.getChildAt(i).setOnClickListener(
new SpringMenuLauncher(null,mainResources[i]));
}
}
/**
*
*/
private void showLinearMenus() {
int[] size = DeviceUtility.getScreenSize(this);
if (!areMenusShowing) {
SpringAnimation.startAnimations(
this.menusWrapper, ZoomAnimation.Direction.SHOW, size);
this.imageViewPlus.startAnimation(this.animRotateClockwise);
} else {
SpringAnimation.startAnimations(
this.menusWrapper, ZoomAnimation.Direction.HIDE, size);
this.imageViewPlus.startAnimation(this.animRotateAntiClockwise);
}
areMenusShowing = !areMenusShowing;
}
//
private class SpringMenuLauncher implements OnClickListener {
private final Class<?> cls;
private int resource;
private SpringMenuLauncher(Class<?> c,int resource) {
this.cls = c;
this.resource = resource;
}
public void onClick(View v) {
// TODO Auto-generated method stub
MainActivity.this.startSpringMenuAnimations(v);
layoutMain.setBackgroundResource(resource);
// MainActivity.this.startActivity(
// new Intent(
// MainActivity.this,
// MainActivity.SpringMenuLauncher.this.cls));
}
}
/**
*
* @param view
* @param runnable
*/
private void startSpringMenuAnimations(View view) {
areMenusShowing = true;
Animation shrinkOut1 = new ShrinkAnimationOut(300);
Animation growOut = new EnlargeAnimationOut(300);
shrinkOut1.setInterpolator(new AnticipateInterpolator(2.0F));
shrinkOut1.setAnimationListener(new Animation.AnimationListener() {
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
MainActivity.this.imageViewPlus.clearAnimation();
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
});
view.startAnimation(growOut);
}
}
빨간색 단 추 를 눌 렀 을 때 맨 위 에 있 는 메뉴 를 팝 업 하고 어떤 메뉴 를 눌 렀 을 때 위의 배경 그림 을 바 꾸 면 물론 특정한 Activity 에 직접 들 어 갈 수 있 습 니 다.그래서 위 에서 intent Activity 와 mainrources 두 개의 배열 을 정 의 했 는데 각각 전환 할 Activity 와 변환 할 그림 을 대표 합 니 다.여러분 은 실제 수요 에 따라 설정 할 수 있 습 니 다.빨간색 단 추 를 눌 렀 을 때 중간 에 있 는 플러스 번 호 를 오른쪽으로 225 도 회전 시 켜 포크 번호 로 바 꾸 고 다음 과 같은 애니메이션 을 통 해:
<?xml version="1.0" encoding="UTF-8"?>
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:duration="200"
android:fromDegrees="0.0"
android:toDegrees="225.0"
android:pivotX="50.0%"
android:pivotY="50.0%"
android:fillAfter="true"
android:fillEnabled="true"/>
다시 클릭 하면 왼쪽으로 회전 하여 복원 합 니 다.위의 android:from Degrees 와 android:toDegrees 를 교체 하면 됩 니 다.다음 중요 한 애니메이션 유형 은 SpringAnimation 입 니 다.각 메뉴 의 애니메이션 효 과 를 제어 합 니 다.코드 는 다음 과 같 습 니 다.
package com.spring.menu.animation;
import com.spring.menu.control.ImageButtonExtend;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.OvershootInterpolator;
import android.view.animation.TranslateAnimation;
/**
*
* @Description:
* @File: SpringAnimation.java
* @Package com.spring.menu.animation
* @Author Hanyonglu
* @Date 2012-10-25 12:18:39
* @Version V1.0
*/
public class SpringAnimation extends ZoomAnimation {
private static int[] size;
private static int xOffset = 210;
private static int yOffset = -15;
public static final int DURATION = 300;
/**
*
* @param direction
* @param duration
* @param view
*/
public SpringAnimation(Direction direction, long duration, View view) {
super(direction, duration, new View[] { view });
SpringAnimation.xOffset = SpringAnimation.size[0] / 2 - 30;
}
/**
*
* @param viewgroup
* @param direction
* @param size
*/
public static void startAnimations(ViewGroup viewgroup,
ZoomAnimation.Direction direction, int[] size) {
SpringAnimation.size = size;
switch (direction) {
case HIDE:
startShrinkAnimations(viewgroup);
break;
case SHOW:
startEnlargeAnimations(viewgroup);
break;
}
}
/**
*
* @param viewgroup
*/
private static void startEnlargeAnimations(ViewGroup viewgroup) {
for (int i = 0; i < viewgroup.getChildCount(); i++) {
if (viewgroup.getChildAt(i) instanceof ImageButtonExtend) {
ImageButtonExtend inoutimagebutton = (ImageButtonExtend) viewgroup
.getChildAt(i);
SpringAnimation animation = new SpringAnimation(
ZoomAnimation.Direction.HIDE, DURATION, inoutimagebutton);
animation.setStartOffset((i * 200)
/ (-1 + viewgroup.getChildCount()));
animation.setInterpolator(new OvershootInterpolator(4F));
inoutimagebutton.startAnimation(animation);
}
}
}
/**
*
* @param viewgroup
*/
private static void startShrinkAnimations(ViewGroup viewgroup) {
for (int i = 0; i < viewgroup.getChildCount(); i++) {
if (viewgroup.getChildAt(i) instanceof ImageButtonExtend) {
ImageButtonExtend inoutimagebutton = (ImageButtonExtend) viewgroup
.getChildAt(i);
SpringAnimation animation = new SpringAnimation(
ZoomAnimation.Direction.SHOW, DURATION,
inoutimagebutton);
animation.setStartOffset((100 * ((-1 + viewgroup
.getChildCount()) - i))
/ (-1 + viewgroup.getChildCount()));
animation.setInterpolator(new AnticipateOvershootInterpolator(2F));
inoutimagebutton.startAnimation(animation);
}
}
}
@Override
protected void addShrinkAnimation(View[] views) {
// TODO Auto-generated method stub
MarginLayoutParams mlp = (MarginLayoutParams) views[0].
getLayoutParams();
addAnimation(new TranslateAnimation(
xOffset + -mlp.leftMargin,
0F,yOffset + mlp.bottomMargin, 0F));
}
@Override
protected void addEnlargeAnimation(View[] views) {
// TODO Auto-generated method stub
MarginLayoutParams mlp = (MarginLayoutParams) views[0].
getLayoutParams();
addAnimation(new TranslateAnimation(
0F, xOffset + -mlp.leftMargin,
0F,yOffset + mlp.bottomMargin));
}
}
이 종 류 는 ZoomAnimation 에서 계승 합 니 다.ZoomAnimation 코드 는 다음 과 같 습 니 다.
package com.spring.menu.animation;
import android.view.View;
import android.view.animation.AnimationSet;
/**
*
* @Description:
* @File: ZoomAnimation.java
* @Package com.spring.menu.animation
* @Author Hanyonglu
* @Date 2012-10-25 11:37:52
* @Version V1.0
*/
public abstract class ZoomAnimation extends AnimationSet {
public Direction direction;
public enum Direction {
HIDE, SHOW;
}
public ZoomAnimation(Direction direction, long duration, View[] views) {
super(true);
this.direction = direction;
switch (this.direction) {
case HIDE:
addShrinkAnimation(views);
break;
case SHOW:
addEnlargeAnimation(views);
break;
}
setDuration(duration);
}
protected abstract void addShrinkAnimation(View[] views);
protected abstract void addEnlargeAnimation(View[] views);
}
때때로 우 리 는 사용자 체험 을 강화 하기 위해 직선 을 반원형 이나 반원형 으로 설정 할 수 있 으 며,Bresenham 알고리즘 이나 다른 방안 을 이용 하여 반원 이나 반원 의 메뉴 를 만 들 수 있 으 며,메뉴 를 간단하게 어 딘 가 에 위치 시 키 는 것 이 아 닙 니 다.이것 에 대해 관심 이 있 는 친 구 는 관련 자 료 를 참고 하여 그것 을 실현 할 수 있다.또한 위의 예 는 동적 설정 메뉴 의 개 수 를 실현 하지 않 았 다.개인 적 으로 메뉴 의 레이아웃 을 동적 으로 설정 하 는 것 이 좋 습 니 다.메뉴 를 추가 하거나 줄 일 때 편리 합 니 다.일반적인 과정 은 하나의 배열(그림 자원 대표)을 이용 하여 배열 에 따라 구 조 를 실현 하 는 것 이다.상단 에서 언급 한 반원형 전개 실현 도 동적 으로 설정 해 야 한다.원래 나 는 그것 을 실현 하고 싶 었 지만,정말 그렇게 많은 시간 이 없 었 다.필요 한 친구 가 프로그램 을 채 울 수 있 는 SpringMenu Layout 류 가 있 었 다.여기 서 나 는 그것 을 실현 하지 않 았 다.
package com.spring.menu.layout;
/**
*
* @Description:
* @File: SpringMenuLayout.java
* @Package com.spring.menu.layout
* @Author Hanyonglu
* @Date 2012-10-26 07:57:56
* @Version V1.0
*/
public class SpringMenuLayout {
//
//
}
이상 은 안 드 로 이 드 에서 신축 탄력 분포 메뉴 효 과 를 실현 하 는 과정 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.