/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package com.taobao.weex.ui.component.list;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.PointF;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.ArrayMap;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.text.TextUtils;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import com.taobao.weex.WXEnvironment;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.annotation.JSMethod;
import com.taobao.weex.common.Constants;
import com.taobao.weex.common.ICheckBindingScroller;
import com.taobao.weex.common.OnWXScrollListener;
import com.taobao.weex.dom.WXAttr;
import com.taobao.weex.ui.action.BasicComponentData;
import com.taobao.weex.ui.component.AppearanceHelper;
import com.taobao.weex.ui.component.Scrollable;
import com.taobao.weex.ui.component.WXBaseRefresh;
import com.taobao.weex.ui.component.WXComponent;
import com.taobao.weex.ui.component.WXComponentProp;
import com.taobao.weex.ui.component.WXHeader;
import com.taobao.weex.ui.component.WXLoading;
import com.taobao.weex.ui.component.WXRefresh;
import com.taobao.weex.ui.component.WXVContainer;
import com.taobao.weex.ui.component.helper.ScrollStartEndHelper;
import com.taobao.weex.ui.component.helper.WXStickyHelper;
import com.taobao.weex.ui.view.listview.WXRecyclerView;
import com.taobao.weex.ui.view.listview.adapter.IOnLoadMoreListener;
import com.taobao.weex.ui.view.listview.adapter.IRecyclerAdapterListener;
import com.taobao.weex.ui.view.listview.adapter.ListBaseViewHolder;
import com.taobao.weex.ui.view.listview.adapter.RecyclerViewBaseAdapter;
import com.taobao.weex.ui.view.listview.adapter.WXRecyclerViewOnScrollListener;
import com.taobao.weex.ui.view.refresh.wrapper.BounceRecyclerView;
import com.taobao.weex.utils.WXLogUtils;
import com.taobao.weex.utils.WXResourceUtils;
import com.taobao.weex.utils.WXUtils;
import com.taobao.weex.utils.WXViewUtils;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * Created by sospartan on 13/12/2016.
 */

