Fix ViewPager behavior with Nodes
Summary: Add a batch addition operation for ViewPager. Differential Revision: D3597840 fbshipit-source-id: 1c9c42e03da2492444298220e75f547b6567b4e5
This commit is contained in:
parent
32a717892c
commit
5f41769485
|
@ -9,15 +9,16 @@
|
||||||
|
|
||||||
package com.facebook.react.uimanager;
|
package com.facebook.react.uimanager;
|
||||||
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class providing children management API for view managers of classes extending ViewGroup.
|
* Class providing children management API for view managers of classes extending ViewGroup.
|
||||||
*/
|
*/
|
||||||
|
@ -45,6 +46,19 @@ public abstract class ViewGroupManager <T extends ViewGroup>
|
||||||
reorderChildrenByZIndex(parent);
|
reorderChildrenByZIndex(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method for batching a set of addView calls
|
||||||
|
* Note that this adds the views to the beginning of the ViewGroup
|
||||||
|
*
|
||||||
|
* @param parent the parent ViewGroup
|
||||||
|
* @param views the set of views to add
|
||||||
|
*/
|
||||||
|
public void addViews(T parent, List<View> views) {
|
||||||
|
for (int i = 0, size = views.size(); i < size; i++) {
|
||||||
|
addView(parent, views.get(i), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void setViewZIndex(View view, int zIndex) {
|
public static void setViewZIndex(View view, int zIndex) {
|
||||||
mZIndexHash.put(view, zIndex);
|
mZIndexHash.put(view, zIndex);
|
||||||
// zIndex prop gets set BEFORE the view is added, so parent may be null.
|
// zIndex prop gets set BEFORE the view is added, so parent may be null.
|
||||||
|
|
|
@ -28,11 +28,12 @@ import com.facebook.react.uimanager.events.NativeGestureUtil;
|
||||||
* views to custom {@link PagerAdapter} instance which is used by {@link NativeViewHierarchyManager}
|
* views to custom {@link PagerAdapter} instance which is used by {@link NativeViewHierarchyManager}
|
||||||
* to add children nodes according to react views hierarchy.
|
* to add children nodes according to react views hierarchy.
|
||||||
*/
|
*/
|
||||||
/* package */ class ReactViewPager extends ViewPager {
|
public class ReactViewPager extends ViewPager {
|
||||||
|
|
||||||
private class Adapter extends PagerAdapter {
|
private class Adapter extends PagerAdapter {
|
||||||
|
|
||||||
private final List<View> mViews = new ArrayList<>();
|
private final List<View> mViews = new ArrayList<>();
|
||||||
|
private boolean mIsViewPagerInIntentionallyInconsistentState = false;
|
||||||
|
|
||||||
void addView(View child, int index) {
|
void addView(View child, int index) {
|
||||||
mViews.add(index, child);
|
mViews.add(index, child);
|
||||||
|
@ -57,6 +58,32 @@ import com.facebook.react.uimanager.events.NativeGestureUtil;
|
||||||
setOffscreenPageLimit(mViews.size());
|
setOffscreenPageLimit(mViews.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace a set of views to the ViewPager adapter and update the ViewPager
|
||||||
|
*/
|
||||||
|
void setViews(List<View> views) {
|
||||||
|
mViews.clear();
|
||||||
|
mViews.addAll(views);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
|
||||||
|
// we want to make sure we return POSITION_NONE for every view here, since this is only
|
||||||
|
// called after a removeAllViewsFromAdapter
|
||||||
|
mIsViewPagerInIntentionallyInconsistentState = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all the views from the adapter and de-parents them from the ViewPager
|
||||||
|
* After calling this, it is expected that notifyDataSetChanged should be called soon
|
||||||
|
* afterwards.
|
||||||
|
*/
|
||||||
|
void removeAllViewsFromAdapter(ViewPager pager) {
|
||||||
|
mViews.clear();
|
||||||
|
pager.removeAllViews();
|
||||||
|
// set this, so that when the next addViews is called, we return POSITION_NONE for every
|
||||||
|
// entry so we can remove whichever views we need to and add the ones that we need to.
|
||||||
|
mIsViewPagerInIntentionallyInconsistentState = true;
|
||||||
|
}
|
||||||
|
|
||||||
View getViewAt(int index) {
|
View getViewAt(int index) {
|
||||||
return mViews.get(index);
|
return mViews.get(index);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +95,9 @@ import com.facebook.react.uimanager.events.NativeGestureUtil;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemPosition(Object object) {
|
public int getItemPosition(Object object) {
|
||||||
return mViews.contains(object) ? mViews.indexOf(object) : POSITION_NONE;
|
// if we've removed all views, we want to return POSITION_NONE intentionally
|
||||||
|
return mIsViewPagerInIntentionallyInconsistentState || !mViews.contains(object) ?
|
||||||
|
POSITION_NONE : mViews.indexOf(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -190,4 +219,12 @@ import com.facebook.react.uimanager.events.NativeGestureUtil;
|
||||||
/*package*/ View getViewFromAdapter(int index) {
|
/*package*/ View getViewFromAdapter(int index) {
|
||||||
return getAdapter().getViewAt(index);
|
return getAdapter().getViewAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setViews(List<View> views) {
|
||||||
|
getAdapter().setViews(views);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeAllViewsFromAdapter() {
|
||||||
|
getAdapter().removeAllViewsFromAdapter(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue