Добавить представление в limitedLayout с ограничениями, аналогичными другому дочернему элементу.

У меня есть макет ограничений (alpha9) с разбросанными по нему представлениями, и у меня есть один конкретный ImageView, который мне нужно воспроизвести и добавить больше подобных. Макет выглядит так: Основной макет

Основная цель - анимировать 5 из этих "монет" imageViews при нажатии кнопки. ImageViews, которые мне нужно сгенерировать, должны иметь точные свойства imageView за кнопкой ниже (с теми же ограничениями) ImageView за кнопкой

Я пытался сделать следующее:

private ImageView generateCoin() {
    ImageView coin = new ImageView(this);
    constraintLayout.addView(coin,-1,originCoinImage.getLayoutParams());//originCoinImage is the imageView behind the button
    coin.setImageResource(R.drawable.ic_coin);
    coin.setScaleType(ImageView.ScaleType.FIT_XY);
    coin.setVisibility(View.VISIBLE);
    return coin;
}

И это не удалось. РЕДАКТИРОВАТЬ: Мне не удалось показать то, что я хотел, иногда он показывает монету в левом верхнем углу экрана, иногда ничего не показывает, но в любом случае количество монет увеличивается (имеется в виду анимация пытается что-то сделать, а затем вызывает метод onAnimationFinished)

Я использовал для анимации библиотеку EasyAndroidAnimations

код выглядит следующим образом:

MainActivity.java

@OnClick(R.id.addCoin)
public void addCoin() {
//        for (int x = 0 ; x < 5 ; x++){
    final View newCoin = generateCoin();

    sendCoin(newCoin, 300, new AnimationListener() {
        @Override
        public void onAnimationEnd(com.easyandroidanimations.library.Animation animation) {
            incrementCoins();
            constraintLayout.removeView(newCoin);
            shakeCoin(targetCoinImage, 200, null);
        }
    });
//        }
}

private void incrementCoins() {
    coins++;
    coinNumber.setText(String.valueOf(coins));
}

private void sendCoin(View coinView, long duration, AnimationListener listener) {
    new TransferAnimation(coinView)
            .setDestinationView(targetCoinImage)
            .setDuration(duration)
            .setInterpolator(new AccelerateDecelerateInterpolator())
            .setListener(listener)
            .animate();
}

private void shakeCoin(View coinView, long duration, AnimationListener listener) {
    new ShakeAnimation(coinView)
            .setDuration(duration)
            .setShakeDistance(6f)
            .setNumOfShakes(5)
            .setListener(listener)
            .animate();
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="seaskyways.canvasanddrawtest.MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:text="Coins : "
        android:textSize="30sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/coinNumber"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="16dp"
        android:layout_marginStart="8dp"
        android:text="0"
        android:textColor="@color/colorPrimary"
        android:textSize="50sp"
        android:textStyle="normal|bold"
        app:layout_constraintBottom_toBottomOf="@+id/textView"
        app:layout_constraintLeft_toRightOf="@+id/textView"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@+id/textView" />

    <ImageView
        android:id="@+id/coinOrigin"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:scaleType="fitXY"
        app:layout_constraintBottom_toBottomOf="@+id/addCoin"
        app:layout_constraintLeft_toLeftOf="@+id/addCoin"
        app:layout_constraintTop_toTopOf="@+id/addCoin"
        app:srcCompat="@drawable/ic_coin"
        app:layout_constraintRight_toRightOf="@+id/addCoin" />

    <ImageView
        android:id="@+id/coinTarget"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginLeft="16dp"
        android:layout_marginStart="16dp"
        android:scaleType="fitXY"
        app:layout_constraintBottom_toBottomOf="@+id/coinNumber"
        app:layout_constraintLeft_toRightOf="@+id/coinNumber"
        app:layout_constraintTop_toTopOf="@+id/coinNumber"
        app:srcCompat="@drawable/ic_coin" />

    <Button
        android:id="@+id/addCoin"
        android:layout_width="0dp"
        android:layout_height="75dp"
        android:layout_marginBottom="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginStart="16dp"
        android:text="Button"
        android:textAlignment="center"
        android:textSize="36sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>

person Seaskyways    schedule 03.10.2016    source источник
comment
Что вы получаете в качестве вывода, когда вы нажимаете кнопку?/   -  person O_o    schedule 03.10.2016
comment
Если я правильно понимаю, вы хотите, чтобы монета переходила от нижней кнопки к верхней монете, а когда анимация заканчивалась, количество монет увеличивалось на единицу. Итак, вы хотите увеличить их на пять, что означает, что 5 монет должны быть анимированы снизу вверх. Я близко?   -  person mihanovak1024    schedule 03.10.2016
comment
Именно то, что я хочу, но я должен сделать это с одной монетой, тогда миллион не будет иметь значения @mihanovak1024   -  person Seaskyways    schedule 03.10.2016
comment
То есть анимация должна идти вертикально вверх? Или он должен двигаться или что-то в этом роде? Какую анимацию вы имели в виду? Подойдет ли простая TranslateAnimation?   -  person mihanovak1024    schedule 03.10.2016
comment
@ mihanovak1024 речь идет не об анимации, а о правильном программном размещении изображения.   -  person Seaskyways    schedule 04.10.2016
comment
@Seaskyways, тогда я бы порекомендовал вам расположить изображение в том месте, где вы хотите, чтобы оно было в конце анимации, и установить его видимость либо исчезнувшим, либо невидимым, а затем анимируйте его из нижней части экрана в фактическое место просмотра и в начале анимации установите для нее видимость.   -  person mihanovak1024    schedule 04.10.2016


Ответы (1)


ConstraintLayout.LayoutParams кэширует свои параметры и связан с виджетом, на котором вы его используете, поэтому вы не можете просто передать layoutParams одного виджета другому.

Вместо этого вам нужно создать новый layoutParams для вашего нового объекта и скопировать соответствующие поля.

Например, если у вас есть что-то вроде:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/content_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:text="Button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginLeft="16dp" />

</android.support.constraint.ConstraintLayout>

Тогда вы можете сделать:

ConstraintLayout layout = (ConstraintLayout) findViewById(R.id.content_main);
ConstraintLayout.LayoutParams params = 
                (ConstraintLayout.LayoutParams) button.getLayoutParams();

Button anotherButton = new Button(this);

ConstraintLayout.LayoutParams newParams = new ConstraintLayout.LayoutParams(
                ConstraintLayout.LayoutParams.WRAP_CONTENT,
                ConstraintLayout.LayoutParams.WRAP_CONTENT);

newParams.leftToLeft = params.leftToLeft;
newParams.topToTop = params.topToTop;
newParams.leftMargin = params.leftMargin;
newParams.topMargin = params.topMargin;

layout.addView(anotherButton, -1, newParams);

Это поместит вторую кнопку точно в то же место, что и определено в XML.

person Nicolas Roard    schedule 04.10.2016
comment
Привет, Николас Роард. Если у меня сложный пользовательский интерфейс, например, кнопка является динамической и имеет много параметров макета и множество ограничений, я хочу добавить новую кнопку в ту же позицию, что мне делать? Спасибо. - person Changwei; 15.10.2017
comment
В любом случае, благодарю Вас. Реализую следующим образом: val screenshotViewLayoutParams = ConstraintLayout.LayoutParams(cl.width, cl.height) screenshotView.layoutParams = screenshotViewLayoutParams cs.connect(screenshotView.id, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, cl. x.toInt()) cs.connect(screenshotView.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, cl.y.toInt()) - person Changwei; 15.10.2017