2017-02-17 1 views
0

클리핑 내가안드로이드 선형 레이아웃 애니메이션

enter image description here

enter image description here

내가있는 LinearLayout를 확장하는 사용자 정의보기로이 구현

등의 사용자 정의보기를 구축하는 요구 사항이의있는 LinearLayout은 두 가지 이상 포함 LinearLayouts (각 행) 및 각 요소는 RelativeLayout을 확장하고 애니메이션/상태 변경 기능을 포함하는 다른 사용자 정의보기입니다.

화살표가있는 원을 자라게하는 애니메이션이 이미지 뷰를 확대하기 때문에 크기가 일단 그려지기 때문에 이미지 뷰는 부모 컨테이너에 의해 잘립니다. 이미지 뷰를 스케일링하기 전에 부모 자체에서 setScaleX/Y를 호출 할 수 있습니다. 그런 다음 좀 이상한 동작을 얻습니다 ... 더 간단한 해결책이 있어야합니다! 레이아웃 파일에 대한

클래스

public class CameraCalibrationIndicatorCircles extends LinearLayout { 

ArrayList<CalibrationIndicatorCircle> circles; 
int currentCircleIndex = 0; 

public CameraCalibrationIndicatorCircles(Context context) { 
    super(context); 
    initialize(context); 
} 

public CameraCalibrationIndicatorCircles(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    initialize(context); 
} 

public CameraCalibrationIndicatorCircles(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    initialize(context); 
} 

public void initialize(Context context){ 
    inflate(context, R.layout.camera_calibration_indication_circles_view, this); 

    circles = new ArrayList<>(); 

    CalibrationIndicatorCircle 
      c0,  c1, c2,  c3,  c4, 
      c5,  c6, c7,  c8,  c9; 

    c0 = (CalibrationIndicatorCircle)findViewById(R.id.c0); 
    c1 = (CalibrationIndicatorCircle)findViewById(R.id.c1); 
    c2 = (CalibrationIndicatorCircle)findViewById(R.id.c2); 
    c3 = (CalibrationIndicatorCircle)findViewById(R.id.c3); 
    c4 = (CalibrationIndicatorCircle)findViewById(R.id.c4); 
    c5 = (CalibrationIndicatorCircle)findViewById(R.id.c5); 
    c6 = (CalibrationIndicatorCircle)findViewById(R.id.c6); 
    c7 = (CalibrationIndicatorCircle)findViewById(R.id.c7); 
    c8 = (CalibrationIndicatorCircle)findViewById(R.id.c8); 
    c9 = (CalibrationIndicatorCircle)findViewById(R.id.c9); 

    circles.add(c0); 
    circles.add(c1); 
    circles.add(c2); 
    circles.add(c3); 
    circles.add(c4); 
    circles.add(c5); 
    circles.add(c6); 
    circles.add(c7); 
    circles.add(c8); 
    circles.add(c9); 

    currentCircleIndex = 0; 
    circles.get(currentCircleIndex).indicateCurrent(); 

} 

public void successfulEvent(){ 
    if(currentCircleIndex < CalibrationBox.MINIMUM_NUMBER_OF_CAMERA_IMAGES_FOR_CALIB) { 
     circles.get(currentCircleIndex).indicateSucess(1,1, true); 
     currentCircleIndex++; 
     if (currentCircleIndex < CalibrationBox.MINIMUM_NUMBER_OF_CAMERA_IMAGES_FOR_CALIB) 
      circles.get(currentCircleIndex).indicateCurrent(); 
    } 
} 

} 

레이아웃 파일

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" android:layout_width="wrap_content" 
android:layout_height="wrap_content" android:weightSum="4" 
android:clipChildren="false"> 

<LinearLayout 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:weightSum="5" 
    android:layout_weight="1" 
    android:orientation="horizontal" 
    android:clipChildren="false"> 

    <CalibrationIndicatorCircle 
     android:id="@+id/c0" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" /> 

    <CalibrationIndicatorCircle 
     android:id="@+id/c1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" /> 

    <CalibrationIndicatorCircle 
     android:id="@+id/c2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" /> 

    <CalibrationIndicatorCircle 
     android:id="@+id/c3" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" /> 

    <CalibrationIndicatorCircle 
     android:id="@+id/c4" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" /> 

</LinearLayout> 

<LinearLayout 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:weightSum="5" 
    android:layout_weight="1" 
    android:orientation="horizontal"> 

    <CalibrationIndicatorCircle 
     android:id="@+id/c5" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" /> 

    <CalibrationIndicatorCircle 
     android:id="@+id/c6" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" /> 

    <CalibrationIndicatorCircle 
     android:id="@+id/c7" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" /> 

    <CalibrationIndicatorCircle 
     android:id="@+id/c8" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" /> 

    <CalibrationIndicatorCircle 
     android:id="@+id/c9" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" /> 

