/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package androidx.leanback.widget;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.RecyclerView;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A Presenter is used to generate {@link View}s and bind Objects to them on
* demand. It is closely related to the concept of an {@link
* RecyclerView.Adapter RecyclerView.Adapter}, but is
* not position-based. The leanback framework implements the adapter concept using
* {@link ObjectAdapter} which refers to a Presenter (or {@link PresenterSelector}) instance.
*
*
* Presenters should be stateless. Presenters typically extend {@link ViewHolder} to store all
* necessary view state information, such as references to child views to be used when
* binding to avoid expensive calls to {@link View#findViewById(int)}.
*
*
*
* A trivial Presenter that takes a string and renders it into a {@link
* android.widget.TextView TextView}:
*
*
* public class StringTextViewPresenter extends Presenter {
* // This class does not need a custom ViewHolder, since it does not use
* // a complex layout.
*
* {@literal @}Override
* public ViewHolder onCreateViewHolder(ViewGroup parent) {
* return new ViewHolder(new TextView(parent.getContext()));
* }
*
* {@literal @}Override
* public void onBindViewHolder(ViewHolder viewHolder, Object item) {
* String str = (String) item;
* TextView textView = (TextView) viewHolder.mView;
*
* textView.setText(item);
* }
*
* {@literal @}Override
* public void onUnbindViewHolder(ViewHolder viewHolder) {
* // Nothing to unbind for TextView, but if this viewHolder had
* // allocated bitmaps, they can be released here.
* }
* }
*
* In addition to view creation and binding, Presenter allows dynamic interface (facet) to
* be added: {@link #setFacet(Class, Object)}. Supported facets:
*
{@link ItemAlignmentFacet} is used by {@link HorizontalGridView} and
* {@link VerticalGridView} to customize child alignment.
*/
public abstract class Presenter implements FacetProvider {
/**
* ViewHolder can be subclassed and used to cache any view accessors needed
* to improve binding performance (for example, results of findViewById)
* without needing to subclass a View.
*/
public static class ViewHolder implements FacetProvider {
public final View view;
private Map mFacets;
public ViewHolder(View view) {
this.view = view;
}
@Override
public final Object getFacet(Class> facetClass) {
if (mFacets == null) {
return null;
}
return mFacets.get(facetClass);
}
/**
* Sets dynamic implemented facet in addition to basic ViewHolder functions.
* @param facetClass Facet classes to query, can be class of {@link ItemAlignmentFacet}.
* @param facetImpl Facet implementation.
*/
public final void setFacet(Class> facetClass, Object facetImpl) {
if (mFacets == null) {
mFacets = new HashMap();
}
mFacets.put(facetClass, facetImpl);
}
}
/**
* Base class to perform a task on Presenter.ViewHolder.
*/
public static abstract class ViewHolderTask {
/**
* Called to perform a task on view holder.
* @param holder The view holder to perform task.
*/
public void run(Presenter.ViewHolder holder) {
}
}
private Map mFacets;
/**
* Creates a new {@link View}.
*/
public abstract ViewHolder onCreateViewHolder(ViewGroup parent);
/**
* Binds a {@link View} to an item.
*/
public abstract void onBindViewHolder(ViewHolder viewHolder, Object item);
/**
* Binds a {@link View} to an item with a list of payloads.
* @param viewHolder The ViewHolder which should be updated to represent the contents of the
* item at the given position in the data set.
* @param item The item which should be bound to view holder.
* @param payloads A non-null list of merged payloads. Can be empty list if requires full
* update.
*/
public void onBindViewHolder(ViewHolder viewHolder, Object item, List