Programing

Android에서 뷰 배경색의 애니메이션 변경

lottogame 2020. 3. 12. 08:06
반응형

Android에서 뷰 배경색의 애니메이션 변경


Android에서 뷰의 배경색 변경을 어떻게 애니메이션합니까?

예를 들면 다음과 같습니다.

빨간색 배경색으로 볼 수 있습니다. 뷰의 배경색이 파란색으로 바뀝니다. 색상 사이를 부드럽게 전환하려면 어떻게해야합니까?

뷰를 사용하여이 작업을 수행 할 수 없으면 다른 방법을 환영합니다.


나는이 문제에 대한 (꽤 좋은) 해결책을 알아 냈습니다!

TransitionDrawable 을 사용하여이 작업을 수행 할 수 있습니다 . 예를 들어 드로어 블 폴더의 XML 파일에서 다음과 같이 작성할 수 있습니다.

<?xml version="1.0" encoding="UTF-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- The drawables used here can be solid colors, gradients, shapes, images, etc. -->
    <item android:drawable="@drawable/original_state" />
    <item android:drawable="@drawable/new_state" />
</transition>

그런 다음 실제보기의 XML에서 android:background속성 에서이 TransitionDrawable을 참조 합니다.

이 시점에서 다음을 수행하여 명령에 따라 코드 전환을 시작할 수 있습니다.

TransitionDrawable transition = (TransitionDrawable) viewObj.getBackground();
transition.startTransition(transitionTime);

또는 다음을 호출하여 전환을 반대로 실행하십시오.

transition.reverseTransition(transitionTime);

이 답변이 처음 게시 된 시점에는 사용할 수 없었던 Property Animation API를 사용하는 다른 솔루션에 대한 Roman의 답변참조하십시오 .


컬러 애니메이션에 새로운 속성 애니메이션 API사용할 수 있습니다 .

int colorFrom = getResources().getColor(R.color.red);
int colorTo = getResources().getColor(R.color.blue);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(250); // milliseconds
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(ValueAnimator animator) {
        textView.setBackgroundColor((int) animator.getAnimatedValue());
    }

});
colorAnimation.start();

Android 2.x와의 호환성을 위해 Jake Wharton의 Nine Old Androids 라이브러리사용하십시오 .

getColor방법은 Android M에서 더 이상 사용되지 않으므로 다음 두 가지 중에서 선택할 수 있습니다.

  • 지원 라이브러리를 사용하는 경우 getColor통화를 다음과 같이 바꿔야합니다 .

    ContextCompat.getColor(this, R.color.red);
    
  • 지원 라이브러리를 사용하지 않는 경우 getColor통화를 다음과 같이 바꿔야합니다 .

    getColor(R.color.red);
    

뷰의 배경색을 얻는 방법과 대상 색을 얻는 방법에 따라 여러 가지 방법이 있습니다.

처음 두 개는 Android 속성 애니메이션 프레임 워크를 사용합니다 .

다음과 같은 경우 Object Animator를 사용하십시오 .

  • 뷰의 배경색 argb이 xml 파일 값으로 정의되어 있습니다.
  • 뷰의 색상이 이전에 설정되었습니다 view.setBackgroundColor()
  • 뷰의 배경색은 드로어 블에 정의되어 있으며 획 또는 모서리 반경과 같은 추가 속성을 정의 하지 않습니다 .
  • 뷰의 배경색이 드로어 블에 정의되어 있고 획 또는 모서리 반경과 같은 추가 속성을 제거하려는 경우 추가 속성을 제거해도 애니메이션이 적용되지 않습니다.

객체 애니메이터 view.setBackgroundColor는 정의 된 드로어 블 ColorDrawable이 거의 인스턴스가 아닌 한 정의 된 드로어 블을 대체하여 호출 하여 작동 합니다 . 즉, 획 또는 모서리와 같은 드로어 블의 추가 배경 속성이 제거됩니다.

