2017-03-07 100 views

回答

0

我需要它太,然后我创建了以下类:

/** 
* Created by Butzke on 19/05/2017. 
*/ 

public class GridViewAnimated extends GridView { 
    private int animationDuration = 300, nextColumns; 
    private boolean animating = false, waitingScroll, shouldWait = true; 
    private GridViewAnimationListener animationListener; 
    public GridViewAnimated(Context context) { 
     super(context); 
     init(); 
    } 
    public GridViewAnimated(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 
    public GridViewAnimated(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     init(); 
    } 
    @TargetApi(21) 
    public GridViewAnimated(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(context, attrs, defStyleAttr, defStyleRes); 
     init(); 
    } 
    @Override 
    public int computeVerticalScrollOffset() { 
     return super.computeVerticalScrollOffset(); 
    } 
    private void init() { 
     this.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); 
    } 
    public void setAnimating(boolean animating) { 
     this.animating = animating; 
    } 
    @Override 
    protected void onScrollChanged(int l, int t, int oldl, int oldt) { 
     if (waitingScroll) { 
      super.onScrollChanged(l, t, oldl, oldt); 
      if (computeVerticalScrollOffset() == 0) { 
       setEnabled(true); 
       waitingScroll = false; 
       setAnimating(false); 
       setNumColumns(nextColumns); 
      } 
     } else if (!animating) { 
      super.onScrollChanged(l, t, oldl, oldt); 
     } 
    } 
    public int getAnimationDuration() { 
     return animationDuration; 
    } 
    public void setAnimationDuration(int animationDuration) { 
     this.animationDuration = animationDuration; 
    } 
    public interface GridViewAnimationListener { 
     void onAnimationStart(Animator animator); 
     void onAnimationEnd(Animator animator); 
     void onAnimationCancel(Animator animator); 
     void onAnimationRepeat(Animator animator); 
    } 
    public GridViewAnimationListener getAnimationListener() { 
     return animationListener; 
    } 
    public void setAnimationListener(GridViewAnimationListener animationListener) {this.animationListener = animationListener;} 
    public void removeAt(int... positions) { 
     ArrayList<MyInteger> ints = new ArrayList<>(); 
     for (Integer pos : positions) { 
      ints.add(new MyInteger(pos)); 
     } 
     Collections.sort(ints); 
     int lowest = 99999, highest = 0; 
     for (MyInteger pos : ints) { 
      lowest = lowest < pos.getValue() ? lowest : pos.getValue(); 
      highest = highest > pos.getValue() ? highest : pos.getValue(); 
     } 

     if (lowest >= 0 && highest <= getChildCount()) { 
      ViewsVO originalViews = getOriginalViews(); 
      for (MyInteger pos : ints) { 
       getAdapter().removeAt(pos.getValue()); 
      } 
      getAdapter().notifyDataSetChanged(); 
      animateChildViews(originalViews); 
     } 
    } 
    @Override 
    public void setAdapter(ListAdapter adapter) { 
     if (adapter instanceof GridViewAnimatedAdapter) { 
      super.setAdapter(adapter); 
     } else { 
      Log.e("GridViewAnimated", "Adapter needs to be instance of GridViewAnimatedAdapter"); 
      Toast.makeText(getContext(), "Adapter needs to be instance of GridViewAnimatedAdapter", Toast.LENGTH_SHORT).show(); 
     } 
    } 
    @Override 
    public GridViewAnimatedAdapter getAdapter() { 
     return (GridViewAnimatedAdapter) super.getAdapter(); 
    } 
    @Override 
    public void setNumColumns(int numColumns) { 
     if (getAdapter() == null || !getAdapter().hasStableIds() || getChildCount() == 0) { 
      super.setNumColumns(numColumns); 
      setAnimating(false); 
      return; 
     } else if (animating) { 
      return; 
     } 
     setAnimating(true); 
     if (computeVerticalScrollOffset() > 0) { 
      waitingScroll = true; 
      setEnabled(false); 
      smoothScrollToPosition(0); 
      nextColumns = numColumns; 
      return; 
     } 
     ViewsVO originalViews = getOriginalViews(); 
     super.setNumColumns(numColumns); 
     getAdapter().notifyDataSetChanged(); 
     animateChildViews(originalViews); 
    } 
    private ViewsVO getOriginalViews() { 
     ViewsVO originalViews = new ViewsVO(); 
     for (int i = 0; i < getChildCount(); i++) { 
      originalViews.addView(getChildAt(i)); 
     } 
     return originalViews; 
    } 
    private void animateChildViews(final ViewsVO originalViews) { 
     final GridViewAnimated gridView = this; 
     getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
      @Override 
      public boolean onPreDraw() { 
       gridView.getViewTreeObserver().removeOnPreDrawListener(this); 
       ViewsVO newViews = new ViewsVO(); 
       if (Build.VERSION.SDK_INT >= 21) { 
        for (int i = 0, z = getChildCount() - 1; z >= 0; z--, i++) { 
         gridView.getChildAt(z).setTranslationZ(i); 
        } 
       } 
       boolean hasFirst = false; 
       View firstView = null, lastView = null; 
       float firstHeight = 0, lastHeight = 0; 
       ViewsVO newViewsFirstTime = new ViewsVO(); 
       for (int i = 0; i < getChildCount(); i++) { 
        View view = getChildAt(i); 
        ViewVO nView = newViews.addView(view); 
        ViewVO oView = originalViews.getView(view.getId()); 
        if (oView != null) { 
         view.setScaleX(getScaleX(oView, nView)); 
         view.setScaleY(getScaleY(oView, nView)); 
         view.setTranslationX(getTranslateX(oView, nView)); 
         view.setTranslationY(getTranslateY(oView, nView)); 
         if (!hasFirst) { 
          firstView = view; 
          firstHeight = oView.getHeight(); 
          hasFirst = true; 
         } 
         lastView = view; 
         lastHeight = oView.getHeight(); 
         animateView(view); 
        } else { 
         newViewsFirstTime.addView(nView); 
        } 
       } 
       for (int i = 0; i < newViewsFirstTime.size(); i++) { 
        try { 
         View view = newViewsFirstTime.getViews().get(i).getView(); 
         view.getId(); 
         view.setScaleX(view.getId() > firstView.getId() ? firstView.getScaleX() : lastView.getScaleX()); 
         view.setScaleY(view.getId() > firstView.getId() ? firstView.getScaleY() : lastView.getScaleX()); 
         view.setTranslationX(view.getId() > firstView.getId() ? firstView.getTranslationX() : lastView.getTranslationX()); 
         view.setTranslationY(view.getId() > firstView.getId() ? 0 - firstHeight : lastView.getTranslationY() + lastHeight); 
         animateView(view); 
        } catch (Exception ex) { 
         ex.printStackTrace(); 
        } 
       } 
       return false; 
      } 
     }); 
    } 
    private void animateView(final View view) { 
     ViewPropertyAnimator animator = view.animate().setDuration(animationDuration).translationX(0).translationY(0).scaleX(1).scaleY(1).setListener(new Animator.AnimatorListener() { 
      @Override 
      public void onAnimationStart(Animator animator) {animationListener.onAnimationStart(animator);} 
      @Override 
      public void onAnimationEnd(Animator animator) { 
       setAnimating(false); 
       animationListener.onAnimationEnd(animator); 
       ViewGroup.LayoutParams params = view.getLayoutParams(); 
       params.width = ViewGroup.LayoutParams.MATCH_PARENT; 
       params.height = ViewGroup.LayoutParams.MATCH_PARENT; 
       view.setLayoutParams(params); 
      } 
      @Override 
      public void onAnimationCancel(Animator animator) {animationListener.onAnimationCancel(animator);} 
      @Override 
      public void onAnimationRepeat(Animator animator) {animationListener.onAnimationRepeat(animator);} 
     }); 
     if (Build.VERSION.SDK_INT >= 21) { 
      animator.translationZ(0); 
     } 
    } 
    private float getTranslateX(ViewVO ov, ViewVO nv) {return ov.getPosX() - nv.getPosX() - ((ov.getWidth() < nv.getWidth() ? nv.getWidth() - ov.getWidth() : ov.getWidth() - nv.getWidth()) * (ov.getWidth() < nv.getWidth() ? 0.5f : -0.5f));} 
    private float getTranslateY(ViewVO ov, ViewVO nv) {return ov.getPosY() - nv.getPosY() - ((ov.getHeight() < nv.getHeight() ? nv.getHeight() - ov.getHeight() : ov.getHeight() - nv.getHeight()) * (ov.getHeight() < nv.getHeight() ? 0.5f : -0.5f));} 
    private float getScaleY(ViewVO ov, ViewVO nv) { 
     return ov.getHeight()/nv.getHeight(); 
    } 
    private float getScaleX(ViewVO ov, ViewVO nv) { 
     return ov.getWidth()/nv.getWidth(); 
    } 
    private class ViewsVO { 
     private ArrayList<ViewVO> views; 
     private int size() { 
      return views.size(); 
     } 
     private ViewsVO() { 
      views = new ArrayList<>(); 
     } 
     private ViewVO addView(View view) { 
      ViewVO v = new ViewVO(view); 
      addView(v); 
      return v; 
     } 
     private void addView(ViewVO view) { 
      views.add(view); 
     } 
     private ViewVO getView(long id) { 
      for (ViewVO view : views) { 
       if (view.getId() == id) { 
        return view; 
       } 
      } 
      return null; 
     } 
     private ArrayList<ViewVO> getViews() { 
      return views; 
     } 
    } 
    private class ViewVO { 
     private View view; 
     private int id; 
     private float posY; 
     private float posX; 
     private float width; 
     private float height; 
     private ViewVO(View view) { 
      this.view = view; 
      id = view.getId(); 
      posX = view.getLeft(); 
      posY = view.getTop(); 
      width = view.getWidth(); 
      height = view.getHeight(); 
     } 
     public int getId() { 
      return id; 
     } 
     public View getView() { 
      return view; 
     } 
     private float getWidth() { 
      return width; 
     } 
     private float getHeight() { 
      return height; 
     } 
     private float getPosY() { 
      return posY; 
     } 
     private float getPosX() { 
      return posX; 
     } 
    } 
    public static class GridViewAnimatedAdapter extends ArrayAdapter { 
     private List objects; 
     public GridViewAnimatedAdapter(Context context, int resource, List objects) { 
      super(context, resource, objects); 
      this.objects = objects; 
     } 
     public void removeAt(int pos) {objects.remove(pos);} 
     @Override 
     public boolean hasStableIds() { 
      return true; 
     } 
     public View dealViewToAnimation(View view) { 
      ViewGroup.LayoutParams params = view.getLayoutParams(); 
      params.width = ViewGroup.LayoutParams.MATCH_PARENT; 
      params.height = ViewGroup.LayoutParams.MATCH_PARENT; 
      view.setLayoutParams(params); 
      return view; 
     } 
    } 
    private class MyInteger implements Comparable<MyInteger> { 
     private int value; 
     public MyInteger(int value) { 
      this.value = value; 
     } 
     public int getValue() { 
      return value; 
     } 
     public void setValue(int value) { 
      this.value = value; 
     } 
     @Override 
     public int compareTo(MyInteger another) {return value > another.getValue() ? -1 : (value == another.getValue() ? 0 : 1);}} 
} 

