Анимационный вид сползает с другого взгляда, отталкивая взгляды снизу

У меня есть список кнопок. Когда я нажимаю кнопку, вид должен скользить вниз по кнопке, например:

Начало:
Введите описание изображения здесь

Наполовину:
Введите описание изображения здесь

Конец:
Введите описание изображения здесь

Как я могу это сделать? Вид, который должен выдвигаться, больше, чем кнопка, поэтому сначала скрывать вид за кнопкой и затем сдвигать ее вниз, чтобы вид был виден над кнопкой. Этого не должно быть.

Любые идеи или примеры того, как подойти к этому?

Solutions Collecting From Web of "Анимационный вид сползает с другого взгляда, отталкивая взгляды снизу"

Я считаю, что самый простой подход заключается в расширении класса Animation и переопределении applyTransformation() чтобы изменить высоту представления следующим образом:

 import android.view.View; import android.view.ViewGroup.LayoutParams; import android.view.animation.Animation; import android.view.animation.Transformation; import android.widget.LinearLayout; public class MyCustomAnimation extends Animation { public final static int COLLAPSE = 1; public final static int EXPAND = 0; private View mView; private int mEndHeight; private int mType; private LinearLayout.LayoutParams mLayoutParams; public MyCustomAnimation(View view, int duration, int type) { setDuration(duration); mView = view; mEndHeight = mView.getHeight(); mLayoutParams = ((LinearLayout.LayoutParams) view.getLayoutParams()); mType = type; if(mType == EXPAND) { mLayoutParams.height = 0; } else { mLayoutParams.height = LayoutParams.WRAP_CONTENT; } view.setVisibility(View.VISIBLE); } public int getHeight(){ return mView.getHeight(); } public void setHeight(int height){ mEndHeight = height; } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); if (interpolatedTime < 1.0f) { if(mType == EXPAND) { mLayoutParams.height = (int)(mEndHeight * interpolatedTime); } else { mLayoutParams.height = (int) (mEndHeight * (1 - interpolatedTime)); } mView.requestLayout(); } else { if(mType == EXPAND) { mLayoutParams.height = LayoutParams.WRAP_CONTENT; mView.requestLayout(); }else{ mView.setVisibility(View.GONE); } } } } 

Чтобы использовать его, установите onclick() следующим образом:

 int height; @Override public void onClick(View v) { if(view2.getVisibility() == View.VISIBLE){ MyCustomAnimation a = new MyCustomAnimation(view2, 1000, MyCustomAnimation.COLLAPSE); height = a.getHeight(); view2.startAnimation(a); }else{ MyCustomAnimation a = new MyCustomAnimation(view2, 1000, MyCustomAnimation.EXPAND); a.setHeight(height); view2.startAnimation(a); } } 

С уважением.

Используйте что-то вроде:

  Animation a = new ScaleAnimation(1, 1, 0, 1, Animation.RELATIVE_TO_SELF, (float) 0.5, Animation.RELATIVE_TO_SELF, (float) 0); a.setFillAfter(true); view.setAnimation(a); a.setDuration(1000); view.startAnimation(a); 

Вот простой пример ручной анимации, которая обеспечивает то, что вы хотите. Он работает в тестовом приложении, но я не уверен, что ошибок нет:

 public class MainActivity extends Activity implements OnClickListener { private Timer timer; private TimerTask animationTask; private View view1; private View view2; boolean animating; boolean increasing = true; int initHeight = -1; private LayoutParams params; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); timer = new Timer(); view1 = findViewById(R.id.view1);// clickable view view1.setOnClickListener(this); view2 = findViewById(R.id.view2);// animated view params = view2.getLayoutParams(); } @Override protected void onDestroy() { super.onDestroy(); timer.cancel(); } @Override public void onClick(View v) { Toast.makeText(this, "start animating...", Toast.LENGTH_SHORT).show(); animationTask = new TimerTask() { @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { if (animationFinished()) { animating = false; cancel();//canceling animating task return; } params.height += increasing ? 1 : -1; view2.setLayoutParams(params); } }); } private boolean animationFinished() { int viewHeight = view2.getHeight(); if (increasing && viewHeight >= initHeight) { return true; } if (!increasing && viewHeight <= 0) { return true; } return false; } }; //if we already animating - we just change direction of animation increasing = !increasing; if (!animating) { animating = true; int height = view2.getHeight(); params.height = height; view2.setLayoutParams(params);//change param "height" from "wrap_conent" to real height if (initHeight < 0) {//height of view - we setup it only once initHeight = height; } timer.schedule(animationTask, 0, 10);//changing repeat time here will fasten or slow down animation } } } 

Возможно, вы можете установить высоту на 0 и постепенно увеличить высоту. Но тогда у вас будет проблема, что вы должны быть уверены, что ваш текст выровнен в нижней части представления. А также знать, какова максимальная высота представления.

Вероятно, это не лучшее решение: S

Я бы сделал это так. Сначала макет для всего сворачиваемого компонента панели: (псевдо xml)

 RelativeLayout (id=panel, clip) LinearLayout (id=content, alignParentBottom=true) LinearLayout (id=handle, above=content) 

Это должно гарантировать, что содержание всегда находится под дескриптором.

Затем, когда вам нужно рухнуть:

  • Анимируйте верхний край содержимого от 0 до -content.height
  • Анимируйте высоту панели с текущего на текущий-content.height

Используйте адаптер скользящего списка так просто, как возиться с анимацией

https://github.com/tjerkw/Android-SlideExpandableListView