</LinearLayout> 
</LinearLayout> 

단일 원 뷰 클래스

public class CalibrationIndicatorCircle extends RelativeLayout { 

ImageView mWaiting, mCurrent, mSuccess, mCompleted; 
boolean mIsCurrent = false; 
Context mContext; 

public CalibrationIndicatorCircle(Context context) { 
    super(context); 
    initialize(context); 
} 

public CalibrationIndicatorCircle(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    initialize(context); 
} 

public CalibrationIndicatorCircle(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    initialize(context); 
} 

public void initialize(Context context){ 
    inflate(context, R.layout.calibration_indicator_circle_view, this); 
    mWaiting = (ImageView)findViewById(R.id.waiting); 
    mCurrent = (ImageView)findViewById(R.id.current); 
    mSuccess = (ImageView)findViewById(R.id.success); 
    mCompleted = (ImageView)findViewById(R.id.completed); 
    mCurrent.setVisibility(INVISIBLE); 
    mSuccess.setVisibility(INVISIBLE); 
    mCompleted.setVisibility(INVISIBLE); 
} 

public void indicateCurrent(){ 
    post(new Runnable() { 
     @Override 
     public void run() { 
      mWaiting.setVisibility(INVISIBLE); 
      mCurrent.setVisibility(VISIBLE); 
      mIsCurrent = true; 
     } 
    }); 
} 

public void indicateSucess(final float scaleX, final float scaleY, final boolean hideCheckMark){ 

    post(new Runnable() { 
     @Override 
     public void run() { 
      //Animate 
      mSuccess.setScaleX(0); 
      mSuccess.setScaleY(0); 
      mSuccess.setVisibility(VISIBLE); 
      mCurrent.setVisibility(INVISIBLE); 
      mWaiting.setVisibility(INVISIBLE); 
      mSuccess 
        .animate() 
        .scaleX(scaleX) 
        .scaleY(scaleY) 
        .setDuration(500) 
        .setListener(new Animator.AnimatorListener() { 
         @Override 
         public void onAnimationStart(Animator animation) { 

         } 

         @Override 
         public void onAnimationEnd(Animator animation) { 

          if(hideCheckMark) { 

           new Thread(new Runnable() { 
            @Override 
            public void run() { 
             postDelayed(new Runnable() { 
              @Override 
              public void run() { 
               mSuccess.setVisibility(INVISIBLE); 
               mCompleted.setVisibility(VISIBLE); 
              } 
             }, 300); 
            } 
           }).start(); 

          } 

         } 

         @Override 
         public void onAnimationCancel(Animator animation) { 

         } 

         @Override 
         public void onAnimationRepeat(Animator animation) { 

         } 
        }) 
        .start(); 
     } 
    }); 

} 

public void hideUntilReady() { 
    post(new Runnable() { 
     @Override 
     public void run() { 
      mWaiting.setVisibility(INVISIBLE); 
      mCurrent.setVisibility(INVISIBLE); 
      mSuccess.setVisibility(INVISIBLE); 
      mCompleted.setVisibility(INVISIBLE); 
     } 
    }); 
} 
} 

단일 원 레이아웃 파일

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
android:clipChildren="false"> 

<ImageView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    app:srcCompat="@drawable/image_success_icon" 
    android:layout_centerInParent="true" 
    android:id="@+id/success" 
    android:scaleType="fitXY" /> 

<ImageView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    app:srcCompat="@drawable/image_current_icon" 
    android:layout_centerInParent="true" 
    android:id="@+id/current" 
    android:scaleType="fitXY" /> 

<ImageView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    app:srcCompat="@drawable/image_waiting_icon" 
    android:id="@+id/waiting" 
    android:layout_centerInParent="true" 
    android:scaleType="fitXY" /> 

<ImageView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    app:srcCompat="@drawable/image_taken_icon" 
    android:id="@+id/completed" 
    android:layout_centerInParent="true" 
    android:scaleType="fitXY" /> 

</RelativeLayout> 
,

답변

0

사용 setClipChildren(false)RelativeLayout 또는 LinearLayout위한 ViewGroup에있는 ImageView가 포함된다.

는 는
+0

는 계층 구조까지 레이아웃의 각 층처럼 이것을에서 재판 .. 뷰 크기와 상관이되는 관계없이 한번 설정 그려지 애니메이션 – Arjun

+1

나는 이것을 오랫동안 사용해 왔으며 잘 작동한다. xml을 사용하여 코드를 게시하는 경우에만 더 파고들 수 있습니다. –

+0

위의 코드를 추가했습니다. – Arjun

관련 문제