public abstract class BasicListComponent<T extends ViewGroup & ListComponentView> extends WXVContainer<T> implements
    IRecyclerAdapterListener<ListBaseViewHolder>, IOnLoadMoreListener, Scrollable {
  public static final String TRANSFORM = "transform";
  public static final String LOADMOREOFFSET = "loadmoreoffset";
  private String TAG = "BasicListComponent";
  private int mListCellCount = 0;
  private boolean mForceLoadmoreNextTime = false;
  private static final Pattern transformPattern = Pattern.compile("([a-z]+)\\(([0-9\\.]+),?([0-9\\.]+)?\\)");

  private Map<String, AppearanceHelper> mAppearComponents = new HashMap<>();
  private Runnable mAppearChangeRunnable = null;
  private long mAppearChangeRunnableDelay = 50;

  private boolean isScrollable = true;
  private ArrayMap<String, Long> mRefToViewType;
  private SparseArray<ArrayList<WXComponent>> mViewTypes;
  private WXRecyclerViewOnScrollListener mViewOnScrollListener = new WXRecyclerViewOnScrollListener(this);

  private static final int MAX_VIEWTYPE_ALLOW_CACHE = 9;
  private static boolean mAllowCacheViewHolder = true;
  private static boolean mDownForBidCacheViewHolder = false;


  protected int mLayoutType = WXRecyclerView.TYPE_LINEAR_LAYOUT;
  protected int mColumnCount = 1;
  protected float mColumnGap = 0;
  protected float mColumnWidth = 0;
  protected float mLeftGap = 0;
  protected float mRightGap = 0;

  private int mOffsetAccuracy = 10;
  private Point mLastReport = new Point(-1, -1);
  private boolean mHasAddScrollEvent = false;

  private RecyclerView.ItemAnimator mItemAnimator;

  private DragHelper mDragHelper;

  /**
   * exclude cell when dragging(attributes for cell)
   */
  private static final String EXCLUDED = "dragExcluded";

  /**
   * the type to trigger drag-drop
   */
  private static final String DRAG_TRIGGER_TYPE = "dragTriggerType";

  private static final String DEFAULT_TRIGGER_TYPE = DragTriggerType.LONG_PRESS;
  private static final boolean DEFAULT_EXCLUDED = false;

  private static final String DRAG_ANCHOR = "dragAnchor";

  /**
   * gesture type which can trigger drag&drop
   */
  interface DragTriggerType {
    String PAN = "pan";
    String LONG_PRESS = "longpress";
  }

  private String mTriggerType;

  /**
   * Map for storing component that is sticky.
   **/
  private Map<String, Map<String, WXComponent>> mStickyMap = new HashMap<>();
  private WXStickyHelper stickyHelper;

  /**
   * scroll start and scroll end event
   * */
  private ScrollStartEndHelper mScrollStartEndHelper;

  /**
   * keep positon
   * */
  private  WXComponent keepPositionCell = null;
  private  Runnable keepPositionCellRunnable = null;
  private  long keepPositionLayoutDelay = 150;


  public BasicListComponent(WXSDKInstance instance, WXVContainer parent, BasicComponentData basicComponentData) {
    super(instance, parent, basicComponentData);
    stickyHelper = new WXStickyHelper(this);
  }

  @Override
  protected void onHostViewInitialized(T host) {
    super.onHostViewInitialized(host);

    WXRecyclerView recyclerView = host.getInnerView();
    if (recyclerView == null || recyclerView.getAdapter() == null) {
      WXLogUtils.e(TAG, "RecyclerView is not found or Adapter is not bound");
      return;
    }
    if(WXUtils.getBoolean(getAttrs().get("prefetchGapDisable"), false)){
      if(recyclerView.getLayoutManager() != null){
        recyclerView.getLayoutManager().setItemPrefetchEnabled(false);
      }
    }

    if (mChildren == null) {
      WXLogUtils.e(TAG, "children is null");
      return;
    }

    mDragHelper = new DefaultDragHelper(mChildren, recyclerView, new EventTrigger() {
      @Override
      public void triggerEvent(String type, Map<String, Object> args) {
        fireEvent(type, args);
      }
    });

    mTriggerType = getTriggerType(this);
  }

  /**
   * Measure the size of the recyclerView.
   *
   * @param width  the expected width
   * @param height the expected height
   * @return the result of measurement
   */
  @Override
  protected MeasureOutput measure(int width, int height) {
    int screenH = WXViewUtils.getScreenHeight(WXEnvironment.sApplication);
    int weexH = WXViewUtils.getWeexHeight(getInstanceId());
    int outHeight = height > (weexH >= screenH ? screenH : weexH) ? weexH - getAbsoluteY() : height;
    return super.measure((int)(width+mColumnGap), outHeight);
  }

  public int getOrientation() {
    return Constants.Orientation.VERTICAL;
  }

  @Override
  public void destroy() {
    if(mAppearChangeRunnable != null &&  getHostView() != null) {
      getHostView().removeCallbacks(mAppearChangeRunnable);
      mAppearChangeRunnable = null;
    }
    super.destroy();
    if (mStickyMap != null)
      mStickyMap.clear();
    if (mViewTypes != null)
      mViewTypes.clear();
    if (mRefToViewType != null)
      mRefToViewType.clear();

  }

  @Override
  public ViewGroup.LayoutParams getChildLayoutParams(WXComponent child, View hostView, int width, int height, int left, int right, int top, int bottom) {
    ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) hostView.getLayoutParams();
    if (child instanceof WXBaseRefresh && params == null) {
      params = new LinearLayout.LayoutParams(width, height);
    } else if (params == null) {
      params = new RecyclerView.LayoutParams(width, height);
    } else {
      params.width = width;
      params.height = height;
      params.setMargins(left, 0, right, 0);
    }
    return params;
  }

  abstract T generateListView(Context context, int orientation);

  @Override
  protected T initComponentHostView(@NonNull Context context) {
    T bounceRecyclerView = generateListView(context, getOrientation());

    String transforms = getAttrByKey(TRANSFORM);
    if (transforms != null) {
      bounceRecyclerView.getInnerView().addItemDecoration(RecyclerTransform.parseTransforms(getOrientation(), transforms));
    }
    if(getAttrs().get(Constants.Name.KEEP_POSITION_LAYOUT_DELAY) != null){
      keepPositionLayoutDelay = WXUtils.getNumberInt(getAttrs().get(Constants.Name.KEEP_POSITION_LAYOUT_DELAY), (int)keepPositionLayoutDelay);
    }
    if(getAttrs().get("appearActionDelay") != null){
      mAppearChangeRunnableDelay =  WXUtils.getNumberInt(getAttrs().get("appearActionDelay"), (int) mAppearChangeRunnableDelay);
    }

    mItemAnimator=bounceRecyclerView.getInnerView().getItemAnimator();

    RecyclerViewBaseAdapter recyclerViewBaseAdapter = new RecyclerViewBaseAdapter<>(this);
    recyclerViewBaseAdapter.setHasStableIds(true);
    bounceRecyclerView.setRecyclerViewBaseAdapter(recyclerViewBaseAdapter);
    bounceRecyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
    bounceRecyclerView.getInnerView().clearOnScrollListeners();
    bounceRecyclerView.getInnerView().addOnScrollListener(mViewOnScrollListener);
    if(getAttrs().get(Constants.Name.HAS_FIXED_SIZE) != null){
      boolean hasFixedSize = WXUtils.getBoolean(getAttrs().get(Constants.Name.HAS_FIXED_SIZE), false);
      bounceRecyclerView.getInnerView().setHasFixedSize(hasFixedSize);
    }

    bounceRecyclerView.getInnerView().addOnScrollListener(new RecyclerView.OnScrollListener() {
      @Override
      public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);

        List<OnWXScrollListener> listeners = getInstance().getWXScrollListeners();
        if (listeners != null && listeners.size() > 0) {
          for (OnWXScrollListener listener : listeners) {
            if (listener != null) {
              View topView = recyclerView.getChildAt(0);
              if (topView != null) {
                int y = topView.getTop();
                listener.onScrollStateChanged(recyclerView, 0, y, newState);
              }
            }
          }
        }
      }

      @Override
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        List<OnWXScrollListener> listeners = getInstance().getWXScrollListeners();
        if (listeners != null && listeners.size() > 0) {
          try {
            for (OnWXScrollListener listener : listeners) {
              if (listener != null) {
                if (listener instanceof ICheckBindingScroller) {
                  if (((ICheckBindingScroller) listener).isNeedScroller(getRef(), null)) {
                    listener.onScrolled(recyclerView, dx, dy);
                  }
                } else {
                  listener.onScrolled(recyclerView, dx, dy);
                }
              }
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    });



    bounceRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
      @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
      @Override
      public void onGlobalLayout() {
        T view;
        if ((view = getHostView()) == null)
          return;
        mViewOnScrollListener.onScrolled(view.getInnerView(), 0, 0);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
          view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        } else {
          view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
      }
    });
    return bounceRecyclerView;
  }

  @Override
  public void bindStickStyle(WXComponent component) {
    stickyHelper.bindStickStyle(component, mStickyMap);
  }

  @Override
  public void unbindStickStyle(WXComponent component) {
    stickyHelper.unbindStickStyle(component, mStickyMap);
    WXHeader cell = (WXHeader) findTypeParent(component, WXHeader.class);
    if(cell != null && getHostView() != null) {
      getHostView().notifyStickyRemove(cell);
    }
  }

  private
  @Nullable
  WXComponent findDirectListChild(WXComponent comp) {
    WXComponent parent;
    if (comp == null || (parent = comp.getParent()) == null) {
      return null;
    }

    if (parent instanceof BasicListComponent) {
      return comp;
    }

    return findDirectListChild(parent);
  }

  @Override
  protected boolean setProperty(String key, Object param) {
    switch (key) {
      case LOADMOREOFFSET:
        return true;
      case Constants.Name.SCROLLABLE:
        boolean scrollable = WXUtils.getBoolean(param, true);
        setScrollable(scrollable);
        return true;
      case Constants.Name.OFFSET_ACCURACY:
        int accuracy = WXUtils.getInteger(param, 10);
        setOffsetAccuracy(accuracy);
        return true;
      case Constants.Name.DRAGGABLE:
        boolean draggable = WXUtils.getBoolean(param,false);
        setDraggable(draggable);
        return true;
      case Constants.Name.SHOW_SCROLLBAR:
        Boolean result = WXUtils.getBoolean(param,null);
        if (result != null)
          setShowScrollbar(result);
        return true;
    }
    return super.setProperty(key, param);
  }

  @WXComponentProp(name = Constants.Name.SCROLLABLE)
  public void setScrollable(boolean scrollable) {
    this.isScrollable = scrollable;
    WXRecyclerView inner = getHostView().getInnerView();
    if(inner != null) {
      inner.setScrollable(scrollable);
    }
  }

  @WXComponentProp(name = Constants.Name.OFFSET_ACCURACY)
  public void setOffsetAccuracy(int accuracy) {
    float real = WXViewUtils.getRealPxByWidth(accuracy, getInstance().getInstanceViewPortWidth());
    this.mOffsetAccuracy = (int) real;
  }

  @WXComponentProp(name = Constants.Name.DRAGGABLE)
  public void setDraggable(boolean isDraggable) {
    if (mDragHelper != null) {
      mDragHelper.setDraggable(isDraggable);
    }
    if (WXEnvironment.isApkDebugable()) {
      WXLogUtils.d("set draggable : " + isDraggable);
    }
  }

  @WXComponentProp(name = Constants.Name.SHOW_SCROLLBAR)
  public void setShowScrollbar(boolean show) {
    if(getHostView() == null || getHostView().getInnerView() == null){
      return;
    }
    if (getOrientation() == Constants.Orientation.VERTICAL) {
      getHostView().getInnerView().setVerticalScrollBarEnabled(show);
    } else {
      getHostView().getInnerView().setHorizontalScrollBarEnabled(show);
    }
  }

  @Override
  public boolean isScrollable() {
    return isScrollable;
  }


  private void setAppearanceWatch(WXComponent component, int event, boolean enable) {
    AppearanceHelper item = mAppearComponents.get(component.getRef());
    if (item != null) {
      item.setWatchEvent(event, enable);
    } else if (!enable) {
      //Do nothing if disable target not exist.
    } else {
      WXComponent dChild = findDirectListChild(component);
      int index = mChildren.indexOf(dChild);
      if (index != -1) {
        item = new AppearanceHelper(component, index);
        item.setWatchEvent(event, true);
        mAppearComponents.put(component.getRef(), item);
      }
    }
  }

  @Override
  public void bindAppearEvent(WXComponent component) {
    setAppearanceWatch(component, AppearanceHelper.APPEAR, true);
    if(mAppearChangeRunnable == null){
      mAppearChangeRunnable =  new Runnable() {
        @Override
        public void run() {
          if(mAppearChangeRunnable != null) {
            notifyAppearStateChange(0, 0, 0, 0);
          }
        }
      };
    }
    if (getHostView() != null) {
      getHostView().removeCallbacks(mAppearChangeRunnable);
      getHostView().postDelayed(mAppearChangeRunnable, mAppearChangeRunnableDelay);
    }
  }

  @Override
  public void bindDisappearEvent(WXComponent component) {
    setAppearanceWatch(component, AppearanceHelper.DISAPPEAR, true);
  }

  @Override
  public void unbindAppearEvent(WXComponent component) {
    setAppearanceWatch(component, AppearanceHelper.APPEAR, false);
  }

  @Override
  public void unbindDisappearEvent(WXComponent component) {
    setAppearanceWatch(component, AppearanceHelper.DISAPPEAR, false);
  }

  @Override
  public void scrollTo(WXComponent component, Map<String, Object> options) {
    float offsetFloat = 0;
    boolean smooth = true;

    if (options != null) {
      String offsetStr = options.get(Constants.Name.OFFSET) == null ? "0" : options.get(Constants.Name.OFFSET).toString();
      smooth = WXUtils.getBoolean(options.get(Constants.Name.ANIMATED), true);
      if (offsetStr != null) {
        try {
          offsetFloat = WXViewUtils.getRealPxByWidth(Float.parseFloat(offsetStr), getInstance().getInstanceViewPortWidth());
        }catch (Exception e ){
          WXLogUtils.e("Float parseFloat error :"+e.getMessage());
        }
      }
    }

    final int offset = (int) offsetFloat;

    T bounceRecyclerView = getHostView();
    if (bounceRecyclerView == null) {
      return;
    }

    WXComponent parent = component;
    WXCell cell = null;
    while (parent != null) {
      if (parent instanceof WXCell) {
        cell = (WXCell) parent;
        break;
      }
      parent = parent.getParent();
    }

    if (cell != null) {
      final int pos = mChildren.indexOf(cell);
      if (pos == -1) {
        //Invalid position
        return;
      }
      final WXRecyclerView view = bounceRecyclerView.getInnerView();
      view.scrollTo(smooth, pos, offset, getOrientation());
    }
  }

  @Override
  public void onBeforeScroll(int dx, int dy) {
    T bounceRecyclerView = getHostView();
    if (mStickyMap == null || bounceRecyclerView == null) {
      return;
    }
    Map<String, WXComponent> stickyMap = mStickyMap.get(getRef());
    if (stickyMap == null) {
      return;
    }
    Iterator<Map.Entry<String, WXComponent>> iterator = stickyMap.entrySet().iterator();
    Map.Entry<String, WXComponent> entry;
    WXComponent stickyComponent;
    int currentStickyPos = -1;
    while (iterator.hasNext()) {
      entry = iterator.next();
      stickyComponent = entry.getValue();

      if (stickyComponent != null && stickyComponent instanceof WXCell) {

        WXCell cell = (WXCell) stickyComponent;
        if (cell.getHostView() == null) {
          return;
        }

        int[] location = new int[2];
        stickyComponent.getHostView().getLocationOnScreen(location);
        int[] parentLocation = new int[2];
        stickyComponent.getParentScroller().getView().getLocationOnScreen(parentLocation);
        int top = location[1] - parentLocation[1];


        RecyclerView.LayoutManager layoutManager;
        boolean beforeFirstVisibleItem = false;
        boolean removeOldSticky = false;
        layoutManager = getHostView().getInnerView().getLayoutManager();
        if (layoutManager instanceof LinearLayoutManager || layoutManager instanceof GridLayoutManager) {
          int firstVisiblePosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
          int lastVisiblePosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
          int pos = mChildren.indexOf(cell);
          cell.setScrollPositon(pos);
          if (pos <= firstVisiblePosition
                  || (cell.getStickyOffset() > 0 && firstVisiblePosition < pos && pos <= lastVisiblePosition  &&
                  top <= cell.getStickyOffset())) {
            beforeFirstVisibleItem = true;
            if(pos > currentStickyPos) {
              currentStickyPos = pos;
            }
          }else{
            removeOldSticky = true;
          }
        } else if(layoutManager instanceof StaggeredGridLayoutManager){
          int [] firstItems= new int[3];
          int firstVisiblePosition = ((StaggeredGridLayoutManager) layoutManager).findFirstVisibleItemPositions(firstItems)[0];
          int lastVisiblePosition = ((StaggeredGridLayoutManager)  layoutManager).findLastVisibleItemPositions(firstItems)[0];
          int pos = mChildren.indexOf(cell);

          if (pos <= firstVisiblePosition || (cell.getStickyOffset() > 0 && firstVisiblePosition < pos && pos <= lastVisiblePosition  &&
                  top <= cell.getStickyOffset())) {
            beforeFirstVisibleItem = true;
            if(pos > currentStickyPos) {
              currentStickyPos = pos;
            }
          }else{
            removeOldSticky = true;
          }
        }


        boolean showSticky = beforeFirstVisibleItem && cell.getLocationFromStart() >= 0 && top <= cell.getStickyOffset() && dy >= 0;
        boolean removeSticky = cell.getLocationFromStart() <= cell.getStickyOffset() && top > cell.getStickyOffset() && dy <= 0;
        if (showSticky) {
          bounceRecyclerView.notifyStickyShow(cell);
        } else if (removeSticky || removeOldSticky) {
          bounceRecyclerView.notifyStickyRemove(cell);
        }
        cell.setLocationFromStart(top);
      }
    }

    if(currentStickyPos >= 0){
      bounceRecyclerView.updateStickyView(currentStickyPos);
    }else{
      if(bounceRecyclerView instanceof BounceRecyclerView){
        ((BounceRecyclerView) bounceRecyclerView).getStickyHeaderHelper().clearStickyHeaders();
      }
    }
  }

  @Override
  public int getScrollY() {
    T bounceRecyclerView = getHostView();
    return bounceRecyclerView == null ? 0 : bounceRecyclerView.getInnerView().getScrollY();
  }

  @Override
  public int getScrollX() {
    T bounceRecyclerView = getHostView();
    return bounceRecyclerView == null ? 0 : bounceRecyclerView.getInnerView().getScrollX();
  }

  /**
   * Append a child component to the end of list. This will not refresh the underlying
   * view immediately. The message of index of the inserted child is given to the adapter, and the
   * adapter will determine when to refresh. The default implementation of adapter will push the
   * message into a message and refresh the view in a period of time.
   *
   * @param child the inserted child
   */
  @Override
  public void addChild(WXComponent child) {
    addChild(child, -1);
  }

  @Override
  protected int getChildrenLayoutTopOffset() {
    return 0;
  }

  /**
   * @param child the inserted child
   * @param index the index of the child to be inserted.
   * @see #addChild(WXComponent)
   */
  @Override
  public void addChild(WXComponent child, int index) {
    super.addChild(child, index);
    if (child == null || index < -1) {
      return;
    }
    int count = mChildren.size();
    index = index >= count ? -1 : index;
    bindViewType(child);

    int adapterPosition = index == -1 ? mChildren.size() - 1 : index;
    final T view = getHostView();
    if (view != null) {
      boolean isAddAnimation = false;
      if (getBasicComponentData() != null) {
        Object attr = getAttrs().get(Constants.Name.INSERT_CELL_ANIMATION);
        if (Constants.Value.DEFAULT.equals(attr)) {
          isAddAnimation = true;
        }
      }
      if (isAddAnimation) {
        view.getInnerView().setItemAnimator(mItemAnimator);
      } else {
        view.getInnerView().setItemAnimator(null);
      }
      boolean isKeepScrollPosition =  false;
      if (child.getBasicComponentData() != null) {
        Object attr = child.getAttrs().get(Constants.Name.KEEP_SCROLL_POSITION);
        if (WXUtils.getBoolean(attr, false) && index <= getChildCount() && index>-1) {
          isKeepScrollPosition = true;
        }
      }
      if (isKeepScrollPosition) {
        if(view.getInnerView().getLayoutManager() instanceof  LinearLayoutManager){
          if(!view.getInnerView().isLayoutFrozen()){ //frozen, prevent layout when scroll
            view.getInnerView().setLayoutFrozen(true);
          }
          if(keepPositionCell == null){
            int last=((LinearLayoutManager)view.getInnerView().getLayoutManager()).findLastCompletelyVisibleItemPosition();
            ListBaseViewHolder holder = (ListBaseViewHolder) view.getInnerView().findViewHolderForAdapterPosition(last);
            if(holder != null){
              keepPositionCell = holder.getComponent();
            }
            if(keepPositionCell != null) {
              if(keepPositionCellRunnable != null){
                view.removeCallbacks(keepPositionCellRunnable);
              }
              keepPositionCellRunnable = new Runnable() {
                @Override
                public void run() {
                  if(keepPositionCell != null){
                    int keepPosition = indexOf(keepPositionCell);
                    int offset = 0;
                    if(keepPositionCell.getHostView() != null){
                      offset = keepPositionCell.getHostView().getTop();
                    }
                    if(offset > 0) {
                      ((LinearLayoutManager) view.getInnerView().getLayoutManager()).scrollToPositionWithOffset(keepPosition, offset);
                    }else{
                      view.getInnerView().getLayoutManager().scrollToPosition(keepPosition);

                    }
                    view.getInnerView().setLayoutFrozen(false);
                    keepPositionCell = null;
                    keepPositionCellRunnable = null;
                  }
                }
              };
            }
          }
          if(keepPositionCellRunnable == null){
            view.getInnerView().scrollToPosition(((LinearLayoutManager)view.getInnerView().getLayoutManager()).findLastVisibleItemPosition());
          }
        }
        view.getRecyclerViewBaseAdapter().notifyItemInserted(adapterPosition);
        if(keepPositionCellRunnable != null){
          view.removeCallbacks(keepPositionCellRunnable);
          view.postDelayed(keepPositionCellRunnable, keepPositionLayoutDelay);
        }
      } else {
        view.getRecyclerViewBaseAdapter().notifyItemChanged(adapterPosition);
      }
    }
    relocateAppearanceHelper();
  }

  private void relocateAppearanceHelper() {
    Iterator<Map.Entry<String, AppearanceHelper>> iterator = mAppearComponents.entrySet().iterator();
    while (iterator.hasNext()) {
      Map.Entry<String, AppearanceHelper> item = iterator.next();
      AppearanceHelper value = item.getValue();
      WXComponent dChild = findDirectListChild(value.getAwareChild());
      int index = mChildren.indexOf(dChild);
      value.setCellPosition(index);
    }
  }


  /**
   * RecyclerView manage its children in a way that different from {@link WXVContainer}. Therefore,
   * {@link WXVContainer#addSubView(View, int)} is an empty implementation in {@link
   * com.taobao.weex.ui.view.listview.WXRecyclerView}
   */
  @Override
  public void addSubView(View child, int index) {

  }

  /**
   * Remove the child from list. This method will use {@link
   * java.util.List#indexOf(Object)} to retrieve the component to be deleted. Like {@link
   * #addChild(WXComponent)}, this method will not refresh the view immediately, the adapter will
   * decide when to refresh.
   *
   * @param child the child to be removed
   */
  @Override
  public void remove(WXComponent child, boolean destroy) {
    int index = mChildren.indexOf(child);
    if (destroy) {
      child.detachViewAndClearPreInfo();
    }
    unBindViewType(child);

    T view = getHostView();
    if (view == null) {
      return;
    }

    boolean isRemoveAnimation = false;
    Object attr = getAttrs().get(Constants.Name.DELETE_CELL_ANIMATION);
    if (Constants.Value.DEFAULT.equals(attr)) {
      isRemoveAnimation = true;
    }
    if (isRemoveAnimation) {
      view.getInnerView().setItemAnimator(mItemAnimator);
    } else {
      view.getInnerView().setItemAnimator(null);
    }

    view.getRecyclerViewBaseAdapter().notifyItemRemoved(index);
    if (WXEnvironment.isApkDebugable()) {
      WXLogUtils.d(TAG, "removeChild child at " + index);
    }
    super.remove(child, destroy);
  }



  @Override
  public void computeVisiblePointInViewCoordinate(PointF pointF) {
    RecyclerView view = getHostView().getInnerView();
    pointF.set(view.computeHorizontalScrollOffset(), view.computeVerticalScrollOffset());
  }

  /**
   * Recycle viewHolder and its underlying view. This may because the view is removed or reused.
   * Either case, this method will be called.
   *
   * @param holder The view holder to be recycled.
   */
  @Override
  public void onViewRecycled(ListBaseViewHolder holder) {
    long begin = System.currentTimeMillis();

    holder.setComponentUsing(false);
    if (holder != null
            && holder.canRecycled()
            && holder.getComponent() != null
            && !holder.getComponent().isUsing()) {
      holder.recycled();

    } else {
      WXLogUtils.w(TAG, "this holder can not be allowed to  recycled");
    }
    if (WXEnvironment.isApkDebugable()) {
      WXLogUtils.d(TAG, "Recycle holder " + (System.currentTimeMillis() - begin) + "  Thread:" + Thread.currentThread().getName());
    }
  }

  /**
   * Bind the component of the position to the holder. Then flush the view.
   *
   * @param holder   viewHolder, which holds reference to the view
   * @param position position of component in list
   */
  @Override
  public void onBindViewHolder(final ListBaseViewHolder holder, int position) {
    if (holder == null) return;
    holder.setComponentUsing(true);
    WXComponent component = getChild(position);
    if (component == null
            || (component instanceof WXRefresh)
            || (component instanceof WXLoading)
            || (component.isFixed())
            ) {
      if (WXEnvironment.isApkDebugable()) {
        WXLogUtils.d(TAG, "Bind WXRefresh & WXLoading " + holder);
      }
      if(component instanceof  WXBaseRefresh
              && holder.getView() != null
              && (component.getAttrs().get("holderBackground") != null)){
        Object holderBackground = component.getAttrs().get("holderBackground");
        int color = WXResourceUtils.getColor(holderBackground.toString(), Color.WHITE);
        holder.getView().setBackgroundColor(color);
        holder.getView().setVisibility(View.VISIBLE);
        holder.getView().postInvalidate();
      }
      return;
    }

    if (holder.getComponent() != null && holder.getComponent() instanceof WXCell) {
      if(holder.isRecycled()) {
        holder.bindData(component);
        component.onRenderFinish(STATE_UI_FINISH);
      }
      if (mDragHelper == null || !mDragHelper.isDraggable()) {
        return;
      }
      mTriggerType = (mTriggerType == null) ? DEFAULT_TRIGGER_TYPE : mTriggerType;

      WXCell cell = (WXCell) holder.getComponent();
      boolean isExcluded = DEFAULT_EXCLUDED;
      WXAttr cellAttrs = cell.getAttrs();
      isExcluded = WXUtils.getBoolean(cellAttrs.get(EXCLUDED), DEFAULT_EXCLUDED);

      mDragHelper.setDragExcluded(holder, isExcluded);

      //NOTICE: event maybe consumed by other views
      if (DragTriggerType.PAN.equals(mTriggerType)) {
        mDragHelper.setLongPressDragEnabled(false);

        WXComponent anchorComponent = findComponentByAnchorName(cell, DRAG_ANCHOR);

        if (anchorComponent != null && anchorComponent.getHostView() != null && !isExcluded) {
          View anchor = anchorComponent.getHostView();
          anchor.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
              if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
                mDragHelper.startDrag(holder);
              }
              return true;
            }
          });
        } else {
          if (WXEnvironment.isApkDebugable()) {
            if(!isExcluded) {
              WXLogUtils.e(TAG, "[error] onBindViewHolder: the anchor component or view is not found");
            } else {
              WXLogUtils.d(TAG, "onBindViewHolder: position "+ position + " is drag excluded");
            }
          }
        }

      } else if (DragTriggerType.LONG_PRESS.equals(mTriggerType)) {
        mDragHelper.setLongPressDragEnabled(true);
      }
    }

  }

  protected void markComponentUsable(){
    for (WXComponent component : mChildren){
      component.setUsing(false);
    }
  }
  /**
   * Create an instance of {@link ListBaseViewHolder} for the given viewType (not for the given
   * index). This  markComponentUsable();method will look up for the first component that fits the viewType requirement and
   * doesn't be used. Then create the certain type of view, detach the view f[rom the component.
   *
   * @param parent   the ViewGroup into which the new view will be inserted
   * @param viewType the type of the new view
   * @return the created view holder.
   */
  @Override
  public ListBaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (mChildren != null) {
      if (mViewTypes == null)
        return createVHForFakeComponent(viewType);
      ArrayList<WXComponent> mTypes = mViewTypes.get(viewType);
      checkRecycledViewPool(viewType);
      if (mTypes == null)
        return createVHForFakeComponent(viewType);

      for (int i = 0; i < mTypes.size(); i++) {
        WXComponent component = mTypes.get(i);
        if (component == null
            || component.isUsing()) {
          continue;
        }
        if (component.isFixed()) {
          return createVHForFakeComponent(viewType);
        } else {
          if (component instanceof WXCell) {
            if (component.getRealView() != null) {
              return new ListBaseViewHolder(component, viewType);
            } else {
              ((WXCell) component).lazy(false);
              component.createView();
              component.applyLayoutAndEvent(component);
              return new ListBaseViewHolder(component, viewType);
            }
          } else if (component instanceof WXBaseRefresh) {
            return createVHForRefreshComponent(viewType);
          } else {
            WXLogUtils.e(TAG, "List cannot include element except cell、header、fixed、refresh and loading");
            return createVHForFakeComponent(viewType);
          }
        }
      }
    }
    if (WXEnvironment.isApkDebugable()) {
      WXLogUtils.e(TAG, "Cannot find request viewType: " + viewType);
    }
    return createVHForFakeComponent(viewType);
  }

  /**
   * Forbid ViewHolder cache if viewType > MAX_VIEWTYPE_ALLOW_CACHE
   *
   * @param viewType
   */
  private void checkRecycledViewPool(int viewType) {
    try {
      if (mViewTypes.size() > MAX_VIEWTYPE_ALLOW_CACHE)
        mAllowCacheViewHolder = false;

      if (mDownForBidCacheViewHolder)
        if (getHostView() != null && getHostView().getInnerView() != null)
          getHostView().getInnerView().getRecycledViewPool().setMaxRecycledViews(viewType, 0);

      if (!mDownForBidCacheViewHolder) {
        if (!mAllowCacheViewHolder) {
          if (getHostView() != null && getHostView().getInnerView() != null) {
            for (int i = 0; i < mViewTypes.size(); i++) {
              getHostView().getInnerView().getRecycledViewPool().setMaxRecycledViews(mViewTypes.keyAt(i), 0);
            }
            mDownForBidCacheViewHolder = true;
          }
        }
      }
    } catch (Exception e) {
      WXLogUtils.e(TAG, "Clear recycledViewPool error!");
    }
  }

  /**
   * Return the child component type. The type is defined by scopeValue in .we file.
   *
   * @param position the position of the child component.
   * @return the type of certain component.
   */
  @Override
  public int getItemViewType(int position) {
    return generateViewType(getChild(position));
  }

  @Nullable
  private WXComponent findComponentByAnchorName(@NonNull WXComponent root, @NonNull String anchorName) {
    long start = 0;
    if (WXEnvironment.isApkDebugable()) {
      start = System.currentTimeMillis();
    }

    Deque<WXComponent> deque = new ArrayDeque<>();
    deque.add(root);
    while (!deque.isEmpty()) {
      WXComponent curComponent = deque.removeFirst();
      if (curComponent != null) {
        String isAnchorSet = WXUtils.getString(curComponent.getAttrs().get(anchorName), null);

        //hit
        if (isAnchorSet != null && isAnchorSet.equals("true")) {
          if (WXEnvironment.isApkDebugable()) {
            WXLogUtils.d("dragPerf", "findComponentByAnchorName time: " + (System.currentTimeMillis() - start) + "ms");
          }
          return curComponent;
        }
      }
      if (curComponent instanceof WXVContainer) {
        WXVContainer container = (WXVContainer) curComponent;
        for (int i = 0, len = container.childCount(); i < len; i++) {
          WXComponent child = container.getChild(i);
          deque.add(child);
        }
      }
    }

    if (WXEnvironment.isApkDebugable()) {
      WXLogUtils.d("dragPerf", "findComponentByAnchorName elapsed time: " + (System.currentTimeMillis() - start) + "ms");
    }
    return null;

  }

  private String getTriggerType(@Nullable WXComponent component) {
    String triggerType = DEFAULT_TRIGGER_TYPE;
    if (component == null) {
      return triggerType;
    }
    triggerType = WXUtils.getString(component.getAttrs().get(DRAG_TRIGGER_TYPE), DEFAULT_TRIGGER_TYPE);
    if (!DragTriggerType.LONG_PRESS.equals(triggerType) && !DragTriggerType.PAN.equals(triggerType)) {
      triggerType = DEFAULT_TRIGGER_TYPE;
    }

    if (WXEnvironment.isApkDebugable()) {
      WXLogUtils.d(TAG, "trigger type is " + triggerType);
    }

    return triggerType;
  }


  /**
   * ViewType will be classified into {HashMap<Integer,ArrayList<Integer>> mViewTypes}
   *
   * @param component
   */
  private void bindViewType(WXComponent component) {
    int id = generateViewType(component);

    if (mViewTypes == null) {
      mViewTypes = new SparseArray<>();
    }

    ArrayList<WXComponent> mTypes = mViewTypes.get(id);

    if (mTypes == null) {
      mTypes = new ArrayList<>();
      mViewTypes.put(id, mTypes);
    }
    mTypes.add(component);
  }

  private void unBindViewType(WXComponent component) {
    int id = generateViewType(component);

    if (mViewTypes == null)
      return;
    ArrayList<WXComponent> mTypes = mViewTypes.get(id);
    if (mTypes == null)
      return;

    mTypes.remove(component);
  }

  /**
   * generate viewtype by component
   *
   * @param component
   * @return
   */
  private int generateViewType(WXComponent component) {
    long id;
    try {
      id = Integer.parseInt(component.getRef());
      String type = component.getAttrs().getScope();

      if (!TextUtils.isEmpty(type)) {
        if (mRefToViewType == null) {
          mRefToViewType = new ArrayMap<>();
        }
        if (!mRefToViewType.containsKey(type)) {
          mRefToViewType.put(type, id);
        }
        id = mRefToViewType.get(type);

      }
    } catch (RuntimeException e) {
      WXLogUtils.eTag(TAG, e);
      id = RecyclerView.NO_ID;
      WXLogUtils.e(TAG, "getItemViewType: NO ID, this will crash the whole render system of WXListRecyclerView");
    }
    return (int) id;
  }

  /**
   * Get child component num.
   *
   * @return return the size of {@link #mChildren} if mChildren is not empty, otherwise, return 0;
   */
  @Override
  public int getItemCount() {
    return getChildCount();
  }

  @Override
  public boolean onFailedToRecycleView(ListBaseViewHolder holder) {
    if (WXEnvironment.isApkDebugable()) {
      WXLogUtils.d(TAG, "Failed to recycle " + holder);
    }
    return false;
  }

  @Override
  public long getItemId(int position) {
    long id;
    try {
      id = Long.parseLong(getChild(position).getRef());
    } catch (RuntimeException e) {
      WXLogUtils.e(TAG, WXLogUtils.getStackTrace(e));
      id = RecyclerView.NO_ID;
    }
    return id;
  }

  @Override
  public void onLoadMore(int offScreenY) {
    try {
      String offset = getAttrs().getLoadMoreOffset();

      if (TextUtils.isEmpty(offset)) {
        offset = "0";
      }
      float offsetParsed = WXViewUtils.getRealPxByWidth(Integer.parseInt(offset),getInstance().getInstanceViewPortWidth());

      if (offScreenY < offsetParsed) {

        if (mListCellCount != mChildren.size()
            || mForceLoadmoreNextTime) {
          fireEvent(Constants.Event.LOADMORE);
          mListCellCount = mChildren.size();
          mForceLoadmoreNextTime = false;
        }
      }
    } catch (Exception e) {
      WXLogUtils.d(TAG + "onLoadMore :", e);
    }
  }

  @Override
  public void notifyAppearStateChange(int firstVisible, int lastVisible, int directionX, int directionY) {
    if(mAppearChangeRunnable != null) {
      getHostView().removeCallbacks(mAppearChangeRunnable);
      mAppearChangeRunnable = null;
    }
    //notify appear state
    Iterator<AppearanceHelper> it = mAppearComponents.values().iterator();
    String direction = directionY > 0 ? Constants.Value.DIRECTION_UP :
            directionY < 0 ? Constants.Value.DIRECTION_DOWN : null;
    if (getOrientation() == Constants.Orientation.HORIZONTAL && directionX != 0) {
      direction = directionX > 0 ? Constants.Value.DIRECTION_LEFT : Constants.Value.DIRECTION_RIGHT;
    }

    while (it.hasNext()) {
      AppearanceHelper item = it.next();
      WXComponent component = item.getAwareChild();

      if (!item.isWatch()) {
        continue;
      }


      View view = component.getHostView();
      if (view == null) {
        continue;
      }

      boolean outOfVisibleRange = !ViewCompat.isAttachedToWindow(view);
      boolean visible = (!outOfVisibleRange) && item.isViewVisible(true);

      int result = item.setAppearStatus(visible);
      if (result == AppearanceHelper.RESULT_NO_CHANGE) {
        continue;
      }
      if (WXEnvironment.isApkDebugable()) {
        WXLogUtils.d("appear", "item " + item.getCellPositionINScollable() + " result " + result);
      }
      component.notifyAppearStateChange(result == AppearanceHelper.RESULT_APPEAR ? Constants.Event.APPEAR : Constants.Event.DISAPPEAR, direction);
    }
  }

  @NonNull
  private ListBaseViewHolder createVHForFakeComponent(int viewType) {
    FrameLayout view = new FrameLayout(getContext());
    view.setBackgroundColor(Color.WHITE);
    view.setLayoutParams(new FrameLayout.LayoutParams(0, 0));
    return new ListBaseViewHolder(view, viewType);
  }


  private ListBaseViewHolder createVHForRefreshComponent(int viewType) {
    FrameLayout view = new FrameLayout(getContext());
    view.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1));
    return new ListBaseViewHolder(view, viewType);
  }

  @JSMethod
  public void resetLoadmore() {
    mForceLoadmoreNextTime = true;
    mListCellCount = 0;
  }

  @Override
  public void addEvent(String type) {
    super.addEvent(type);
    if (ScrollStartEndHelper.isScrollEvent(type)
            && getHostView() != null
            && getHostView().getInnerView() != null
            && !mHasAddScrollEvent) {
      mHasAddScrollEvent = true;
      WXRecyclerView innerView = getHostView().getInnerView();
      innerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        private int offsetXCorrection, offsetYCorrection;
        private boolean mFirstEvent = true;

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
          super.onScrolled(recyclerView, dx, dy);
//          WXLogUtils.e("SCROLL", dx + ", " + dy + ", " + recyclerView.computeHorizontalScrollRange()
//          + ", " + recyclerView.computeVerticalScrollRange()
//          + ", " + recyclerView.computeHorizontalScrollOffset()
//          + ", " + recyclerView.computeVerticalScrollOffset());

          int offsetX = recyclerView.computeHorizontalScrollOffset();
          int offsetY = recyclerView.computeVerticalScrollOffset();

          if (dx == 0 && dy == 0) {
            offsetXCorrection = offsetX;
            offsetYCorrection = offsetY;
            offsetX = 0;
            offsetY = 0;
          } else {
            offsetX = offsetX - offsetXCorrection;
            offsetY = offsetY - offsetYCorrection;
          }
          getScrollStartEndHelper().onScrolled(offsetX, offsetY);
          if(!getEvents().contains(Constants.Event.SCROLL)){
            return;
          }
          if (mFirstEvent) {
            //skip first event
            mFirstEvent = false;
            return;
          }

          RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
          if (!layoutManager.canScrollVertically()) {
            return;
          }

          if (shouldReport(offsetX, offsetY)) {
            fireScrollEvent(recyclerView, offsetX, offsetY);
          }
        }
      });
    }
  }

  private void fireScrollEvent(RecyclerView recyclerView, int offsetX, int offsetY) {
    fireEvent(Constants.Event.SCROLL, getScrollEvent(recyclerView, offsetX, offsetY));
  }

  public Map<String, Object> getScrollEvent(RecyclerView recyclerView, int offsetX, int offsetY){
    if(getOrientation() == Constants.Orientation.VERTICAL){
      offsetY = - calcContentOffset(recyclerView);
    }
    int contentWidth = recyclerView.getMeasuredWidth() + recyclerView.computeHorizontalScrollRange();
    int contentHeight = 0;
    for (int i = 0; i < getChildCount(); i++) {
      WXComponent child = getChild(i);
      if (child != null) {
        contentHeight += child.getLayoutHeight();
      }
    }

    Map<String, Object> event = new HashMap<>(2);
    Map<String, Object> contentSize = new HashMap<>(2);
    Map<String, Object> contentOffset = new HashMap<>(2);

    contentSize.put(Constants.Name.WIDTH, WXViewUtils.getWebPxByWidth(contentWidth, getInstance().getInstanceViewPortWidth()));
    contentSize.put(Constants.Name.HEIGHT, WXViewUtils.getWebPxByWidth(contentHeight, getInstance().getInstanceViewPortWidth()));

    contentOffset.put(Constants.Name.X, - WXViewUtils.getWebPxByWidth(offsetX, getInstance().getInstanceViewPortWidth()));
    contentOffset.put(Constants.Name.Y, - WXViewUtils.getWebPxByWidth(offsetY, getInstance().getInstanceViewPortWidth()));
    event.put(Constants.Name.CONTENT_SIZE, contentSize);
    event.put(Constants.Name.CONTENT_OFFSET, contentOffset);
    return event;
  }

  private boolean shouldReport(int offsetX, int offsetY) {
    if (mLastReport.x == -1 && mLastReport.y == -1) {
      mLastReport.x = offsetX;
      mLastReport.y = offsetY;
      return true;
    }

    int gapX = Math.abs(mLastReport.x - offsetX);
    int gapY = Math.abs(mLastReport.y - offsetY);

    if (gapX >= mOffsetAccuracy || gapY >= mOffsetAccuracy) {
      mLastReport.x = offsetX;
      mLastReport.y = offsetY;
      return true;
    }

    return false;
  }



  public int calcContentOffset(RecyclerView recyclerView) {
    RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
    if (layoutManager instanceof LinearLayoutManager) {
      int firstVisibleItemPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
      if (firstVisibleItemPosition == -1) {
        return 0;
      }

      View firstVisibleView = layoutManager.findViewByPosition(firstVisibleItemPosition);
      int firstVisibleViewOffset = 0;
      if (firstVisibleView != null) {
        firstVisibleViewOffset = firstVisibleView.getTop();
      }

      int offset = 0;
      for (int i=0;i<firstVisibleItemPosition;i++) {
        WXComponent child = getChild(i);
        if (child != null) {
          offset -= child.getLayoutHeight();
        }
      }

      if (layoutManager instanceof GridLayoutManager) {
        int spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
        offset = offset / spanCount;
      }

      offset += firstVisibleViewOffset;
      return offset;
    } else if (layoutManager instanceof StaggeredGridLayoutManager) {
      int spanCount = ((StaggeredGridLayoutManager) layoutManager).getSpanCount();
      int firstVisibleItemPosition = ((StaggeredGridLayoutManager) layoutManager).findFirstVisibleItemPositions(null)[0];
      if (firstVisibleItemPosition == -1) {
        return 0;
      }

      View firstVisibleView = layoutManager.findViewByPosition(firstVisibleItemPosition);
      int firstVisibleViewOffset = 0;
      if (firstVisibleView != null) {
        firstVisibleViewOffset = firstVisibleView.getTop();
      }

      int offset = 0;
      for (int i=0;i<firstVisibleItemPosition;i++) {
        WXComponent child = getChild(i);
        if (child != null) {
          offset -= child.getLayoutHeight();
        }
      }

      offset = offset / spanCount;
      offset += firstVisibleViewOffset;
      return offset;
    }
    //Unhandled LayoutManager type
    return -1;
  }

  public ScrollStartEndHelper getScrollStartEndHelper() {
    if(mScrollStartEndHelper == null){
      mScrollStartEndHelper = new ScrollStartEndHelper(this);
    }
    return mScrollStartEndHelper;
  }
}
