У меня есть требование, чтобы построить пользовательский вид какAndroid Linear Layout отсечение с анимацией
Я реализовал это как настраиваемое представление, которое проходит в 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>
Пытался это в каждом слое, как макет вверх по иерархии .. это связанно с размером просмотра быть установлено один раз обращаюсь независимо от того, анимация – Arjun
Я использую это из долгого времени, и он отлично работает. Тогда мы могли бы только больше копать, если вы разместите код с помощью xml. –
Я добавил код выше – Arjun