Ho due viste in un layout lineare, modificando a livello di codice la proprietà layout_weight. C'è un modo per animare questo cambiamento di peso in modo che quando il peso viene cambiato, le diapositive si spostano verso una nuova dimensione?Ad ogni modo per animare a livello di programmazione le proprietà di peso del layout lineare
risposta
Ho visto anche questo. Alla fine l'ho risolto animando la proprietà weightsum del genitore, che funziona molto bene se hai due viste in un LinearLayout.
vedere: Animating weightSum property using ObjectAnimator
Nell'esempio qui sotto, se animate la weightSum 1,0-2,0, Schermo 2 animerà ben in vista.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dual_pane"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:weightSum="1.0">
<!-- Screen 1 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="#ff0000"
android:layout_weight="1">
</LinearLayout>
<!-- Screen 2 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="#ff6600"
android:layout_weight="1">
</LinearLayout>
</LinearLayout>
È sufficiente utilizzare ObjectAnimator.
ObjectAnimator anim = ObjectAnimator.ofFloat(
viewToAnimate,
"weight",
startValue,
endValue);
anim.setDuration(2500);
anim.start();
L'unico problema è che Vista classe ha alcun metodo setWeight() (che è richiesta da ObjectAnimator). Per risolvere questo problema ho scritto un semplice wrapper che aiuta ad archiviare l'animazione del peso della vista.
public class ViewWeightAnimationWrapper {
private View view;
public ViewWeightAnimationWrapper(View view) {
if (view.getLayoutParams() instanceof LinearLayout.LayoutParams) {
this.view = view;
} else {
throw new IllegalArgumentException("The view should have LinearLayout as parent");
}
}
public void setWeight(float weight) {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();
params.weight = weight;
view.getParent().requestLayout();
}
public float getWeight() {
return ((LinearLayout.LayoutParams) view.getLayoutParams()).weight;
}
}
utilizzarlo in questo modo:
ViewWeightAnimationWrapper animationWrapper = new ViewWeightAnimationWrapper(view);
ObjectAnimator anim = ObjectAnimator.ofFloat(animationWrapper,
"weight",
animationWrapper.getWeight(),
weight);
anim.setDuration(2500);
anim.start();
Un altro modo è quello di utilizzare vecchio Animation
di classe, come descritto in https://stackoverflow.com/a/20334557/2914140. In questo caso è possibile modificare contemporaneamente pesi di diverse viste.
private static class ExpandAnimation extends Animation {
private final View[] views;
private final float startWeight;
private final float deltaWeight;
ExpandAnimation(View[] views, float startWeight, float endWeight) {
this.views = views;
this.startWeight = startWeight;
this.deltaWeight = endWeight - startWeight;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float weight = startWeight + (deltaWeight * interpolatedTime);
for (View view : views) {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) view.getLayoutParams();
lp.weight = weight;
view.setLayoutParams(lp);
}
views[0].getParent().requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
}
Nota: Non sono sicuro che questo è il modo migliore, ma ho provato e che sta funzionando benissimo
Semplicemente usando ValueAnimator
ValueAnimator m1 = ValueAnimator.ofFloat(0.2f, 0.5f); //fromWeight, toWeight
m1.setDuration(400);
m1.setStartDelay(100); //Optional Delay
m1.setInterpolator(new LinearInterpolator());
m1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
((LinearLayout.LayoutParams) viewToAnimate.getLayoutParams()).weight = (float) animation.getAnimatedValue();
viewToAnimate.requestLayout();
}
});
m1.start();
Questo approccio ha una limitazione a cui non è possibile animare piacevolmente il primo schermo 0 peso. Avresti bisogno di un grande weightSum per farlo, ma poi l'animazione sarà più veloce. – headsvk
In qualsiasi modo questo potrebbe essere fatto in senso inverso? animare la vista sinistra scomparendo e riapparendo? –