以编程方式移动视图 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
中,或者将 ConstraintLayout
与 Barrier
一起使用。
一般推荐使用ConstraintLayout
,因为嵌套的LinearLayout
对性能不利,但由于ConstraintLayout
需要一些时间来适应,我不想省略另一个选项.
为了演示这两种方法,我在同一屏幕中设置了一个带有 LinearLayout
和 ConstraintLayout
的小示例:
<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);
}
});
}
我有一个 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
中,或者将 ConstraintLayout
与 Barrier
一起使用。
一般推荐使用ConstraintLayout
,因为嵌套的LinearLayout
对性能不利,但由于ConstraintLayout
需要一些时间来适应,我不想省略另一个选项.
为了演示这两种方法,我在同一屏幕中设置了一个带有 LinearLayout
和 ConstraintLayout
的小示例:
<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);
}
});
}