Animacja widoku przesuwanie się z innego widoku, przesuwanie widoków poniżej
Mam listę przycisków. Po naciśnięciu przycisku Widok powinien przesuwać się ruchem w dół z przycisku, Tak:
Start:
Halfway:
End:
Jak mam to zrobić? Widok, który powinien się wysunąć jest większy niż przycisk, więc najpierw ukrycie widoku za przyciskiem, a następnie przesunięcie go w dół powoduje, że widok jest widoczny powyżej przycisku. To nie powinno się zdarzyć.
Wszelkie pomysły lub przykłady, jak podchodzisz do tego?
7 answers
Uważam, że najprostszym podejściem jest rozszerzenie Animation
klasy i nadpisanie applyTransformation()
, aby zmienić wysokość widoku w następujący sposób:
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);
}
}
}
}
Aby go użyć, ustaw onclick()
w następujący sposób:
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);
}
}
Pozdrawiam.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-30 09:58:06
Użyj czegoś w stylu:
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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-19 14:29:16
Oto prosty przykład ręcznie robionej animacji, która zapewnia to, co chcesz. Działa w aplikacji testowej, ale nie jestem pewien, czy nie ma błędów:
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
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-20 14:10:04
Może możesz ustawić wysokość na 0 i stopniowo zwiększać wysokość. Ale wtedy będziesz miał problem, że musisz mieć pewność, że Twój tekst jest wyrównany u dołu widoku. A także wiedzieć, jaka powinna być maksymalna wysokość widoku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-14 22:22:25
Zrobiłbym to w ten sposób. Najpierw układ całego składanego panelu: (pseudo xml)
RelativeLayout (id=panel, clip)
LinearLayout (id=content, alignParentBottom=true)
LinearLayout (id=handle, above=content)
Powinno to zapewnić, że zawartość jest zawsze poniżej uchwytu.
Wtedy, gdy trzeba się zwinąć:
- Animacja górnego marginesu zawartości od 0 do-content.wysokość
- animuje wysokość panelu od bieżącej do bieżącej zawartości.wysokość
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-19 14:43:17
Korzystanie z adaptera listy przesuwnej jest o wiele łatwiejsze niż wygłupianie się animacjami
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-19 14:52:12
Po prostu prześlij android:animateLayoutChanges
do LinearLayout, który zawiera wszystkie widoki, osiągniesz pożądany rezultat.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-25 11:19:46