다음과 같은 경우 Value Animator를 사용하십시오 .

  • 뷰에는 배경색이 드로어 블에 정의되어 있으며 획 또는 모서리 반경과 같은 속성을 설정하고 실행 중에 결정된 새 색상으로 변경하려고합니다.

다음과 같은 경우 전환 드로어 블을 사용하십시오 .

  • 뷰는 배치 전에 정의 된 두 드로어 블 사이를 전환해야합니다.

해결할 수 없었던 DrawerLayout을 여는 동안 실행되는 전환 드로어 블에 성능 문제가 있었으므로 예기치 않은 말더듬이 발생하면 같은 버그가 발생했을 수 있습니다.

StateList 드로어 블 또는 LayerLists 드로어 을 사용하려면 Value Animator 예제를 수정해야합니다 . 그렇지 않으면 final GradientDrawable background = (GradientDrawable) view.getBackground();줄에서 충돌이 발생 합니다.

오브젝트 애니메이터 :

정의보기 :

<View
    android:background="#FFFF0000"
    android:layout_width="50dp"
    android:layout_height="50dp"/>

ObjectAnimator이런 식으로 만들고 사용 하십시오.

final ObjectAnimator backgroundColorAnimator = ObjectAnimator.ofObject(view,
                                                                       "backgroundColor",
                                                                       new ArgbEvaluator(),
                                                                       0xFFFFFFFF,
                                                                       0xff78c5f9);
backgroundColorAnimator.setDuration(300);
backgroundColorAnimator.start();

XMight가 Android 객체 에서하는 것과 같은 AnimatorInflater를 사용하여 XML에서 애니메이션 정의를로드 할 수도 있습니다.

가치 애니메이터 :

정의보기 :

<View
    android:background="@drawable/example"
    android:layout_width="50dp"
    android:layout_height="50dp"/>

드로어 블 정의 :

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#FFFFFF"/>
    <stroke
        android:color="#edf0f6"
        android:width="1dp"/>
    <corners android:radius="3dp"/>

</shape>

다음과 같이 ValueAnimator를 만들고 사용하십시오.

final ValueAnimator valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(),
                                                           0xFFFFFFFF,
                                                           0xff78c5f9);

final GradientDrawable background = (GradientDrawable) view.getBackground();
currentAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(final ValueAnimator animator) {
        background.setColor((Integer) animator.getAnimatedValue());
    }

});
currentAnimation.setDuration(300);
currentAnimation.start();

전환 드로어 블 :

정의보기 :

<View
    android:background="@drawable/example"
    android:layout_width="50dp"
    android:layout_height="50dp"/>

드로어 블 정의 :

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="#FFFFFF"/>
            <stroke
                android:color="#edf0f6"
                android:width="1dp"/>
            <corners android:radius="3dp"/>
        </shape>
    </item>

    <item>
        <shape>
            <solid android:color="#78c5f9"/>
            <stroke
                android:color="#68aff4"
                android:width="1dp"/>
            <corners android:radius="3dp"/>
        </shape>
    </item>
</transition>

다음과 같이 TransitionDrawable을 사용하십시오.

final TransitionDrawable background = (TransitionDrawable) view.getBackground();
background.startTransition(300);

.reverse()애니메이션 인스턴스를 호출하여 애니메이션을 되돌릴 수 있습니다 .

애니메이션을 만드는 다른 방법이 있지만이 세 가지가 가장 일반적 일 것입니다. 나는 일반적으로 ValueAnimator를 사용합니다.


객체 애니메이터를 만들 수 있습니다. 예를 들어 targetView가 있고 배경색을 변경하고 싶습니다.

int colorFrom = Color.RED;
int colorTo = Color.GREEN;
int duration = 1000;
ObjectAnimator.ofObject(targetView, "backgroundColor", new ArgbEvaluator(), colorFrom, colorTo)
    .setDuration(duration)
    .start();

이와 같은 컬러 애니메이션을 원한다면

여기에 이미지 설명을 입력하십시오

이 코드는 당신을 도울 것입니다 :

