English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
이 기사는 커스텀 View와 속성 애니메이션을 사용하여 다음과 같은 효과를 구현하는 방법을 소개합니다
구현 방법은 매우 간단합니다:
먼저 반투명한 원을 그리는 부분을 보겠습니다
public class ClickCircleView extends View { private Bitmap bitmap; private Paint paint; private Canvas canvas; private boolean isSpreadFlag = false;//표시 여부를 발사 완료 public boolean isSpreadFlag() { return isSpreadFlag; } public void setIsSpreadFlag(boolean isSpreadFlag) { this.isSpreadFlag = isSpreadFlag; } public ClickCircleView(Context context, int width, int height, int screenWidth, int screenHeight) { super(context); bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888); // 이미지의 너비와 높이를 설정합니다 canvas = new Canvas(); canvas.setBitmap(bitmap); paint = new Paint(Paint.DITHER_FLAG); paint.setAntiAlias(true); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.FILL); paint.setAlpha(50); canvas.drawCircle(screenWidth / 2, screenHeight / 2, width / 2 + 10, paint); invalidate(); } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(bitmap, 0, 0, null); } }
관련 속성들은 펜에 설정되어 있으며, 그런 다음 투명한 원을 그리기 위해 캔버스의 drawCircle() 메서드를 직접 호출하고, 마지막으로 invalidate() 메서드를 호출하여 뷰를 새로 고칩니다.
부모 클래스의 onDraw() 메서드를 재정의해야 합니다. 그렇지 않으면 커스텀 뷰가 적용되지 않습니다.
isSpreadFlag 라는 마커를 설정했습니다. 확산 애니메이션이 완료되었는지를 표시하는 역할을 합니다.
그런 다음 두 가지 애니메이션 효과를 구현하겠습니다.
클릭 시 확산 애니메이션
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:duration="1000" android:propertyName="scaleY" android:valueFrom="1.0" android:valueTo="1.8" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleX" android:valueFrom="1.0" android:valueTo="1.8" android:valueType="floatType" /> </set>
매우 간단합니다. scale 값이 증가되는 것을 변경하는 것입니다.1.8배
때문에 확산 회수 애니메이션
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="together"> <objectAnimator android:duration="1000" android:propertyName="scaleX" android:valueFrom="1.0" android:valueTo="1.2" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleY" android:valueFrom="1.0" android:valueTo="1.2" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleX" android:startOffset="1000" android:valueFrom="1.2" android:valueTo="1.0" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleY" android:startOffset="1000" android:valueFrom="1.2" android:valueTo="1.0" android:valueType="floatType" /> </set>
이전 애니메이션과 유사하게, startOffset 파라미터는 Animation의 실행 순서를 제어할 수 있습니다, 예를 들어 Android:startOffset=""1000"은 이 속성의 애니메이션 지연을 설정하는 것을 의미합니다1초에 실행
그리고 이제 스레드를 사용하여 애니메이션과 로직을 실행하는 부분입니다
클릭하지 않을 때의 애니메이션 부분
mXiuyixiuButton.post(new Runnable() { @Override public void run() { clickCircleView = new ClickCircleView(CustomView1.this, mXiuyixiuButton.getWidth() , mXiuyixiuButton.getHeight(), mXiuyixiuLayout.getMeasuredWidth(), mXiuyixiuLayout.getMeasuredHeight()); clickCircleView.setVisibility(View.VISIBLE); mXiuyixiuLayout.addView(clickCircleView); mXiuyixiuLayout.postInvalidate(); // 애니메이션 로드 final Animator anim = AnimatorInflater.loadAnimator(CustomView1.this, R.animator.circle_scale_animator); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (anim != null) { anim.start();//반복 실행 애니메이션 } } }); anim.setTarget(clickCircleView); anim.start(); } });
clickCircleView를 초기화한 후 이 뷰를 부모 레이아웃에 추가하고 애니메이션을 로드하여 반복 실행을 설정한 후 postInvalidate()를 사용하여 서브 스레드에서 뷰를 새로고침
클릭 시의 애니메이션 부분
mXiuyixiuButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { clickCircleView.setVisibility(View.GONE);//발사 원형, 반복 애니메이션 View를 숨기기 final ClickCircleView item = new ClickCircleView(CustomView1.this, mXiuyixiuButton.getWidth() , mXiuyixiuButton.getHeight(), mXiuyixiuLayout.getWidth(), mXiuyixiuLayout.getHeight()); Animator spreadAnim = AnimatorInflater.loadAnimator(CustomView1.this, R.animator.circle_spread_animator); spreadAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { item.setIsSpreadFlag(true);//动画执行完成,标记一下 } }); spreadAnim.setTarget(item); spreadAnim.start(); clickCircleViewList.add(item); mXiuyixiuLayout.addView(item); mXiuyixiuLayout.invalidate(); handler.post(circleViewRunnable); } });
隐藏不点击动画,初始化好ClickCircleView后将该view加入List中并添加到父布局中,然后加载动画并在动画结束时添加isSpreadFlag标记,最后调用invalidate()方法刷新view并开启线程
线程部分
private Runnable circleViewRunnable = new Runnable() { public void run() { for (int i = 0; i < clickCircleViewList.size(); i++) { if (clickCircleViewList.get(i).isSpreadFlag()) { mXiuyixiuLayout.removeView(clickCircleViewList.get(i)); clickCircleViewList.remove(i); mXiuyixiuLayout.postInvalidate(); } } if (clickCircleViewList.size() <= 0) { clickCircleView.setVisibility(View.VISIBLE); } handler.postDelayed(this, 100); } }
list를 순회하며 isSpreadFlag 표시가 있는 view를 list와 부모 레이아웃에서 제거하고 view를 새로 고침합니다. 마지막으로 list가 비어 있으면 클릭하지 않았을 때의 애니메이션을 표시합니다.
최종적으로 onDestroy()에서 스레드를 제거하십시오.
@Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacks(circleViewRunnable); }
이 효과를 구현하기 위해 커스텀 뷰와 속성 애니메이션을 사용하면 결합성이 높지만, 이 방법은 커스텀 뷰를 완전히 사용하는 방법보다 더 원활합니다. 이 방법은 대부분 다른 블로그에서 코드를 참조하여 구현되었지만, 단순히 사용만 하고 요약하지 않으면 자신의 지식이 되지 않으므로 이 블로그가 생겼습니다.
참조: android에서 알ipay의 스쿠이스쿠를 구현하는 몇 가지 방법
이것이 이 문서의 전체 내용입니다. 많은 도움이 되길 바라며, 많은 지원을 해 주시기를 바랍니다.
선언: 이 문서의 내용은 인터넷에서 가져왔으며, 저작권자는 모두입니다. 내용은 인터넷 사용자가 자발적으로 기여하고 업로드한 것이며, 이 사이트는 소유권을 가지지 않으며, 인공적인 편집 처리를 하지 않았으며, 관련 법적 책임도 부담하지 않습니다. 저작권 위반 내용이 있음을 발견하면 notice#w로 이메일을 보내 주시기 바랍니다.3codebox.com(보고서를 작성할 때는 #을 @으로 변경하십시오. 신고하고 관련 증거를 제공하시면, 사실을 확인하면 이 사이트가 즉시 저작권 위반 내용을 삭제합니다.