Пример #1
0
 @Override
 public long getItemId(int position) {
   long id;
   try {
     id = Long.parseLong(getChild(position).getDomObject().getRef());
   } catch (RuntimeException e) {
     WXLogUtils.e(TAG, WXLogUtils.getStackTrace(e));
     id = RecyclerView.NO_ID;
   }
   return id;
 }
Пример #2
0
 /**
  * These transform functions are supported: - `scale(x,y)`: scale item, x and y should be a
  * positive float number. - `translate(x,y)`: translate item, `x` and `y` shoule be integer
  * numbers. - `opacity(n)`: change the transparency of item, `n` must in `[0,1.0]`. - `rotate(n)`:
  * rotate item, n is integer number.
  *
  * @param raw
  * @return
  */
 private RecyclerView.ItemDecoration parseTransforms(String raw) {
   if (raw == null) {
     return null;
   }
   float scaleX = 0f, scaleY = 0f;
   int translateX = 0, translateY = 0;
   float opacity = 0f;
   int rotate = 0;
   // public TransformItemDecoration(boolean isVertical,float alpha,int translateX,int
   // translateY,int rotation,float scale)
   Matcher matcher = transformPattern.matcher(raw);
   while (matcher.find()) {
     String match = matcher.group();
     String name = matcher.group(1);
     try {
       switch (name) {
         case "scale":
           scaleX = Float.parseFloat(matcher.group(2));
           scaleY = Float.parseFloat(matcher.group(3));
           break;
         case "translate":
           translateX = Integer.parseInt(matcher.group(2));
           translateY = Integer.parseInt(matcher.group(3));
           break;
         case "opacity":
           opacity = Float.parseFloat(matcher.group(2));
           break;
         case "rotate":
           rotate = Integer.parseInt(matcher.group(2));
           break;
         default:
           WXLogUtils.e(TAG, "Invaild transform expression:" + match);
           break;
       }
     } catch (NumberFormatException e) {
       WXLogUtils.e("", e);
       WXLogUtils.e(TAG, "Invaild transform expression:" + match);
     }
   }
   return new TransformItemDecoration(
       getOrientation() == Constants.Orientation.VERTICAL,
       opacity,
       translateX,
       translateY,
       rotate,
       scaleX,
       scaleY);
 }
Пример #3
0
  /**
   * 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!");
    }
  }
Пример #4
0
 @Override
 public boolean onFailedToRecycleView(ListBaseViewHolder holder) {
   if (WXEnvironment.isApkDebugable()) {
     WXLogUtils.d(TAG, "Failed to recycle " + holder);
   }
   return false;
 }
Пример #5
0
  /**
   * Create an instance of {@link ListBaseViewHolder} for the given viewType (not for the given
   * index). This 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.getDomObject() != null && component.getDomObject().isFixed()) {
          return createVHForFakeComponent(viewType);
        } else {
          if (component instanceof WXCell) {
            if (component.getRealView() != null) {
              return new ListBaseViewHolder(component, viewType);
            } else {
              component.lazy(false);
              component.createView(this, -1);
              component.applyLayoutAndEvent(component);
              return new ListBaseViewHolder(component, 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);
  }
Пример #6
0
 /**
  * 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);
   recycleViewList.add(holder);
   if (WXEnvironment.isApkDebugable()) {
     WXLogUtils.d(
         TAG,
         "Recycle holder "
             + (System.currentTimeMillis() - begin)
             + "  Thread:"
             + Thread.currentThread().getName());
   }
 }
Пример #7
0
 /** Update all components' dom info stored in {@link #mAddDom} */
 private void updateDomObj() {
   long start = System.currentTimeMillis();
   Iterator<Map.Entry<String, AddDomInfo>> iterator = mAddDom.entrySet().iterator();
   Map.Entry<String, AddDomInfo> entry;
   AddDomInfo value;
   while (iterator.hasNext()) {
     entry = iterator.next();
     value = entry.getValue();
     updateDomObj(value.component);
   }
   if (WXEnvironment.isApkDebugable()) {
     WXLogUtils.d("updateDomObj", "time:" + (System.currentTimeMillis() - start));
   }
 }
Пример #8
0
  /**
   * generate viewtype by component
   *
   * @param component
   * @return
   */
  private int generateViewType(WXComponent component) {
    long id;
    try {
      id = Integer.parseInt(component.getDomObject().getRef());
      String type = component.getDomObject().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;
  }
Пример #9
0
 private WXAnimationBean createAnimationBean(String ref, String animation) {
   try {
     WXAnimationBean animationBean = JSONObject.parseObject(animation, WXAnimationBean.class);
     if (animationBean != null && animationBean.styles != null) {
       WXDomObject domObject = mRegistry.get(ref);
       int width = (int) domObject.getLayoutWidth();
       int height = (int) domObject.getLayoutHeight();
       animationBean.styles.init(
           animationBean.styles.transformOrigin, animationBean.styles.transform, width, height);
     }
     return animationBean;
   } catch (RuntimeException e) {
     WXLogUtils.e("", e);
     return null;
   }
 }
Пример #10
0
  private void recycleImage(View view) {
    if (view instanceof ImageView) {
      if (getInstance().getImgLoaderAdapter() != null) {
        getInstance().getImgLoaderAdapter().setImage(null, (ImageView) view, null, null);
      } else {
        if (WXEnvironment.isApkDebugable()) {
          throw new WXRuntimeException("getImgLoaderAdapter() == null");
        }
        WXLogUtils.e("Error getImgLoaderAdapter() == null");
      }

    } else if (view instanceof ViewGroup) {
      for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
        recycleImage(((ViewGroup) view).getChildAt(i));
      }
    }
  }
Пример #11
0
  @Override
  public void remove(WXComponent child, boolean destroy) {
    int index = mChildren.indexOf(child);
    if (destroy) {
      child.detachViewAndClearPreInfo();
    }
    unBindViewType(child);

    BounceRecyclerView view = getHostView();
    if (view == null) {
      return;
    }
    view.getAdapter().notifyItemRemoved(index);
    if (WXEnvironment.isApkDebugable()) {
      WXLogUtils.d(TAG, "removeChild child at " + index);
    }
    super.remove(child, destroy);
  }
Пример #12
0
  @Override
  public void notifyAppearStateChange(
      int firstVisible, int lastVisible, int directionX, int directionY) {
    // notify appear state
    Iterator<AppearanceHelper> it = mAppearComponents.values().iterator();
    String direction = directionY > 0 ? "up" : "down";
    if (getOrientation() == Constants.Orientation.HORIZONTAL) {
      direction = directionX > 0 ? "left" : "right";
    }

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

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

      boolean outOfVisibleRange =
          item.getCellPositionINScollable() < firstVisible
              || item.getCellPositionINScollable() > lastVisible;

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

      boolean visible = (!outOfVisibleRange) && item.isViewVisible();

      int result = item.setAppearStatus(visible);
      if (WXEnvironment.isApkDebugable()) {
        WXLogUtils.d("appear", "item " + item.getCellPositionINScollable() + " result " + result);
      }
      if (result == AppearanceHelper.RESULT_NO_CHANGE) {
        continue;
      }
      component.notifyAppearStateChange(
          result == AppearanceHelper.RESULT_APPEAR
              ? Constants.Event.APPEAR
              : Constants.Event.DISAPPEAR,
          direction);
    }
  }
Пример #13
0
 private WXAnimationBean createAnimationBean(String ref, Map<String, Object> style) {
   if (style != null) {
     try {
       Object transform = style.get(WXDomObject.TRANSFORM);
       if (transform instanceof String && !TextUtils.isEmpty((String) transform)) {
         String transformOrigin = (String) style.get(WXDomObject.TRANSFORM_ORIGIN);
         WXAnimationBean animationBean = new WXAnimationBean();
         WXDomObject domObject = mRegistry.get(ref);
         int width = (int) domObject.getLayoutWidth();
         int height = (int) domObject.getLayoutHeight();
         animationBean.styles = new WXAnimationBean.Style();
         animationBean.styles.init(transformOrigin, (String) transform, width, height);
         return animationBean;
       }
     } catch (RuntimeException e) {
       WXLogUtils.e("", e);
       return null;
     }
   }
   return null;
 }
Пример #14
0
  /**
   * 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 WXListComponent
   */
  @Override
  public void onBindViewHolder(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.getDomObject() != null && component.getDomObject().isFixed())) {
      if (WXEnvironment.isApkDebugable()) {
        WXLogUtils.d(TAG, "Bind WXRefresh & WXLoading " + holder);
      }
      return;
    }

    if (component != null
        && holder.getComponent() != null
        && holder.getComponent() instanceof WXCell) {

      holder.getComponent().bindData(component);
      //              holder.getComponent().refreshData(component);
    }
  }
Пример #15
0
  @Override
  public void onLoadMore(int offScreenY) {
    try {
      String offset = getDomObject().getAttrs().getLoadMoreOffset();

      if (TextUtils.isEmpty(offset)) {
        offset = "0";
      }

      if (offScreenY < Integer.parseInt(offset)) {
        String loadMoreRetry = getDomObject().getAttrs().getLoadMoreRetry();

        if (mListCellCount != mChildren.size()
            || mLoadMoreRetry == null
            || !mLoadMoreRetry.equals(loadMoreRetry)) {
          getInstance().fireEvent(getDomObject().getRef(), Constants.Event.LOADMORE);
          mListCellCount = mChildren.size();
          mLoadMoreRetry = loadMoreRetry;
        }
      }
    } catch (Exception e) {
      WXLogUtils.d(TAG + "onLoadMore :", e);
    }
  }