ValueAnimator anim = ValueAnimator.ofFloat(0, 1);   
anim.setDuration(2000);

float[] hsv;
int runColor;
int hue = 0;
hsv = new float[3]; // Transition color
hsv[1] = 1;
hsv[2] = 1;
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {

        hsv[0] = 360 * animation.getAnimatedFraction();

        runColor = Color.HSVToColor(hsv);
        yourView.setBackgroundColor(runColor);
    }
});

anim.setRepeatCount(Animation.INFINITE);

anim.start();

이를 달성하는 또 다른 쉬운 방법은 AlphaAnimation을 사용하여 페이드를 수행하는 것입니다.

  1. 뷰를 ViewGroup으로 설정
  2. match_parent 레이아웃 크기로 인덱스 0에 자식 뷰를 추가하십시오.
  3. 자녀에게 용기와 같은 배경을 제공하십시오
  4. 컨테이너의 배경을 대상 색상으로 변경
  5. AlphaAnimation을 사용하여 아이를 페이드 아웃하십시오.
  6. 애니메이션이 완료되면 자식을 제거합니다 (AnimationListener 사용)

가장 좋은 방법은 사용하는 것입니다 ValueAnimator을 하고ColorUtils.blendARGB

 ValueAnimator valueAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
 valueAnimator.setDuration(325);
 valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {

              float fractionAnim = (float) valueAnimator.getAnimatedValue();

              view.setBackgroundColor(ColorUtils.blendARGB(Color.parseColor("#FFFFFF")
                                    , Color.parseColor("#000000")
                                    , fractionAnim));
        }
});
valueAnimator.start();

이것이 기본 활동에서 배경을 변경하는 데 사용하는 방법입니다. 코드로 생성 된 GradientDrawables를 사용하고 있지만 적합하게 조정할 수 있습니다.

    protected void setPageBackground(View root, int type){
        if (root!=null) {
            Drawable currentBG = root.getBackground();
            //add your own logic here to determine the newBG 
            Drawable newBG = Utils.createGradientDrawable(type); 
            if (currentBG==null) {
                if(Build.VERSION.SDK_INT<Build.VERSION_CODES.JELLY_BEAN){
                    root.setBackgroundDrawable(newBG);
                }else{
                    root.setBackground(newBG);
                }
            }else{
                TransitionDrawable transitionDrawable = new TransitionDrawable(new Drawable[]{currentBG, newBG});
                transitionDrawable.setCrossFadeEnabled(true);
                if(Build.VERSION.SDK_INT<Build.VERSION_CODES.JELLY_BEAN){
                     root.setBackgroundDrawable(transitionDrawable);
                }else{
                    root.setBackground(transitionDrawable);
                }
                transitionDrawable.startTransition(400);
            }
        }
    }

업데이트 : 내가 발견 한 동일한 문제가 setCrossFadeEnabled(true)발생하는 경우 Android <4.3에서 어떤 이유로 인해 바람직하지 않은 화이트 아웃 효과가 발생하므로 위에서 언급 한 @Roman Minenok ValueAnimator 방법을 사용하여 <4.3의 단색으로 전환해야했습니다.


답변은 여러 가지 방법으로 제공됩니다. 당신은 또한 사용할 수 ofArgb(startColor,endColor)ValueAnimator.

API> 21의 경우 :

int cyanColorBg = ContextCompat.getColor(this,R.color.cyan_bg);
int purpleColorBg = ContextCompat.getColor(this,R.color.purple_bg);

ValueAnimator valueAnimator = ValueAnimator.ofArgb(cyanColorBg,purpleColorBg);
        valueAnimator.setDuration(500);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
              @Override
              public void onAnimationUpdate(ValueAnimator valueAnimator) {
                   relativeLayout.setBackgroundColor((Integer)valueAnimator.getAnimatedValue());
              }
        });
        valueAnimator.start();

이를 가능하게하는 멋진 기능이 있습니다.

