Tôi có hai chế độ xem trong bố cục tuyến tính, tôi lập trình thay đổi thuộc tính layout_weight của chúng. Có cách nào tôi có thể tạo hiệu ứng thay đổi cân nặng này để khi trọng lượng thay đổi chế độ xem trang trình bày về kích thước mới không?Dù sao để lập trình animate bố trí trọng lượng tài sản bố trí tuyến tính
Trả lời
Tôi cũng đã xem xét vấn đề này. Cuối cùng tôi đã giải quyết nó bằng cách làm hoạt hóa thuộc tính weightsum của cha mẹ, nó hoạt động rất tốt nếu bạn có hai khung nhìn trong LinearLayout.
xem: Animating weightSum property using ObjectAnimator
Trong ví dụ dưới đây, nếu bạn animate weightSum 1,0-2,0, màn hình 2 sẽ animate độc đáo vào xem.
<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>
Bạn chỉ cần sử dụng ObjectAnimator.
ObjectAnimator anim = ObjectAnimator.ofFloat(
viewToAnimate,
"weight",
startValue,
endValue);
anim.setDuration(2500);
anim.start();
Vấn đề một là lớp Xem không có phương thức setWeight() (được yêu cầu bởi ObjectAnimator). Để giải quyết vấn đề này, tôi đã viết trình bao bọc đơn giản giúp lưu trữ hoạt ảnh cân nặng xem.
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;
}
}
Sử dụng nó theo cách này:
ViewWeightAnimationWrapper animationWrapper = new ViewWeightAnimationWrapper(view);
ObjectAnimator anim = ObjectAnimator.ofFloat(animationWrapper,
"weight",
animationWrapper.getWeight(),
weight);
anim.setDuration(2500);
anim.start();
Một cách khác là sử dụng cũ Animation
lớp, như mô tả trong https://stackoverflow.com/a/20334557/2914140. Trong trường hợp này, bạn có thể đồng thời thay đổi trọng số của một số Chế độ xem.
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;
}
}
Lưu ý: Tôi không chắc chắn rằng đây là cách tốt nhất, nhưng tôi đã thử nó và nó làm việc tốt
Đơn giản chỉ cần sử dụng 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();
Cách tiếp cận này có một giới hạn mà bạn không thể tạo hiệu ứng độc đáo cho màn hình đầu tiên 0 trọng lượng. Bạn sẽ cần một weightSum lớn để làm điều đó nhưng sau đó các hình ảnh động sẽ nhanh hơn. – headsvk
Bất kỳ cách nào điều này có thể được thực hiện ngược lại? animate xem bên trái biến mất và tái xuất hiện? –