2016-11-24 185 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