public static void animateBetweenColors(final View viewToAnimateItBackground, final int colorFrom, final int colorTo,
        final int durationInMs) {
    final ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
    colorAnimation.addUpdateListener(new AnimatorUpdateListener() {
        ColorDrawable colorDrawable = new ColorDrawable(colorFrom);

        @Override
        public void onAnimationUpdate(final ValueAnimator animator) {
            colorDrawable.setColor((Integer) animator.getAnimatedValue());
            viewToAnimateItBackground.setBackgroundDrawable(colorDrawable);
        }
    });
    if (durationInMs >= 0)
        colorAnimation.setDuration(durationInMs);
    colorAnimation.start();
}

res 폴더에 폴더 애니메이터추가하십시오 . 이름은 애니메이터 여야합니다 . 애니메이터 리소스 파일을 추가하십시오. 예를 들어 res / animator / fade.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="backgroundColor"
        android:duration="1000"
        android:valueFrom="#000000"
        android:valueTo="#FFFFFF"
        android:startOffset="0"
        android:repeatCount="-1"
        android:repeatMode="reverse" />
</set>

내부 활동 자바 파일, 이것을 호출

View v = getWindow().getDecorView().findViewById(android.R.id.content);
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.fade);
set.setTarget(v);
set.start();

ArgbEvaluatorAndroid 소스 코드에서 사용되는 구현 이 전환 색상에서 가장 잘 작동 한다는 것을 알았습니다 . HSV를 사용할 때 두 가지 색상에 따라 전환이 너무 많은 색조를 뛰어 넘었습니다. 그러나이 방법은 그렇지 않습니다.

단순히 애니메이션을 적용하려는 경우 다음 ArgbEvaluatorValueAnimator같이 제안 된대로 사용 하십시오 .

ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(ValueAnimator animator) {
        view.setBackgroundColor((int) animator.getAnimatedValue());
    }

});
colorAnimation.start();

그러나 나와 비슷하고 입력에서 전달 된 일부 사용자 제스처 또는 다른 값으로 전환을 묶고 싶다면 ValueAnimatorAPI 22 이상을 대상으로하지 않는 한 큰 도움이되지 않습니다.이 경우 ValueAnimator.setCurrentFraction()메소드를 사용할 수 있습니다 ). API 22 이하를 대상으로하는 경우 다음 과 같이 ArgbEvaluator소스 코드 에서 찾은 코드 를 고유 한 방법으로 래핑하십시오 .

public static int interpolateColor(float fraction, int startValue, int endValue) {
    int startA = (startValue >> 24) & 0xff;
    int startR = (startValue >> 16) & 0xff;
    int startG = (startValue >> 8) & 0xff;
    int startB = startValue & 0xff;
    int endA = (endValue >> 24) & 0xff;
    int endR = (endValue >> 16) & 0xff;
    int endG = (endValue >> 8) & 0xff;
    int endB = endValue & 0xff;
    return ((startA + (int) (fraction * (endA - startA))) << 24) |
            ((startR + (int) (fraction * (endR - startR))) << 16) |
            ((startG + (int) (fraction * (endG - startG))) << 8) |
            ((startB + (int) (fraction * (endB - startB))));
}

원하는대로 사용하십시오.


XML 기반 애니메이션에 대한 문서는 끔찍합니다. 당신은 사용할 수 있습니다 : 난 그냥 누르면 ... 슬픈 일이 애니메이션은 하나의 속성 떨어져 있다는 것입니다 버튼의 배경색을 애니메이션으로 시간의 주위에 검색 한 exitFadeDuration에서 selector:

<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:exitFadeDuration="200">

    <item android:state_pressed="true">
        <shape android:tint="#3F51B5" />
    </item>

    <item>
        <shape android:tint="#F44336" />
    </item>

</selector>

그런 다음 background보기 로 사용하십시오 . Java / Kotlin 코드가 필요하지 않습니다.

참고 URL : https://stackoverflow.com/questions/2614545/animate-change-of-view-background-color-on-android

반응형