| Index: chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/InnerNode.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/InnerNode.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/InnerNode.java
|
| index 3d6c70be4c444235ffea705d1614ee91ca577f63..0c57425be4eae349cdee5aaf94c3c5987a1a61da 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/InnerNode.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/InnerNode.java
|
| @@ -4,62 +4,58 @@
|
|
|
| package org.chromium.chrome.browser.ntp.cards;
|
|
|
| +import org.chromium.base.VisibleForTesting;
|
| import org.chromium.chrome.browser.ntp.snippets.SnippetArticle;
|
|
|
| +import java.util.ArrayList;
|
| import java.util.List;
|
|
|
| /**
|
| * An inner node in the tree: the root of a subtree, with a list of child nodes.
|
| */
|
| -public abstract class InnerNode extends ChildNode implements NodeParent {
|
| - public InnerNode(NodeParent parent) {
|
| - super(parent);
|
| - }
|
| -
|
| - protected abstract List<TreeNode> getChildren();
|
| +public class InnerNode extends ChildNode implements NodeParent {
|
| + private final List<TreeNode> mChildren = new ArrayList<>();
|
|
|
| private int getChildIndexForPosition(int position) {
|
| if (position < 0) {
|
| throw new IndexOutOfBoundsException(Integer.toString(position));
|
| }
|
| - List<TreeNode> children = getChildren();
|
| int numItems = 0;
|
| - int numChildren = children.size();
|
| + int numChildren = mChildren.size();
|
| for (int i = 0; i < numChildren; i++) {
|
| - numItems += children.get(i).getItemCount();
|
| + numItems += mChildren.get(i).getItemCount();
|
| if (position < numItems) return i;
|
| }
|
| throw new IndexOutOfBoundsException(position + "/" + numItems);
|
| }
|
|
|
| private int getStartingOffsetForChildIndex(int childIndex) {
|
| - List<TreeNode> children = getChildren();
|
| - if (childIndex < 0 || childIndex >= children.size()) {
|
| - throw new IndexOutOfBoundsException(childIndex + "/" + children.size());
|
| + if (childIndex < 0 || childIndex >= mChildren.size()) {
|
| + throw new IndexOutOfBoundsException(childIndex + "/" + mChildren.size());
|
| }
|
|
|
| int offset = 0;
|
| for (int i = 0; i < childIndex; i++) {
|
| - offset += children.get(i).getItemCount();
|
| + offset += mChildren.get(i).getItemCount();
|
| }
|
| return offset;
|
| }
|
|
|
| int getStartingOffsetForChild(TreeNode child) {
|
| - return getStartingOffsetForChildIndex(getChildren().indexOf(child));
|
| + return getStartingOffsetForChildIndex(mChildren.indexOf(child));
|
| }
|
|
|
| /**
|
| * Returns the child whose subtree contains the item at the given position.
|
| */
|
| TreeNode getChildForPosition(int position) {
|
| - return getChildren().get(getChildIndexForPosition(position));
|
| + return mChildren.get(getChildIndexForPosition(position));
|
| }
|
|
|
| @Override
|
| public int getItemCount() {
|
| int numItems = 0;
|
| - for (TreeNode child : getChildren()) {
|
| + for (TreeNode child : mChildren) {
|
| numItems += child.getItemCount();
|
| }
|
| return numItems;
|
| @@ -69,28 +65,28 @@ public int getItemCount() {
|
| @ItemViewType
|
| public int getItemViewType(int position) {
|
| int index = getChildIndexForPosition(position);
|
| - return getChildren().get(index).getItemViewType(
|
| + return mChildren.get(index).getItemViewType(
|
| position - getStartingOffsetForChildIndex(index));
|
| }
|
|
|
| @Override
|
| public void onBindViewHolder(NewTabPageViewHolder holder, int position) {
|
| int index = getChildIndexForPosition(position);
|
| - getChildren().get(index).onBindViewHolder(
|
| + mChildren.get(index).onBindViewHolder(
|
| holder, position - getStartingOffsetForChildIndex(index));
|
| }
|
|
|
| @Override
|
| public SnippetArticle getSuggestionAt(int position) {
|
| int index = getChildIndexForPosition(position);
|
| - return getChildren().get(index).getSuggestionAt(
|
| + return mChildren.get(index).getSuggestionAt(
|
| position - getStartingOffsetForChildIndex(index));
|
| }
|
|
|
| @Override
|
| public int getDismissSiblingPosDelta(int position) {
|
| int index = getChildIndexForPosition(position);
|
| - return getChildren().get(index).getDismissSiblingPosDelta(
|
| + return mChildren.get(index).getDismissSiblingPosDelta(
|
| position - getStartingOffsetForChildIndex(index));
|
| }
|
|
|
| @@ -109,33 +105,63 @@ public void onItemRangeRemoved(TreeNode child, int index, int count) {
|
| notifyItemRangeRemoved(getStartingOffsetForChild(child) + index, count);
|
| }
|
|
|
| - @Override
|
| - public void init() {
|
| - super.init();
|
| - for (TreeNode child : getChildren()) {
|
| - child.init();
|
| - }
|
| - }
|
| -
|
| /**
|
| - * Helper method for adding a new child node. Notifies about the inserted items and initializes
|
| - * the child.
|
| + * Helper method that adds a new child node and notifies about its insertion.
|
| *
|
| * @param child The child node to be added.
|
| */
|
| - protected void didAddChild(TreeNode child) {
|
| + protected void addChild(TreeNode child) {
|
| + int insertedIndex = getItemCount();
|
| + mChildren.add(child);
|
| + child.setParent(this);
|
| +
|
| int count = child.getItemCount();
|
| - if (count > 0) onItemRangeInserted(child, 0, count);
|
| - child.init();
|
| + if (count > 0) notifyItemRangeInserted(insertedIndex, count);
|
| + }
|
| +
|
| + /**
|
| + * Helper method that adds all the children and notifies about the inserted items.
|
| + */
|
| + protected void addChildren(TreeNode... children) {
|
| + int initialCount = getItemCount();
|
| + for (TreeNode child : children) {
|
| + mChildren.add(child);
|
| + child.setParent(this);
|
| + }
|
| +
|
| + int addedCount = getItemCount() - initialCount;
|
| + if (addedCount > 0) notifyItemRangeInserted(initialCount, addedCount);
|
| }
|
|
|
| /**
|
| - * Helper method for removing a child node. Notifies about the removed items.
|
| + * Helper method that removes a child node and notifies about the removed items.
|
| *
|
| * @param child The child node to be removed.
|
| */
|
| - protected void willRemoveChild(TreeNode child) {
|
| + protected void removeChild(TreeNode child) {
|
| + int removedIndex = mChildren.indexOf(child);
|
| + if (removedIndex == -1) throw new IndexOutOfBoundsException();
|
| +
|
| int count = child.getItemCount();
|
| - if (count > 0) onItemRangeRemoved(child, 0, count);
|
| + int childStartingOffset = getStartingOffsetForChildIndex(removedIndex);
|
| +
|
| + mChildren.remove(removedIndex);
|
| + if (count > 0) notifyItemRangeRemoved(childStartingOffset, count);
|
| + }
|
| +
|
| + /**
|
| + * Helper method that removes all the children and notifies about the removed items.
|
| + */
|
| + protected void removeChildren() {
|
| + int itemCount = getItemCount();
|
| + if (itemCount == 0) return;
|
| +
|
| + mChildren.clear();
|
| + notifyItemRangeRemoved(0, itemCount);
|
| + }
|
| +
|
| + @VisibleForTesting
|
| + final List<TreeNode> getChildren() {
|
| + return mChildren;
|
| }
|
| }
|
|
|