Пример #16
0
  /**
   * Create a command object for adding a dom node to its parent in a specific location. If dom's
   * parent doesn't exist or the dom has been added in current {@link WXSDKInstance}, this method
   * will return. If the above request is met, then put the command object in the queue.
   *
   * @param dom the dom object in the form of JSONObject
   * @param parentRef parent to which the dom is added.
   * @param index the location of which the dom is added.
   */
  void addDom(JSONObject dom, final String parentRef, final int index) {
    if (mDestroy) {
      return;
    }
    WXDomObject parent = mRegistry.get(parentRef);
    WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);

    if (parent == null) {
      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_ADDELEMENT);
      }
      return;
    }
    WXDomObject domObject = parseInner(dom);

    if (domObject == null || mRegistry.containsKey(domObject.getRef())) {
      if (WXEnvironment.isApkDebugable()) {
        WXLogUtils.e("[WXDomStatement] addDom error!!");
      }
      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_ADDELEMENT);
      }
      return;
    }

    findFixed(domObject);

    parent.add(domObject, index);

    transformStyle(domObject, true);

    // Create component in dom thread
    final WXComponent component =
        mWXRenderManager.createComponentOnDomThread(mInstanceId, domObject, parentRef, index);
    if (component == null) {
      // stop redner, some fatal happened.
      return;
    }
    AddDomInfo addDomInfo = new AddDomInfo();
    addDomInfo.component = component;
    mAddDom.put(domObject.getRef(), addDomInfo);

    mNormalTasks.add(
        new IWXRenderTask() {

          @Override
          public void execute() {
            WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
            if (instance == null || instance.getContext() == null) {
              WXLogUtils.e("instance is null or instance is destroy!");
              return;
            }
            try {
              mWXRenderManager.addComponent(mInstanceId, component, parentRef, index);
            } catch (Exception e) {
              WXLogUtils.e("add component failed.", e);
            }
          }

          @Override
          public String toString() {
            return "AddDom";
          }
        });
    animations.add(
        new Pair<String, Map<String, Object>>(domObject.getRef(), domObject.getStyles()));
    mDirty = true;

    if (instance != null) {
      instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS);
    }
  }
Пример #17
0
  /**
   * Create command object for creating body according to the JSONObject. And put the command object
   * in the queue.
   *
   * @param element the jsonObject according to which to create command object.
   */
  void createBody(JSONObject element) {
    if (mDestroy) {
      return;
    }
    WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
    if (element == null) {
      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_CREATEBODY);
      }
      return;
    }

    WXDomObject domObject = parseInner(element);
    if (domObject == null) {
      return;
    }
    Map<String, Object> style = new HashMap<>(5);
    if (!domObject.getStyles().containsKey(Constants.Name.FLEX_DIRECTION)) {
      style.put(Constants.Name.FLEX_DIRECTION, "column");
    }
    if (!domObject.getStyles().containsKey(Constants.Name.BACKGROUND_COLOR)) {
      style.put(Constants.Name.BACKGROUND_COLOR, "#ffffff");
    }
    // If there is height or width in JS, then that value will override value here.
    if (!domObject.getStyles().containsKey(Constants.Name.WIDTH)) {
      style.put(
          Constants.Name.WIDTH, WXViewUtils.getWebPxByWidth(WXViewUtils.getWeexWidth(mInstanceId)));
      domObject.setModifyWidth(true);
    }
    if (!domObject.getStyles().containsKey(Constants.Name.HEIGHT)) {
      style.put(
          Constants.Name.HEIGHT,
          WXViewUtils.getWebPxByWidth(WXViewUtils.getWeexHeight(mInstanceId)));
      domObject.setModifyHeight(true);
    }
    WXDomObject.prepareRoot(domObject);
    domObject.updateStyle(style);
    transformStyle(domObject, true);

    try {
      final WXComponent component = mWXRenderManager.createBodyOnDomThread(mInstanceId, domObject);
      AddDomInfo addDomInfo = new AddDomInfo();
      addDomInfo.component = component;
      mAddDom.put(domObject.getRef(), addDomInfo);

      mNormalTasks.add(
          new IWXRenderTask() {

            @Override
            public void execute() {
              WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
              if (instance == null || instance.getContext() == null) {
                WXLogUtils.e("instance is null or instance is destroy!");
                return;
              }
              try {
                mWXRenderManager.createBody(mInstanceId, component);
              } catch (Exception e) {
                WXLogUtils.e("create body failed.", e);
              }
            }

            @Override
            public String toString() {
              return "createBody";
            }
          });
      animations.add(
          new Pair<String, Map<String, Object>>(domObject.getRef(), domObject.getStyles()));
      mDirty = true;

      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS);
      }
    } catch (Exception e) {

      WXLogUtils.e("create body in dom thread failed." + e.getMessage());
    }
  }