以编程方式移动视图 Android

Programmatically move a view Android

我有一个 imageView,我想在特定情况下移动它。

最初我有一个包含两个文本视图和一个图像视图的相对布局。 textViews 的方向是一个在另一个之上。图像视图已设置

android:layout_below="@id/text_view1"
android:layout_toEndOf="@+id/text_view2".

逻辑中 text_view2 在满足特定条件时被删除。当满足此条件时,我想以编程方式将 imageView 移动到 text_view1 的末尾。基本上当 text_view2 被删除时,我想将 imageView 设置为

android:layout_toEndOf="@+id/text_view1"

我认为在这里设置 X、Y、Z 值不合适,因为在编程方面,我不知道在给定不同屏幕尺寸和密度的情况下 imageView 将显示在哪里。我只需要它移动到第一个 textView 的末尾。

看看RelativeLayout.LayoutParams。您将需要按如下方式操作布局参数中的布局规则:

// Make textView2 invisible
tv2.visibility = View.INVISIBLE
// Get the LayoutParams of the ImageView
val ivParams = iv.layoutParams as RelativeLayout.LayoutParams
// Change the rule to be to the right of textView1
ivParams.addRule(RelativeLayout.RIGHT_OF, tv1.id)
// Since the placement of textView2 is changing, request a layout.
iv.requestLayout()

考虑使用“END_OF”代替“RIGHT_OF”。

您可以将 View 放在嵌套的 LinearLayout 中,或者将 ConstraintLayoutBarrier 一起使用。

一般推荐使用ConstraintLayout,因为嵌套的LinearLayout对性能不利,但由于ConstraintLayout需要一些时间来适应,我不想省略另一个选项.

为了演示这两种方法,我在同一屏幕中设置了一个带有 LinearLayoutConstraintLayout 的小示例:

<FrameLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.fragment.TabTwoFragment">

    <LinearLayout
        android:layout_width="240dp"
        android:layout_height="128dp"
        android:background="#cccccc">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="#44ff0000"
                android:maxWidth="160dp"
                android:text="Upper TextView\nin\n nested\n LinearLayout" />

            <TextView
                android:id="@+id/longTextViewInLinearLayout"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="#4400ff00"
                android:maxWidth="160dp"
                android:text="Lower TextView in nested LinearLayout" />
        </LinearLayout>

        <ImageView
            android:id="@+id/linearLayoutImageView"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:background="#ffffff"
            android:src="@drawable/ic_android_black_24dp"
            android:tint="@color/colorPrimary" />
    </LinearLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="240dp"
        android:layout_height="128dp"
        android:layout_gravity="bottom|end"
        android:background="#666666">

        <TextView
            android:id="@+id/shortTextViewInConstraintLayout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#44ff0000"
            android:maxWidth="160dp"
            android:text="Upper TextView\nin\n nested\nConstraintLayout"
            android:textColor="#ffffff"
            app:layout_constraintBottom_toTopOf="@+id/longTextViewInConstraintLayout"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.0"
            app:layout_constraintVertical_chainStyle="packed" />

        <TextView
            android:id="@+id/longTextViewInConstraintLayout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#4400ff00"
            android:maxWidth="160dp"
            android:text="Lower TextView in ConstraintLayout"
            android:textColor="#ffffff"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/shortTextViewInConstraintLayout" />

        <androidx.constraintlayout.widget.Barrier
            android:id="@+id/barrier"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:barrierDirection="end"
            app:constraint_referenced_ids="shortTextViewInConstraintLayout, longTextViewInConstraintLayout" />

        <ImageView
            android:id="@+id/constraintLayoutImageView"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:background="#ffffff"
            android:importantForAccessibility="no"
            android:src="@drawable/ic_android_black_24dp"
            android:tint="@color/colorAccent"
            app:layout_constraintStart_toEndOf="@+id/barrier"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

如果点击ImageView,长的TextView会消失,ImageView会靠近短的TextView。动画由 Android's transition framework 提供,所以基本上您所要做的就是通过调用 TransitionManager.beginDelayedTransition()

来触发转换

出于演示目的,我将所有代码放在一个方法中。请注意,通常会将 TransitionSet 作为 Fragment 的字段,这样就不必在每次需要时都重新创建。 (代码在 Java 中,因为 Android Studio 在需要时支持自动转换为 Kotlin,但反之则不然 ;-))

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    TransitionSet ts = new TransitionSet();
    ts.addTransition( new ChangeBounds());
    ts.addTransition(new Slide());

    View imageViewInLinearLayout = view.findViewById(R.id.linearLayoutImageView);
    imageViewInLinearLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            TransitionManager.beginDelayedTransition((ViewGroup)getView(), ts);
            view.findViewById(R.id.longTextViewInLinearLayout).setVisibility(GONE);
        }
    });

    View imageViewInConstraintLayout = view.findViewById(R.id.constraintLayoutImageView);
    imageViewInConstraintLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            TransitionManager.beginDelayedTransition((ViewGroup)getView(), ts);
            view.findViewById(R.id.longTextViewInConstraintLayout).setVisibility(GONE);
        }
    });
}