Skip to content

Commit

Permalink
fix(android): crash of sticky item view
Browse files Browse the repository at this point in the history
  • Loading branch information
siguangli2018 authored and zoomchan-cxj committed Jun 21, 2022
1 parent 350e0a0 commit f2c78d1
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 46 deletions.
Expand Up @@ -24,6 +24,7 @@

import androidx.annotation.NonNull;

import androidx.annotation.Nullable;
import com.tencent.mtt.hippy.HippyEngineContext;
import com.tencent.mtt.hippy.HippyInstanceLifecycleEventListener;
import com.tencent.mtt.hippy.HippyAPIProvider;
Expand Down Expand Up @@ -366,6 +367,21 @@ public void deleteChild(int pId, int childId, int childIndex) {
}
}

public void removeViewFromRegistry(int id) {
View view = mControllerRegistry.getView(id);
if (view instanceof ViewGroup) {
for (int i = ((ViewGroup) view).getChildCount() - 1; i >= 0; i--) {
View child = ((ViewGroup) view).getChildAt(i);
if (child != null) {
removeViewFromRegistry(child.getId());
}
}
}
if (view != null) {
mControllerRegistry.removeView(view.getId());
}
}

@SuppressLint("Range")
public void measureInWindow(int id, Promise promise) {
View v = mControllerRegistry.getView(id);
Expand Down
Expand Up @@ -217,19 +217,18 @@ public void batch() {
}

private void deleteSelfFromParent(RenderNode uiNode) {

LogUtils.d("RenderManager", "delete RenderNode " + uiNode.mId + " class " + uiNode.mClassName);
// mContext.getGlobalConfigs().getLogAdapter().log(TAG,"delete RenderNode " + uiNode.mId + " class " + uiNode.mClassName);
if (uiNode.mParent != null) {
uiNode.mParent.removeChild(uiNode);
if (uiNode == null) {
return;
}

mNodes.remove(uiNode.mId);

LogUtils.d("RenderManager", "delete RenderNode " + uiNode.mId + " class " + uiNode.mClassName);
int childCount = uiNode.getChildCount();
for (int i = 0; i < childCount; i++) {
deleteSelfFromParent(uiNode.getChildAt(0));
}
if (uiNode.mParent != null) {
uiNode.mParent.removeChild(uiNode);
}
mNodes.remove(uiNode.mId);
}

public DomNode createStyleNode(String className, boolean isVirtual, int id, int rootId) {
Expand Down
Expand Up @@ -28,6 +28,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.tencent.mtt.hippy.HippyEngineContext;
import com.tencent.mtt.hippy.uimanager.DiffUtils;
import com.tencent.mtt.hippy.uimanager.DiffUtils.PatchType;
Expand Down Expand Up @@ -156,6 +157,8 @@ public void deleteExistRenderView(ListItemRenderNode renderNode) {
if (parentNode != null) {
hpContext.getRenderManager().getControllerManager()
.deleteChild(parentNode.getId(), renderNode.getId());
} else {
hpContext.getRenderManager().getControllerManager().removeViewFromRegistry(renderNode.getId());
}
renderNode.setRecycleItemTypeChangeListener(null);
}
Expand Down
Expand Up @@ -33,6 +33,7 @@
import com.tencent.mtt.hippy.views.hippylist.recyclerview.helper.skikcy.IHeaderAttachListener;
import com.tencent.mtt.hippy.views.hippylist.recyclerview.helper.skikcy.IHeaderHost;
import com.tencent.mtt.hippy.views.hippylist.recyclerview.helper.skikcy.StickyHeaderHelper;
import java.util.ArrayList;

/**
* Created on 2020/12/22. Description
Expand Down Expand Up @@ -66,6 +67,12 @@ public HippyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs,
super(context, attrs, defStyle);
}

public void onDestroy() {
if (stickyHeaderHelper != null) {
stickyHeaderHelper.detachSticky();
}
}

public ADP getAdapter() {
return listAdapter;
}
Expand Down
Expand Up @@ -48,9 +48,6 @@ public class HippyRecyclerViewController<HRW extends HippyRecyclerViewWrapper> e
public static final String SCROLL_TO_INDEX = "scrollToIndex";
public static final String SCROLL_TO_CONTENT_OFFSET = "scrollToContentOffset";
public static final String SCROLL_TO_TOP = "scrollToTop";
public static final String COLLAPSE_PULL_HEADER = "collapsePullHeader";
public static final String COLLAPSE_PULL_HEADER_WITH_OPTIONS = "collapsePullHeaderWithOptions";
public static final String EXPAND_PULL_HEADER = "expandPullHeader";
public static final String HORIZONTAL = "horizontal";

public HippyRecyclerViewController() {
Expand All @@ -67,6 +64,11 @@ public View getChildAt(HRW viewGroup, int index) {
return viewGroup.getChildAtWithCaches(index);
}

@Override
public void onViewDestroy(HRW viewGroup) {
((HRW) viewGroup).getRecyclerView().onDestroy();
}

/**
* view 被Hippy的RenderNode 删除了,这样会导致View的child完全是空的,这个view是不能再被recyclerView复用了
* 否则如果被复用,在adapter的onBindViewHolder的时候,view的实际子view和renderNode的数据不匹配,diff会出现异常
Expand Down Expand Up @@ -243,35 +245,6 @@ public void dispatchFunction(HRW view, String functionName, HippyArray dataArray
view.scrollToTop();
break;
}
case COLLAPSE_PULL_HEADER: {
getAdapter(view).onHeaderRefreshCompleted();
break;
}
case COLLAPSE_PULL_HEADER_WITH_OPTIONS: {
HippyMap valueMap = dataArray.getMap(0);
if (valueMap == null) {
return;
}
final int time = valueMap.getInt("time");
final HippyRecyclerListAdapter adapter = getAdapter(view);
if (adapter == null) {
return;
}
if (time > 0) {
view.postDelayed(new Runnable() {
@Override
public void run() {
adapter.onHeaderRefreshCompleted();
}
}, time);
} else {
adapter.onHeaderRefreshCompleted();
}
}
case EXPAND_PULL_HEADER: {
getAdapter(view).enableHeaderRefresh();
break;
}
}
}

Expand Down
Expand Up @@ -24,6 +24,7 @@
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout.LayoutParams;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerViewBase;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.OnScrollListener;
Expand Down Expand Up @@ -86,7 +87,7 @@ public void setUpdateStickyViewWhenLayout(boolean bindStickyHolderWhenLayout) {
/**
* 如果当前stickHolder和新的stickyHolder 不一样,那么把当前的stickyHolder删除掉,并还原HeaderView的Translation
*/
private void detachSticky() {
public void detachSticky() {
if (headerOrgViewHolder != null) {
removeViewFromParent(this.currentHeaderView);
currentHeaderView.setTranslationY(0);
Expand Down
Expand Up @@ -28,6 +28,7 @@
import com.tencent.mtt.hippy.uimanager.PullHeaderRenderNode;
import com.tencent.mtt.hippy.uimanager.RenderNode;
import com.tencent.mtt.hippy.utils.LogUtils;
import com.tencent.mtt.hippy.views.hippylist.HippyRecyclerListAdapter;
import com.tencent.mtt.hippy.views.hippylist.HippyRecyclerView;
import com.tencent.mtt.hippy.views.hippylist.PullHeaderRefreshHelper;
import com.tencent.mtt.hippy.views.list.HippyListView;
Expand All @@ -40,6 +41,7 @@ public class HippyPullHeaderViewController extends HippyViewController<HippyPull
public static final String CLASS_NAME = "PullHeaderView";
public static final String COLLAPSE_PULL_HEADER = "collapsePullHeader";
public static final String EXPAND_PULL_HEADER = "expandPullHeader";
public static final String COLLAPSE_PULL_HEADER_WITH_OPTIONS = "collapsePullHeaderWithOptions";

@Override
protected View createViewImpl(Context context) {
Expand All @@ -59,7 +61,7 @@ public void onViewDestroy(HippyPullHeaderView pullHeaderView) {
pullHeaderView.onDestroy();
}

private void execListViewFunction(HippyListView listView, String functionName) {
private void execListViewFunction(final HippyListView listView, String functionName, HippyArray dataArray) {
switch (functionName) {
case COLLAPSE_PULL_HEADER: {
listView.onHeaderRefreshFinish();
Expand All @@ -69,13 +71,31 @@ private void execListViewFunction(HippyListView listView, String functionName) {
listView.onHeaderRefresh();
break;
}
case COLLAPSE_PULL_HEADER_WITH_OPTIONS: {
HippyMap valueMap = dataArray.getMap(0);
if (valueMap == null) {
return;
}
final int time = valueMap.getInt("time");
if (time > 0) {
listView.postDelayed(new Runnable() {
@Override
public void run() {
listView.onHeaderRefreshFinish();
}
}, time);
} else {
listView.onHeaderRefreshFinish();
}
break;
}
default: {
LogUtils.w(TAG, "Unknown function name: " + functionName);
}
}
}

private void execRecyclerViewFunction(HippyRecyclerView recyclerView, String functionName) {
private void execRecyclerViewFunction(HippyRecyclerView recyclerView, String functionName, HippyArray dataArray) {
switch (functionName) {
case COLLAPSE_PULL_HEADER: {
recyclerView.getAdapter().onHeaderRefreshCompleted();
Expand All @@ -85,8 +105,30 @@ private void execRecyclerViewFunction(HippyRecyclerView recyclerView, String fun
recyclerView.getAdapter().enableHeaderRefresh();
break;
}
case COLLAPSE_PULL_HEADER_WITH_OPTIONS: {
HippyMap valueMap = dataArray.getMap(0);
if (valueMap == null) {
return;
}
final int time = valueMap.getInt("time");
final HippyRecyclerListAdapter adapter = recyclerView.getAdapter();
if (adapter == null) {
return;
}
if (time > 0) {
recyclerView.postDelayed(new Runnable() {
@Override
public void run() {
adapter.onHeaderRefreshCompleted();
}
}, time);
} else {
adapter.onHeaderRefreshCompleted();
}
break;
}
default: {
LogUtils.e(TAG, "Unknown function name: " + functionName);
LogUtils.w(TAG, "Unknown function name: " + functionName);
}
}
}
Expand All @@ -97,9 +139,9 @@ public void dispatchFunction(HippyPullHeaderView view, String functionName,
super.dispatchFunction(view, functionName, dataArray);
View parent = view.getRecyclerView();
if (parent instanceof HippyListView) {
execListViewFunction((HippyListView) parent, functionName);
execListViewFunction((HippyListView) parent, functionName, dataArray);
} else if (parent instanceof HippyRecyclerView) {
execRecyclerViewFunction((HippyRecyclerView) parent, functionName);
execRecyclerViewFunction((HippyRecyclerView) parent, functionName, dataArray);
}
}
}

0 comments on commit f2c78d1

Please sign in to comment.