public abstract class

Presenter

extends java.lang.Object

implements FacetProvider

 java.lang.Object

↳androidx.leanback.widget.Presenter

Subclasses:

PlaybackTransportRowPresenter, FullWidthDetailsOverviewRowPresenter, AbstractDetailsDescriptionPresenter, AbstractMediaListHeaderPresenter, PlaybackControlsRowPresenter, PlaybackRowPresenter, ListRowPresenter, RowPresenter, DetailsOverviewLogoPresenter, AbstractMediaItemPresenter, DetailsOverviewRowPresenter, VerticalGridPresenter, RowHeaderPresenter, InvisibleRowPresenter, DividerPresenter

Gradle dependencies

compile group: 'androidx.leanback', name: 'leanback', version: '1.2.0-alpha04'

  • groupId: androidx.leanback
  • artifactId: leanback
  • version: 1.2.0-alpha04

Artifact androidx.leanback:leanback:1.2.0-alpha04 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.leanback:leanback com.android.support:leanback-v17

Androidx class mapping:

androidx.leanback.widget.Presenter android.support.v17.leanback.widget.Presenter

Overview

A Presenter is used to generate Views and bind Objects to them on demand. It is closely related to the concept of an RecyclerView.Adapter, but is not position-based. The leanback framework implements the adapter concept using ObjectAdapter which refers to a Presenter (or PresenterSelector) instance.

Presenters should be stateless. Presenters typically extend Presenter.ViewHolder to store all necessary view state information, such as references to child views to be used when binding to avoid expensive calls to View.