一nd使用它很简单, GridView的适配器需要扩展GridViewAnimatedAdapter和: getView():为每个视图设置一个ID并在方法getView结束时,需要使用方法dealViewToAnimation完成(视图视图)例如:

@Override 
public View getView(int position, View view, ViewGroup parent) { 
    ... 
    view.setId(images.getId()); 
    ... 
    return dealViewToAnimation(view); 
} 

您还可以设置一个监听器,动画状态:

gridView.setAnimationListener(new GridViewAnimated.GridViewAnimationListener() { 
    @Override 
    public void onAnimationStart(Animator animator) { 
     mListMenu.setVisible(false); 
    } 
    @Override 
    public void onAnimationEnd(Animator animator) { 
     mListMenu.setVisible(true); 
     gridView.setAnimating(false); 
    } 
    @Override 
    public void onAnimationCancel(Animator animator) {} 

    @Override 
    public void onAnimationRepeat(Animator animator) { 
    } 
}); 

有了这个GridView控件能够绘制在列数的变化和动画去除itens的...

列数动画变化:

gridView.setNumColumns(5); 

动画效果去除itens的:

gridView.removeAt(2, 7, 4); 
gridView.removeAt(2); 

当不止一个,无所谓的顺序,该方法将检查订单,并从去除最高到最低,考虑到最高的ID(该图像添加到视图中)是第一个视图...

尽管它没有像GridViewAnimated中的比例动画,但最好使用RecyclerView,GridLayoutManager和DefaultItemAnimator,因为它改变了colu MNS数量和不滚动...

GridLayoutmanager gridLayoutManager = new GridLayoutManager(context, 2); 
recyclerView.setLayoutManager(gridLayoutManager); 
recyclerView.setItemAnimator(new DefaultItemAnimator()); 

然后当你需要更改列:

gridLayoutManager.requestSimpleAnimationsInNextLayout();   
gridLayoutManager.setSpanCount(newNumberOfColumns);