我有一个线性布局,我想显示或隐藏与动画,推动布局向上或向下每当我改变其可见性。
我在那里看过一些样品,但没有一个适合我的需要。
我已经为动画创建了两个xml文件,但我不知道当我改变线性布局的可见性时如何启动它们。
我有一个线性布局,我想显示或隐藏与动画,推动布局向上或向下每当我改变其可见性。
我在那里看过一些样品,但没有一个适合我的需要。
我已经为动画创建了两个xml文件,但我不知道当我改变线性布局的可见性时如何启动它们。
当前回答
科特林
根据Suragch的回答,下面是一种使用View扩展的优雅方式:
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)
}
然后无论你想在哪里使用它,你只需要myview。slideup()或myview。slidedown ()
其他回答
使用ObjectAnimator
private fun slideDown(view: View) {
val height = view.height
ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, 0f, height.toFloat()).apply {
duration = 1000
start()
}
}
private fun slideUp(view: View) {
val height = view.height
ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, height.toFloat(), 0f)).apply {
duration = 1000
start()
}
}
这里有另一种方法来处理多个按钮(在这个例子中是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>
我在理解和应用公认的答案时遇到了困难。我需要更多的背景知识。现在我已经搞清楚了,下面是一个完整的例子:
MainActivity.java
public class MainActivity extends AppCompatActivity {
Button myButton;
View myView;
boolean isUp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myView = findViewById(R.id.my_view);
myButton = findViewById(R.id.my_button);
// initialize as invisible (could also do in xml)
myView.setVisibility(View.INVISIBLE);
myButton.setText("Slide up");
isUp = false;
}
// slide the view from below itself to the current position
public void slideUp(View view){
view.setVisibility(View.VISIBLE);
TranslateAnimation animate = new TranslateAnimation(
0, // fromXDelta
0, // toXDelta
view.getHeight(), // fromYDelta
0); // toYDelta
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
}
// slide the view from its current position to below itself
public void slideDown(View view){
TranslateAnimation animate = new TranslateAnimation(
0, // fromXDelta
0, // toXDelta
0, // fromYDelta
view.getHeight()); // toYDelta
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
}
public void onSlideViewButtonClick(View view) {
if (isUp) {
slideDown(myView);
myButton.setText("Slide up");
} else {
slideUp(myView);
myButton.setText("Slide down");
}
isUp = !isUp;
}
}
activity_mail.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.slideview.MainActivity">
<Button
android:id="@+id/my_button"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:onClick="onSlideViewButtonClick"
android:layout_width="150dp"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="@+id/my_view"
android:background="#a6e1aa"
android:orientation="vertical"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="200dp">
</LinearLayout>
</RelativeLayout>
笔记
感谢这篇文章为我指明了正确的方向。它比本页上的其他答案更有帮助。 如果你想从屏幕上的视图开始,那么不要将它初始化为INVISIBLE。 因为我们是完全在屏幕外制作动画,所以没有必要将它设置为INVISIBLE。如果你的动画不是完全脱离屏幕,那么你可以添加一个alpha动画,并使用AnimatorListenerAdapter设置可见性。 动画文档
你可以上下滑动任何视图或布局使用咆哮的代码在安卓应用程序
boolean isClicked = false;
LinearLayout mLayoutTab = (LinearLayout) findViewById(R.id.linearlayout);
if(isClicked) {
isClicked = false;
mLayoutTab.animate()
.translationYBy(120)
.translationY(0)
.setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
} else {
isClicked = true;
mLayoutTab.animate()
.translationYBy(0)
.translationY(120)
.setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
}
通过Kotlin扩展,你可以这样使用:
enum class SlideDirection{
UP,
DOWN,
LEFT,
RIGHT
}
enum class SlideType{
SHOW,
HIDE
}
fun View.slideAnimation(direction: SlideDirection, type: SlideType, duration: Long = 250){
val fromX: Float
val toX: Float
val fromY: Float
val toY: Float
val array = IntArray(2)
getLocationInWindow(array)
if((type == SlideType.HIDE && (direction == SlideDirection.RIGHT || direction == SlideDirection.DOWN)) ||
(type == SlideType.SHOW && (direction == SlideDirection.LEFT || direction == SlideDirection.UP)) ){
val displayMetrics = DisplayMetrics()
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
windowManager.defaultDisplay.getMetrics(displayMetrics)
val deviceWidth = displayMetrics.widthPixels
val deviceHeight = displayMetrics.heightPixels
array[0] = deviceWidth
array[1] = deviceHeight
}
when (direction) {
SlideDirection.UP -> {
fromX = 0f
toX = 0f
fromY = if(type == SlideType.HIDE) 0f else (array[1] + height).toFloat()
toY = if(type == SlideType.HIDE) -1f * (array[1] + height) else 0f
}
SlideDirection.DOWN -> {
fromX = 0f
toX = 0f
fromY = if(type == SlideType.HIDE) 0f else -1f * (array[1] + height)
toY = if(type == SlideType.HIDE) 1f * (array[1] + height) else 0f
}
SlideDirection.LEFT -> {
fromX = if(type == SlideType.HIDE) 0f else 1f * (array[0] + width)
toX = if(type == SlideType.HIDE) -1f * (array[0] + width) else 0f
fromY = 0f
toY = 0f
}
SlideDirection.RIGHT -> {
fromX = if(type == SlideType.HIDE) 0f else -1f * (array[0] + width)
toX = if(type == SlideType.HIDE) 1f * (array[0] + width) else 0f
fromY = 0f
toY = 0f
}
}
val animate = TranslateAnimation(
fromX,
toX,
fromY,
toY
)
animate.duration = duration
animate.setAnimationListener(object: Animation.AnimationListener{
override fun onAnimationRepeat(animation: Animation?) {
}
override fun onAnimationEnd(animation: Animation?) {
if(type == SlideType.HIDE){
visibility = View.INVISIBLE
}
}
override fun onAnimationStart(animation: Animation?) {
visibility = View.VISIBLE
}
})
startAnimation(animate)
}
扩展示例:
view.slideAnimation(SlideDirection.UP, SlideType.HIDE)//to make it disappear through top of the screen
view.slideAnimation(SlideDirection.DOWN, SlideType.SHOW)//to make it reappear from top of the screen
view.slideAnimation(SlideDirection.DOWN, SlideType.HIDE)//to make it disappear through bottom of the screen
view.slideAnimation(SlideDirection.UP, SlideType.SHOW)//to make it reappear from bottom of the screen