我有一个线性布局,我想显示或隐藏与动画,推动布局向上或向下每当我改变其可见性。
我在那里看过一些样品,但没有一个适合我的需要。
我已经为动画创建了两个xml文件,但我不知道当我改变线性布局的可见性时如何启动它们。
我有一个线性布局,我想显示或隐藏与动画,推动布局向上或向下每当我改变其可见性。
我在那里看过一些样品,但没有一个适合我的需要。
我已经为动画创建了两个xml文件,但我不知道当我改变线性布局的可见性时如何启动它们。
当前回答
Suragch用科特林语回答。这对我很管用。
class MainActivity : AppCompatActivity() {
var isUp: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var myView: View = findViewById(R.id.my_view)
var myButton: Button = findViewById(R.id.my_button)
//Initialize as invisible
myView.visibility = View.INVISIBLE
myButton.setText("Slide up")
isUp = false
}
fun View.slideUp(duration: Int = 500){
visibility = View.VISIBLE
val animate = TranslateAnimation(0f, 0f, this.height.toFloat(), 0f)
animate.duration = duration.toLong()
animate.fillAfter = true
this.startAnimation(animate)
}
fun View.slideDown(duration: Int = 500) {
visibility = View.VISIBLE
val animate = TranslateAnimation(0f, 0f, 0f, this.height.toFloat())
animate.duration = duration.toLong()
animate.fillAfter = true
this.startAnimation(animate)
}
fun onSlideViewButtonClick(view: View){
if(isUp){
my_view.slideDown()
my_button.setText("Slide Up")
}
else{
my_view.slideUp()
my_button.setText("Slide Down")
}
isUp = !isUp
}
}
其他回答
随着Android 3.0 (Honeycomb)引入的新动画API,创建这样的动画非常简单。
将视图向下滑动一段距离:
view.animate().translationY(distance);
你可以稍后将视图滑回原来的位置,如下所示:
view.animate().translationY(0);
您还可以轻松地组合多个动画。下面的动画会将一个视图按高度向下滑动,同时淡入:
// Prepare the View for the animation
view.setVisibility(View.VISIBLE);
view.setAlpha(0.0f);
// Start the animation
view.animate()
.translationY(view.getHeight())
.alpha(1.0f)
.setListener(null);
然后,您可以将视图淡出,并将其滑回原始位置。我们还设置了一个AnimatorListener,这样我们可以在动画完成后将视图的可见性设置为GONE:
view.animate()
.translationY(0)
.alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setVisibility(View.GONE);
}
});
一个完整的答案,在onClick中切换视图可见性,也翻转箭头,并在隐藏组件时平滑地向上移动其他视图。
private fun toggleRecyclerViewVisibility(
recyclerView: RecyclerView,
container: FrameLayout,
arrow: ImageView
) {
//toggle arrow direction, also block user clicks until animation finishes.
arrow
.animate()
.rotation(
if (arrow.rotation == 0F)
180F
else 0F
)
.withStartAction { container.isClickable = false }
.withEndAction { container.isClickable = true }
.start()
//toggle recyclerview visibility with animation.
with(recyclerView) {
var cof = -1
var vis = View.GONE
var alph = 0F
if (visibility == View.GONE) {
cof = 0
vis = View.VISIBLE
alph = 1F
}
animate()
.translationY(height.toFloat() * cof)
.alpha(alph)
.withStartAction {//in case showing the recyclerview show it at the beginning.
if (vis == View.VISIBLE)
visibility = View.VISIBLE
}
.withEndAction {//in case hiding the recyclerview hide it at the end.
if (vis == View.GONE)
visibility = View.GONE
}
.start()
}
}
视图是这样的
<LinearLayout
android:id="@+id/subRootLinearView"
android:animateLayoutChanges="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--other views-->
<LinearLayout
android:id="@+id/Container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/backgroundGray"
android:padding="16dp">
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/awaitingConfirmation"
android:textColor="@color/colorText"
android:textSize="16sp" />
<ImageView
android:id="@+id/arrow_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center"
android:src="@drawable/ic_arrow" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
</LinearLayout>
<!--other views-->
</LinearLayout>
然后在代码中首先添加这一行,这解决了animateLayoutChanges在大嵌套视图中不工作的问题,这基本上使其他视图在隐藏recyclerview时平滑地向上移动
subRootLinearView.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
你的父线性布局也应该包含这个属性
android:animateLayoutChanges="true"
然后用视图调用该方法
toggleRecyclerViewVisibility(
recycler,
header,
arrowImageView
)
从ashakirov的回答为Kotlin用户
val transition: Transition = Slide(Gravity.BOTTOM)
transition.duration = 600
transition.addTarget(you_parent_layout_id)
TransitionManager.beginDelayedTransition(rootLayoutId, transition)
yourViewIdToHide.visibility = if (yourViewIdToHide.isShown) View.GONE else View.VISIBLE
如果你想同时显示/隐藏多个视图,你可以使用TransitionSet(因为你不能同时播放2个“单个”过渡)
fun slideTopBottomVisibility(topLayout: View, bottomLayout: View, show: Boolean) {
val topTransition: Transition = Slide(Gravity.TOP)
topTransition.duration = 600
topTransition.addTarget(topLayout)
val bottomTransition: Transition = Slide(Gravity.BOTTOM)
bottomTransition.duration = 600
bottomTransition.addTarget(bottomLayout)
val transitionSet = TransitionSet()
transitionSet.addTransition(topTransition)
transitionSet.addTransition(bottomTransition)
TransitionManager.beginDelayedTransition(topLayout.parent as ViewGroup, transitionSet)
topLayout.visibility = if (show) View.VISIBLE else View.GONE
bottomLayout.visibility = if (show) View.VISIBLE else View.GONE
}
这里有另一种方法来处理多个按钮(在这个例子中是ImageView)
MainActivity.java
findViewById(R.id.arrowIV).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (strokeWidthIV.getAlpha() == 0f) {
findViewById(R.id.arrowIV).animate().rotationBy(180);
strokeWidthIV.animate().translationXBy(-120 * 4).alpha(1f);
findViewById(R.id.colorChooseIV).animate().translationXBy(-120 * 3).alpha(1f);
findViewById(R.id.saveIV).animate().translationXBy(-120 * 2).alpha(1f);
findViewById(R.id.clearAllIV).animate().translationXBy(-120).alpha(1f);
} else {
findViewById(R.id.arrowIV).animate().rotationBy(180);
strokeWidthIV.animate().translationXBy(120 * 4).alpha(0f);
findViewById(R.id.colorChooseIV).animate().translationXBy(120 * 3).alpha(0f);
findViewById(R.id.saveIV).animate().translationXBy(120 * 2).alpha(0f);
findViewById(R.id.clearAllIV).animate().translationXBy(120).alpha(0f);
}
}
});
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<ImageView
android:id="@+id/strokeWidthIV"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:alpha="0"
android:contentDescription="Clear All"
android:padding="4dp"
android:scaleType="fitXY"
android:src="@drawable/ic_edit"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/colorChooseIV"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:alpha="0"
android:contentDescription="Clear All"
android:padding="4dp"
android:scaleType="fitXY"
android:src="@drawable/ic_palette"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/saveIV"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:alpha="0"
android:contentDescription="Clear All"
android:padding="4dp"
android:scaleType="fitXY"
android:src="@drawable/ic_save"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/clearAllIV"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:alpha="0"
android:contentDescription="Clear All"
android:padding="4dp"
android:scaleType="fitXY"
android:src="@drawable/ic_clear_all"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/arrowIV"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:contentDescription="Arrow"
android:padding="4dp"
android:scaleType="fitXY"
android:src="@drawable/ic_arrow"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>