A trivial Presenter that takes a string and renders it into a TextView:

 public class StringTextViewPresenter extends Presenter {
     // This class does not need a custom ViewHolder, since it does not use
     // a complex layout.

     @Override
     public ViewHolder onCreateViewHolder(ViewGroup parent) {
         return new ViewHolder(new TextView(parent.getContext()));
     }

     @Override
     public void onBindViewHolder(ViewHolder viewHolder, Object item) {
         String str = (String) item;
         TextView textView = (TextView) viewHolder.mView;

         textView.setText(item);
     }

     @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: Presenter.setFacet(Class, Object). Supported facets: ItemAlignmentFacet is used by HorizontalGridView and VerticalGridView to customize child alignment.

Summary

Constructors
publicPresenter()

Methods
protected static voidcancelAnimationsRecursive(View view)

Utility method for removing all running animations on a view.

public final java.lang.ObjectgetFacet(java.lang.Class<java.lang.Object> facetClass)

public abstract voidonBindViewHolder(Presenter.ViewHolder viewHolder, java.lang.Object item)

Binds a View to an item.

public voidonBindViewHolder(Presenter.ViewHolder viewHolder, java.lang.Object item, java.util.List<java.lang.Object> payloads)

Binds a View to an item with a list of payloads.

public abstract Presenter.ViewHolderonCreateViewHolder(ViewGroup parent)

Creates a new View.

public abstract voidonUnbindViewHolder(Presenter.ViewHolder viewHolder)

Unbinds a View from an item.

public voidonViewAttachedToWindow(Presenter.ViewHolder holder)

Called when a view created by this presenter has been attached to a window.

public voidonViewDetachedFromWindow(Presenter.ViewHolder holder)

Called when a view created by this presenter has been detached from its window.

public final voidsetFacet(java.lang.Class<java.lang.Object> facetClass, java.lang.Object facetImpl)

Sets dynamic implemented facet in addition to basic Presenter functions.

public voidsetOnClickListener(Presenter.ViewHolder holder, View.OnClickListener listener)

Called to set a click listener for the given view holder.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public Presenter()

Methods

public abstract Presenter.ViewHolder onCreateViewHolder(ViewGroup parent)

Creates a new View.

public abstract void onBindViewHolder(Presenter.ViewHolder viewHolder, java.lang.Object item)

Binds a View to an item.

public void onBindViewHolder(Presenter.ViewHolder viewHolder, java.lang.Object item, java.util.List<java.lang.Object> payloads)

Binds a View to an item with a list of payloads.

Parameters:

viewHolder: The ViewHolder which should be updated to represent the contents of the item at the given position in the data set.
item: The item which should be bound to view holder.
payloads: A non-null list of merged payloads. Can be empty list if requires full update.

public abstract void onUnbindViewHolder(Presenter.ViewHolder viewHolder)

Unbinds a View from an item. Any expensive references may be released here, and any fields that are not bound for every item should be cleared here.

public void onViewAttachedToWindow(Presenter.ViewHolder holder)

Called when a view created by this presenter has been attached to a window.

This can be used as a reasonable signal that the view is about to be seen by the user. If the adapter previously freed any resources in Presenter.onViewDetachedFromWindow(Presenter.ViewHolder) those resources should be restored here.

Parameters:

holder: Holder of the view being attached

public void onViewDetachedFromWindow(Presenter.ViewHolder holder)

Called when a view created by this presenter has been detached from its window.

Becoming detached from the window is not necessarily a permanent condition; the consumer of an presenter's views may choose to cache views offscreen while they are not visible, attaching and detaching them as appropriate.

Any view property animations should be cancelled here or the view may fail to be recycled.

Parameters:

holder: Holder of the view being detached

protected static void cancelAnimationsRecursive(View view)

Utility method for removing all running animations on a view.

public void setOnClickListener(Presenter.ViewHolder holder, View.OnClickListener listener)

Called to set a click listener for the given view holder. The default implementation sets the click listener on the root view in the view holder. If the root view isn't focusable this method should be overridden to set the listener on the appropriate focusable child view(s).

Parameters:

holder: The view holder containing the view(s) on which the listener should be set.
listener: The click listener to be set.

public final java.lang.Object getFacet(java.lang.Class<java.lang.Object> facetClass)

public final void setFacet(java.lang.Class<java.lang.Object> facetClass, java.lang.Object facetImpl)

Sets dynamic implemented facet in addition to basic Presenter functions.

Parameters:

facetClass: Facet classes to query, can be class of ItemAlignmentFacet.
facetImpl: Facet implementation.

Source

/*
 * 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.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.collection.ArrayMap;

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
 * androidx.recyclerview.widget.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.
 *
 * <p>
 * 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)}.
 * </p>
 *
 * <p>
 * A trivial Presenter that takes a string and renders it into a {@link
 * android.widget.TextView TextView}:
 *
 * <pre class="prettyprint">
 * 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.
 *     }
 * }
 * </pre>
 * 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<Class<?>, Object> 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 ArrayMap<>();
            }
            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<Class<?>, Object> mFacets;

    /**
     * Creates a new {@link View}.
     */
    @NonNull
    public abstract ViewHolder onCreateViewHolder(@NonNull ViewGroup parent);

    /**
     * Binds a {@link View} to an item.
     */
    public abstract void onBindViewHolder(@NonNull ViewHolder viewHolder, @Nullable 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(
            @NonNull ViewHolder viewHolder,
            @NonNull Object item,
            @NonNull List<Object> payloads
    ) {
        onBindViewHolder(viewHolder, item);
    }

    /**
     * Unbinds a {@link View} from an item. Any expensive references may be
     * released here, and any fields that are not bound for every item should be
     * cleared here.
     */
    public abstract void onUnbindViewHolder(@NonNull ViewHolder viewHolder);

    /**
     * Called when a view created by this presenter has been attached to a window.
     *
     * <p>This can be used as a reasonable signal that the view is about to be seen
     * by the user. If the adapter previously freed any resources in
     * {@link #onViewDetachedFromWindow(ViewHolder)}
     * those resources should be restored here.</p>
     *
     * @param holder Holder of the view being attached
     */
    public void onViewAttachedToWindow(@NonNull ViewHolder holder) {
    }

    /**
     * Called when a view created by this presenter has been detached from its window.
     *
     * <p>Becoming detached from the window is not necessarily a permanent condition;
     * the consumer of an presenter's views may choose to cache views offscreen while they
     * are not visible, attaching and detaching them as appropriate.</p>
     *
     * Any view property animations should be cancelled here or the view may fail
     * to be recycled.
     *
     * @param holder Holder of the view being detached
     */
    public void onViewDetachedFromWindow(@NonNull ViewHolder holder) {
        // If there are view property animations running then RecyclerView won't recycle.
        cancelAnimationsRecursive(holder.view);
    }

    /**
     * Utility method for removing all running animations on a view.
     */
    protected static void cancelAnimationsRecursive(View view) {
        if (view != null && view.hasTransientState()) {
            view.animate().cancel();
            if (view instanceof ViewGroup) {
                final int count = ((ViewGroup) view).getChildCount();
                for (int i = 0; view.hasTransientState() && i < count; i++) {
                    cancelAnimationsRecursive(((ViewGroup) view).getChildAt(i));
                }
            }
        }
    }

    /**
     * Called to set a click listener for the given view holder.
     *
     * The default implementation sets the click listener on the root view in the view holder.
     * If the root view isn't focusable this method should be overridden to set the listener
     * on the appropriate focusable child view(s).
     *
     * @param holder The view holder containing the view(s) on which the listener should be set.
     * @param listener The click listener to be set.
     */
    public void setOnClickListener(ViewHolder holder, View.OnClickListener listener) {
        holder.view.setOnClickListener(listener);
    }

    @Override
    public final Object getFacet(Class<?> facetClass) {
        if (mFacets == null) {
            return null;
        }
        return mFacets.get(facetClass);
    }

    /**
     * Sets dynamic implemented facet in addition to basic Presenter 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 ArrayMap<>();
        }
        mFacets.put(facetClass, facetImpl);
    }
}