Commit 2f131cfd authored by Bernhard Bauer's avatar Bernhard Bauer Committed by Commit Bot

Further simplify SimpleRecyclerViewMcp handling

Add observers automatically, which allows constructing the MCP and the
adapter inline. To support this, split ListObservable into an interface
and an implementation class ListObservableImpl, so that
RecyclerViewAdapter.Delegate extends ListObservable.

Also, remove the payload type (which currently is Void everywhere) from
SimpleRecyclerViewMcp and its ViewBinder. It will be reintroduced in a
dedicated MCP class for adapters that do support partial binding.

Bug: 847420
Change-Id: Ie34108836560e0a63a4259150366640d2fcfbe6b
Reviewed-on: https://chromium-review.googlesource.com/1112016Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Reviewed-by: default avatarFriedrich Horschig <fhorschig@chromium.org>
Commit-Queue: Bernhard Bauer <bauerb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#570026}
parent e11e9c7f
......@@ -9,7 +9,6 @@ import android.view.ViewStub;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.autofill.AutofillKeyboardSuggestions;
import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Action;
import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryViewBinder.ActionViewHolder;
import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryViewBinder.TabViewBinder;
import org.chromium.chrome.browser.modelutil.LazyViewBinderAdapter;
......@@ -83,13 +82,9 @@ public class KeyboardAccessoryCoordinator {
*/
static RecyclerViewAdapter<ActionViewHolder, Void> createActionsAdapter(
KeyboardAccessoryModel model) {
SimpleRecyclerViewMcp<Action, ActionViewHolder, Void> processor =
new SimpleRecyclerViewMcp<>(model.getActionList(), null, ActionViewHolder::bind);
RecyclerViewAdapter<ActionViewHolder, Void> actionsAdapter =
new RecyclerViewAdapter<>(processor, ActionViewHolder::create);
processor.addObserver(actionsAdapter);
model.addActionListObserver(processor);
return actionsAdapter;
return new RecyclerViewAdapter<>(
new SimpleRecyclerViewMcp<>(model.getActionList(), null, ActionViewHolder::bind),
ActionViewHolder::create);
}
/**
......
......@@ -4,7 +4,6 @@
package org.chromium.chrome.browser.autofill.keyboard_accessory;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
......@@ -37,7 +36,7 @@ class KeyboardAccessoryViewBinder
.inflate(R.layout.keyboard_accessory_action, parent, false));
}
public void bind(Action action, @Nullable Void payload) {
public void bind(Action action) {
getActionView().setText(action.getCaption());
getActionView().setOnClickListener(view -> action.getCallback().onResult(action));
}
......
......@@ -80,13 +80,9 @@ public class PasswordAccessorySheetCoordinator {
*/
static RecyclerViewAdapter<ItemViewHolder, Void> createAdapter(
SimpleListObservable<Item> model) {
SimpleRecyclerViewMcp<Item, ItemViewHolder, Void> processor =
new SimpleRecyclerViewMcp<>(model, Item::getType, ItemViewHolder::bind);
RecyclerViewAdapter<ItemViewHolder, Void> adapter =
new RecyclerViewAdapter<>(processor, ItemViewHolder::create);
model.addObserver(processor);
processor.addObserver(adapter);
return adapter;
return new RecyclerViewAdapter<>(
new SimpleRecyclerViewMcp<>(model, Item::getType, ItemViewHolder::bind),
ItemViewHolder::create);
}
// TODO(fhorschig): There is only one. Make this a ctor param and self-destruct with it.
......@@ -111,4 +107,4 @@ public class PasswordAccessorySheetCoordinator {
SimpleListObservable<Item> getModelForTesting() {
return mModel;
}
}
\ No newline at end of file
}
......@@ -4,7 +4,6 @@
package org.chromium.chrome.browser.autofill.keyboard_accessory;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.method.PasswordTransformationMethod;
......@@ -64,9 +63,8 @@ class PasswordAccessorySheetViewBinder {
* Binds the item's state to the held {@link View}. Subclasses of this generic view holder
* might want to actually bind the item state to the view.
* @param item The item that determines the state of the held View.
* @param payload Optional generic payload that might be needed during the binding.
*/
protected void bind(Item item, @Nullable Void payload) {}
protected void bind(Item item) {}
}
/**
......@@ -86,8 +84,8 @@ class PasswordAccessorySheetViewBinder {
}
@Override
protected void bind(Item item, @Nullable Void payload) {
super.bind(item, payload);
protected void bind(Item item) {
super.bind(item);
if (item.isPassword()) {
getTextView().setTransformationMethod(new PasswordTransformationMethod());
}
......
......@@ -15,7 +15,6 @@ import android.view.ViewGroup;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.modelutil.ForwardingListObservable;
import org.chromium.chrome.browser.modelutil.ListObservable;
import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter;
import org.chromium.chrome.browser.ntp.ContextMenuManager;
import org.chromium.chrome.browser.ntp.cards.ChildNode;
......@@ -46,12 +45,12 @@ class ContentCoordinator {
* TODO(bauerb): Merge {@link TreeNode} into {@link RecyclerViewAdapter.Delegate}.
*/
private static class ModelChangeProcessor extends ForwardingListObservable<PartialBindCallback>
implements RecyclerViewAdapter.Delegate<NewTabPageViewHolder, PartialBindCallback>,
ListObservable.ListObserver<PartialBindCallback> {
implements RecyclerViewAdapter.Delegate<NewTabPageViewHolder, PartialBindCallback> {
private final TreeNode mTreeNode;
private ModelChangeProcessor(ChildNode treeNode) {
mTreeNode = treeNode;
treeNode.addObserver(this);
}
@Override
......@@ -119,13 +118,9 @@ class ContentCoordinator {
final ClusterList clusterList = mModel.getClusterList();
mModelChangeProcessor = new ModelChangeProcessor(clusterList);
ContextualSuggestionsAdapter adapter =
mRecyclerView.setAdapter(
new ContextualSuggestionsAdapter(profile, new UiConfig(mRecyclerView), uiDelegate,
mContextMenuManager, mModelChangeProcessor);
mRecyclerView.setAdapter(adapter);
mModelChangeProcessor.addObserver(adapter);
clusterList.addObserver(mModelChangeProcessor);
mContextMenuManager, mModelChangeProcessor));
// TODO(twellington): Should this be a proper model property, set by the mediator and bound
// to the RecyclerView?
......
......@@ -39,14 +39,10 @@ public class ChipsCoordinator implements ChipsProvider.Observer {
// Build the underlying components.
mView = createView(context);
SimpleRecyclerViewMcp<Chip, ChipsViewHolder, Void> processor =
new SimpleRecyclerViewMcp<>(mModel, null, ChipsViewHolder::bind);
RecyclerViewAdapter<ChipsViewHolder, Void> adapter =
new RecyclerViewAdapter<>(processor, ChipsViewHolder::create);
mView.setAdapter(adapter);
processor.addObserver(adapter);
mModel.addObserver(processor);
mView.setAdapter(new RecyclerViewAdapter<>(
new SimpleRecyclerViewMcp<>(mModel, null, ChipsViewHolder::bind),
ChipsViewHolder::create));
mProvider.addObserver(this);
mModel.set(mProvider.getChips());
......
......@@ -4,7 +4,6 @@
package org.chromium.chrome.browser.download.home.filter.chips;
import android.content.res.ColorStateList;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
......@@ -12,7 +11,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.chromium.chrome.browser.modelutil.SimpleRecyclerViewMcp;
import org.chromium.chrome.browser.widget.TintedImageView;
/** The {@link ViewHolder} responsible for reflecting a {@link Chip} to a {@link View}. */
......@@ -54,11 +52,9 @@ public class ChipsViewHolder extends ViewHolder {
* Used as a method reference for ViewBinder, to push the properties of {@code chip} to
* {@link #itemView}.
* @param chip The {@link Chip} to visually reflect in the stored {@link View}.
* @param payload Unused payload; must be null.
* @see SimpleRecyclerViewMcp
* .ViewBinder#onBindViewHolder
* @see org.chromium.chrome.browser.modelutil.SimpleRecyclerViewMcp.ViewBinder#onBindViewHolder
*/
public void bind(Chip chip, @Nullable Void payload) {
public void bind(Chip chip) {
itemView.setEnabled(chip.enabled);
mText.setEnabled(chip.enabled);
mImage.setEnabled(chip.enabled);
......
......@@ -8,13 +8,13 @@ import android.support.annotation.Nullable;
import android.support.v7.util.BatchingListUpdateCallback;
import android.support.v7.util.ListUpdateCallback;
import org.chromium.chrome.browser.modelutil.ListObservable;
import org.chromium.chrome.browser.modelutil.ListObservableImpl;
/**
* Helper class to batch updates to ListObservable before notifying observers.
* @see BatchingListUpdateCallback
*/
public abstract class BatchListObservable extends ListObservable<Void> {
public abstract class BatchListObservable extends ListObservableImpl<Void> {
final BatchingListUpdateCallback mBatchingCallback;
/** Creates a new BatchListObservable instance. */
......
......@@ -39,6 +39,7 @@ class DateOrderedListView {
public ModelChangeProcessor(DecoratedListItemModel model) {
mModel = model;
model.addObserver(this);
}
@Override
......@@ -71,12 +72,6 @@ class DateOrderedListView {
mPrefetchVerticalPaddingPx = context.getResources().getDimensionPixelSize(
R.dimen.download_manager_prefetch_vertical_margin);
ModelChangeProcessor processor = new ModelChangeProcessor(mModel);
RecyclerViewAdapter<ListItemViewHolder, Void> adapter =
new DateOrderedListViewAdapter(mModel, processor, ListItemViewHolder::create);
processor.addObserver(adapter);
mModel.addObserver(processor);
mView = new RecyclerView(context);
mView.setHasFixedSize(true);
mView.getItemAnimator().setChangeDuration(0);
......@@ -89,7 +84,8 @@ class DateOrderedListView {
mModel.getProperties(), mView, propertyViewBinder));
// Do the final hook up to the underlying data adapter.
mView.setAdapter(adapter);
mView.setAdapter(new DateOrderedListViewAdapter(
mModel, new ModelChangeProcessor(mModel), ListItemViewHolder::create));
}
/** @return The Android {@link View} representing this widget. */
......
......@@ -9,6 +9,7 @@ import android.support.annotation.Nullable;
import org.chromium.chrome.browser.download.home.list.ListItem.ViewListItem;
import org.chromium.chrome.browser.modelutil.ListObservable;
import org.chromium.chrome.browser.modelutil.ListObservable.ListObserver;
import org.chromium.chrome.browser.modelutil.ListObservableImpl;
import org.chromium.chrome.browser.modelutil.SimpleList;
/**
......@@ -16,7 +17,7 @@ import org.chromium.chrome.browser.modelutil.SimpleList;
* TODO(bauerb): Replace this with InnerNode (once it has been migrated to the UI architecture)
*/
class DecoratedListItemModel
extends ListObservable<Void> implements ListObserver<Void>, SimpleList<ListItem> {
extends ListObservableImpl<Void> implements ListObserver<Void>, SimpleList<ListItem> {
private final ListItemModel mModel;
private ViewListItem mHeaderItem;
......
......@@ -13,7 +13,7 @@ import org.chromium.chrome.browser.modelutil.ListObservable.ListObserver;
* partial updates.
* TODO(bauerb): Remove this class if it turns out we can shortcut notifications
*/
public class ForwardingListObservable<P> extends ListObservable<P> implements ListObserver<P> {
public class ForwardingListObservable<P> extends ListObservableImpl<P> implements ListObserver<P> {
@Override
public void onItemRangeInserted(ListObservable source, int index, int count) {
notifyItemRangeInserted(index, count);
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.modelutil;
import android.support.annotation.Nullable;
import org.chromium.base.ObserverList;
/**
* A base class for models maintaining a list of items. Note that ListObservable models do not need
* to be implemented as a list. Internally they may use any structure to organize their items.
* Note also that this class on purpose does not expose an item type (it only exposes a
* An interface for models notifying about changes to a list of items. Note that ListObservable
* models do not need to be implemented as a list. Internally they may use any structure to organize
* their items. Note also that this class on purpose does not expose an item type (it only exposes a
* <i>payload</i> type for partial change notifications), nor does it give access to the list
* contents. This is because the list might not be homogeneous -- it could represent items of vastly
* different types that don't share a common base class. Use the {@link SimpleListObservable}
......@@ -19,13 +16,21 @@ import org.chromium.base.ObserverList;
* @param <P> The parameter type for the payload for partial updates. Use {@link Void} for
* implementations that don't support partial updates.
*/
public abstract class ListObservable<P> {
public interface ListObservable<P> {
/**
* @param observer An observer to be notified of changes to the model.
*/
void addObserver(ListObserver<P> observer);
/** @param observer The observer to remove. */
void removeObserver(ListObserver<P> observer);
/**
* An observer to be notified of changes to a {@link ListObservable}.
* @param <P> The parameter type for the payload for partial updates. Use {@link Void} for
* implementations that don't support partial updates.
*/
public interface ListObserver<P> {
interface ListObserver<P> {
/**
* Notifies that {@code count} items starting at position {@code index} under the
* {@code source} have been added.
......@@ -34,8 +39,7 @@ public abstract class ListObservable<P> {
* @param index The starting position of the range of added items.
* @param count The number of added items.
*/
default void
onItemRangeInserted(ListObservable source, int index, int count) {}
default void onItemRangeInserted(ListObservable source, int index, int count) {}
/**
* Notifies that {@code count} items starting at position {@code index} under the
......@@ -45,8 +49,7 @@ public abstract class ListObservable<P> {
* @param index The starting position of the range of removed items.
* @param count The number of removed items.
*/
default void
onItemRangeRemoved(ListObservable source, int index, int count) {}
default void onItemRangeRemoved(ListObservable source, int index, int count) {}
/**
* Notifies that {@code count} items starting at position {@code index} under the
......@@ -57,87 +60,8 @@ public abstract class ListObservable<P> {
* @param count The number of changed items.
* @param payload Optional parameter, use {@code null} to identify a "full" update.
*/
default void
onItemRangeChanged(
ListObservable<P> source, int index, int count, @Nullable P payload) {}
}
private final ObserverList<ListObserver<P>> mObservers = new ObserverList<>();
/**
* @param observer An observer to be notified of changes to the model.
*/
public void addObserver(ListObserver<P> observer) {
boolean success = mObservers.addObserver(observer);
assert success;
}
/** @param observer The observer to remove. */
public void removeObserver(ListObserver<P> observer) {
boolean success = mObservers.removeObserver(observer);
assert success;
}
protected final void notifyItemChanged(int index) {
notifyItemRangeChanged(index, 1, null);
}
protected final void notifyItemRangeChanged(int index, int count) {
notifyItemRangeChanged(index, count, null);
}
protected final void notifyItemChanged(int index, @Nullable P payload) {
notifyItemRangeChanged(index, 1, payload);
}
protected final void notifyItemInserted(int index) {
notifyItemRangeInserted(index, 1);
}
protected final void notifyItemRemoved(int index) {
notifyItemRangeRemoved(index, 1);
}
/**
* Notifies observers that {@code count} items starting at position {@code index} have been
* added.
*
* @param index The starting position of the range of added items.
* @param count The number of added items.
*/
protected void notifyItemRangeInserted(int index, int count) {
assert count > 0; // No spurious notifications
for (ListObserver observer : mObservers) {
observer.onItemRangeInserted(this, index, count);
}
}
/**
* Notifies observes that {@code count} items starting at position {@code index} have been
* removed.
*
* @param index The starting position of the range of removed items.
* @param count The number of removed items.
*/
protected void notifyItemRangeRemoved(int index, int count) {
assert count > 0; // No spurious notifications
for (ListObserver observer : mObservers) {
observer.onItemRangeRemoved(this, index, count);
}
}
/**
* Notifies observers that {@code count} items starting at position {@code index} under the
* {@code source} have changed, with an optional payload object.
*
* @param index The starting position of the range of changed items.
* @param count The number of changed items.
* @param payload Optional parameter, use {@code null} to identify a "full" update.
*/
protected void notifyItemRangeChanged(int index, int count, @Nullable P payload) {
assert count > 0; // No spurious notifications
for (ListObserver<P> observer : mObservers) {
observer.onItemRangeChanged(this, index, count, payload);
default void onItemRangeChanged(ListObservable<P> source, int index, int count,
@Nullable P payload) {
}
}
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.modelutil;
import android.support.annotation.Nullable;
import org.chromium.base.ObserverList;
/**
* Helper class for implementations of {@link ListObservable}, with some convenience methods for
* sending notifications.
* @param <P> The parameter type for the payload for partial updates. Use {@link Void} for
* implementations that don't support partial updates.
*/
public abstract class ListObservableImpl<P> implements ListObservable<P> {
private final ObserverList<ListObserver<P>> mObservers = new ObserverList<>();
@Override
public void addObserver(ListObserver<P> observer) {
boolean success = mObservers.addObserver(observer);
assert success;
}
@Override
public void removeObserver(ListObserver<P> observer) {
boolean success = mObservers.removeObserver(observer);
assert success;
}
protected final void notifyItemChanged(int index) {
notifyItemRangeChanged(index, 1, null);
}
protected final void notifyItemRangeChanged(int index, int count) {
notifyItemRangeChanged(index, count, null);
}
protected final void notifyItemChanged(int index, @Nullable P payload) {
notifyItemRangeChanged(index, 1, payload);
}
protected final void notifyItemInserted(int index) {
notifyItemRangeInserted(index, 1);
}
protected final void notifyItemRemoved(int index) {
notifyItemRangeRemoved(index, 1);
}
/**
* Notifies observers that {@code count} items starting at position {@code index} have been
* added.
*
* @param index The starting position of the range of added items.
* @param count The number of added items.
*/
protected void notifyItemRangeInserted(int index, int count) {
assert count > 0; // No spurious notifications
for (ListObserver observer : mObservers) {
observer.onItemRangeInserted(this, index, count);
}
}
/**
* Notifies observes that {@code count} items starting at position {@code index} have been
* removed.
*
* @param index The starting position of the range of removed items.
* @param count The number of removed items.
*/
protected void notifyItemRangeRemoved(int index, int count) {
assert count > 0; // No spurious notifications
for (ListObserver observer : mObservers) {
observer.onItemRangeRemoved(this, index, count);
}
}
/**
* Notifies observers that {@code count} items starting at position {@code index} under the
* {@code source} have changed, with an optional payload object.
*
* @param index The starting position of the range of changed items.
* @param count The number of changed items.
* @param payload Optional parameter, use {@code null} to identify a "full" update.
*/
protected void notifyItemRangeChanged(int index, int count, @Nullable P payload) {
assert count > 0; // No spurious notifications
for (ListObserver<P> observer : mObservers) {
observer.onItemRangeChanged(this, index, count, payload);
}
}
}
......@@ -30,7 +30,7 @@ public class RecyclerViewAdapter<VH extends ViewHolder, P>
* @param <P> The payload type for partial updates, or {@link Void} if the adapter does not
* support partial updates.
*/
public interface Delegate<VH, P> {
public interface Delegate<VH, P> extends ListObservable<P> {
/**
* @return The number of items represented by the adapter.
* @see RecyclerView.Adapter#getItemCount
......@@ -82,6 +82,7 @@ public class RecyclerViewAdapter<VH extends ViewHolder, P>
public RecyclerViewAdapter(Delegate<VH, P> delegate, ViewHolderFactory<VH> factory) {
mDelegate = delegate;
mFactory = factory;
mDelegate.addObserver(this);
}
private final Delegate<VH, P> mDelegate;
......
......@@ -13,7 +13,7 @@ import java.util.List;
* It allows models to compose different ListObservables.
* @param <T> The object type that this class manages in a list.
*/
public class SimpleListObservable<T> extends ListObservable<Void> implements SimpleList<T> {
public class SimpleListObservable<T> extends ListObservableImpl<Void> implements SimpleList<T> {
private final List<T> mItems = new ArrayList<>();
/**
......
......@@ -12,27 +12,22 @@ import android.support.v7.widget.RecyclerView;
* It is intended primarily (but not exclusively) for use in a {@link RecyclerView}.
* @param <T> The type of items in the list.
* @param <VH> The view holder type that shows items.
* @param <P> The payload type for partial updates, or {@link Void} if the object doesn't
* support partial updates.
*/
public class SimpleRecyclerViewMcp<T, VH, P>
extends ForwardingListObservable<P> implements RecyclerViewAdapter.Delegate<VH, P> {
public class SimpleRecyclerViewMcp<T, VH>
extends ForwardingListObservable<Void> implements RecyclerViewAdapter.Delegate<VH, Void> {
/**
* A view binder used to bind items in the {@link ListObservable} model to view holders.
*
* @param <T> The item type in the {@link SimpleList} model.
* @param <VH> The view holder type that shows items.
* @param <P> The payload type for partial updates, or {@link Void} if the object doesn't
* support partial updates.
*/
public interface ViewBinder<T, VH, P> {
public interface ViewBinder<T, VH> {
/**
* Called to display the specified {@code item} in the provided {@code holder}.
* @param holder The view holder which should be updated to represent the {@code item}.
* @param item The item in the list.
* @param payload The payload for partial updates.
*/
void onBindViewHolder(VH holder, T item, @Nullable P payload);
void onBindViewHolder(VH holder, T item);
}
/**
......@@ -50,7 +45,7 @@ public class SimpleRecyclerViewMcp<T, VH, P>
private final SimpleList<T> mModel;
private final ItemViewTypeCallback<T> mItemViewTypeCallback;
private final ViewBinder<T, VH, P> mViewBinder;
private final ViewBinder<T, VH> mViewBinder;
/**
* @param model The {@link SimpleList} model used to retrieve items to display.
......@@ -58,12 +53,12 @@ public class SimpleRecyclerViewMcp<T, VH, P>
* the default view type.
* @param viewBinder The {@link ViewBinder} binding this adapter to the view holder.
*/
public SimpleRecyclerViewMcp(SimpleList<T> model,
@Nullable ItemViewTypeCallback<T> itemViewTypeCallback,
ViewBinder<T, VH, P> viewBinder) {
public SimpleRecyclerViewMcp(SimpleListObservable<T> model,
@Nullable ItemViewTypeCallback<T> itemViewTypeCallback, ViewBinder<T, VH> viewBinder) {
mModel = model;
mItemViewTypeCallback = itemViewTypeCallback;
mViewBinder = viewBinder;
model.addObserver(this);
}
@Override
......@@ -79,7 +74,8 @@ public class SimpleRecyclerViewMcp<T, VH, P>
}
@Override
public void onBindViewHolder(VH holder, int position, @Nullable P payload) {
mViewBinder.onBindViewHolder(holder, mModel.get(position), payload);
public void onBindViewHolder(VH holder, int position, @Nullable Void payload) {
assert payload == null;
mViewBinder.onBindViewHolder(holder, mModel.get(position));
}
}
......@@ -6,7 +6,7 @@ package org.chromium.chrome.browser.ntp.cards;
import android.support.annotation.Nullable;
import org.chromium.chrome.browser.modelutil.ListObservable;
import org.chromium.chrome.browser.modelutil.ListObservableImpl;
import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder.PartialBindCallback;
/**
......@@ -14,7 +14,8 @@ import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder.PartialBindCal
*
* This class mostly serves as a convenience base class for implementations of {@link TreeNode}.
*/
public abstract class ChildNode extends ListObservable<PartialBindCallback> implements TreeNode {
public abstract class ChildNode
extends ListObservableImpl<PartialBindCallback> implements TreeNode {
private int mNumItems = 0;
@Override
......
......@@ -767,6 +767,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/modelutil/LazyViewBinderAdapter.java",
"java/src/org/chromium/chrome/browser/modelutil/ListModelChangeProcessor.java",
"java/src/org/chromium/chrome/browser/modelutil/ListObservable.java",
"java/src/org/chromium/chrome/browser/modelutil/ListObservableImpl.java",
"java/src/org/chromium/chrome/browser/modelutil/PropertyKey.java",
"java/src/org/chromium/chrome/browser/modelutil/PropertyModel.java",
"java/src/org/chromium/chrome/browser/modelutil/PropertyModelChangeProcessor.java",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment