2016-11-24 190 views
3

我试过了这个主题的各种解决方案(请参阅Android: Expand/collapse animation),但它们都没有为我工作。我敢肯定,大部分投票的人都很好,而且不会工作的原因是我不明白。请告诉我我做错了什么。预先感谢您:)Android展开/折叠RelativeLayout

编辑:我的问题的主要问题是,当我点击元素'relativeZaplon'它扩展得很好,但是当我想折叠它,它不符合。

MainActivity

public class MainActivity extends AppCompatActivity { 

    private boolean isVisible = false; 
    private RelativeLayout mRelativeZaplon; 
    private RelativeLayout mRelativeToSlide; 
    private ExpandOrCollapse mAnimationManager; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     mAnimationManager = new ExpandOrCollapse(); 
     mRelativeZaplon = (RelativeLayout) findViewById(R.id.relativeZaplon); 
     mRelativeToSlide = (RelativeLayout) findViewById(R.id.relativevToSlide); 
     mRelativeZaplon.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (isVisible) { 
        mAnimationManager.collapse(mRelativeToSlide, 1000, 200); 
        isVisible = false; 
       } else if (!isVisible){ 
        mAnimationManager.expand(mRelativeToSlide, 1000, 200); 
        isVisible = true; 
       } 
      } 
     }); 
    } 
} 

展开/折叠类

public class ExpandOrCollapse { 

    public static void expand(final View v, int duration, int targetHeight) { 
     int prevHeight = v.getHeight(); 
     v.setVisibility(View.VISIBLE); 
     ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, targetHeight); 
     valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
      @Override 
      public void onAnimationUpdate(ValueAnimator animation) { 
       v.getLayoutParams().height = (int) animation.getAnimatedValue(); 
       v.requestLayout(); 
      } 
     }); 
     valueAnimator.setInterpolator(new DecelerateInterpolator()); 
     valueAnimator.setDuration(duration); 
     valueAnimator.start(); 
    } 

    public static void collapse(final View v, int duration, int targetHeight) { 
     int prevHeight = v.getHeight(); 
     ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, targetHeight); 
     valueAnimator.setInterpolator(new DecelerateInterpolator()); 
     valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
      @Override 
      public void onAnimationUpdate(ValueAnimator animation) { 
       v.getLayoutParams().height = (int) animation.getAnimatedValue(); 
       v.requestLayout(); 
      } 
     }); 
     valueAnimator.setInterpolator(new DecelerateInterpolator()); 
     valueAnimator.setDuration(duration); 
     valueAnimator.start(); 
    } 
} 

XML

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <RelativeLayout 
     android:background="@color/colorPrimaryDark" 
     android:id="@+id/relativevToSlide" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:visibility="gone"> 
    </RelativeLayout> 
    <RelativeLayout 
     android:id="@+id/relativeZaplon" 
     android:background="@color/colorAccent" 
     android:layout_width="match_parent" 
     android:layout_height="20dp" 
     android:layout_below="@+id/relativevToSlide" 
     android:layout_alignParentRight="true" 
     android:layout_alignParentEnd="true"> 
    </RelativeLayout> 
</LinearLayout> 
+0

你能具体谈谈什么不起作用?你有错误吗? –

+0

@AHoneyBustard你好,是的,我很抱歉。我已经编辑帖子:)欢呼声。 –

回答

1

这是因为

  if (isVisible) { 
       mAnimationManager.collapse(mRelativeToSlide, 1000, 200); 
       isVisible = false; 
      } else if (!isVisible){ 
       mAnimationManager.expand(mRelativeToSlide, 1000, 200); 
       isVisible = true; 
      } 

collapse()和expand()做同样的事情,它们在这种情况下都展开动画。你需要传递一个不同的值给你的collapse()方法; 简单的解决办法是

mAnimationManager.collapse(mRelativeToSlide, 1000, -200); 

但也有一些更多的问题与你的编码风格,例如,你可以只摆脱你的崩溃()方法,因为调用扩大两次这样也将工作:

  if (isVisible) { 
       mAnimationManager.expand(mRelativeToSlide, 1000, -200); 
       isVisible = false; 
      } else if (!isVisible){ 
       mAnimationManager.expand(mRelativeToSlide, 1000, 200); 
       isVisible = true; 
      } 

我建议你把它张贴在Code Review

+0

非常感谢。我觉得自己像个假人,我没有看到。该解决方案解决了问题。 –

3

这是我的方法版本,您不必设置任何高度,它将根据其可见性展开或折叠任何视图。

public static void expand(final View v, int duration) { 
    final boolean expand = v.getVisibility()!=View.VISIBLE; 

    int prevHeight = v.getHeight(); 
    int height = 0; 
    if (expand) { 
     int measureSpecParams = View.MeasureSpec.getSize(View.MeasureSpec.UNSPECIFIED); 
     v.measure(measureSpecParams, measureSpecParams); 
     height = v.getMeasuredHeight(); 
    } 

    ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, height); 
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
     @Override 
     public void onAnimationUpdate(ValueAnimator animation) { 
      v.getLayoutParams().height = (int) animation.getAnimatedValue(); 
      v.requestLayout(); 
     } 
    }); 

    valueAnimator.addListener(new Animator.AnimatorListener() { 
     @Override 
     public void onAnimationStart(Animator animation) { 
      if (expand){ 
       v.setVisibility(View.VISIBLE); 
      } 
     } 

     @Override 
     public void onAnimationEnd(Animator animation) { 
      if (!expand){ 
       v.setVisibility(View.INVISIBLE); 
      } 
     } 

     @Override 
     public void onAnimationCancel(Animator animation) { 

     } 

     @Override 
     public void onAnimationRepeat(Animator animation) { 

     } 
    }); 
    valueAnimator.setInterpolator(new DecelerateInterpolator()); 
    valueAnimator.setDuration(duration); 
    valueAnimator.start(); 
} 

只要调用方法是这样的:

expand(YOURVIEWID,500); 
+0

它的工作魅力。你节省了我的时间 – Ninja