Gradle dependencies
compile group: 'androidx.leanback', name: 'leanback', version: '1.2.0-alpha02'
- groupId: androidx.leanback
- artifactId: leanback
- version: 1.2.0-alpha02
Artifact androidx.leanback:leanback:1.2.0-alpha02 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.app.RowsSupportFragment android.support.v17.leanback.app.RowsSupportFragment
Overview
An ordered set of rows of leanback widgets.
A RowsSupportFragment renders the elements of its
ObjectAdapter as a set
of rows in a vertical list. The Adapter's PresenterSelector must maintain subclasses
of RowPresenter.
Summary
Methods |
---|
public void | enableRowScaling(boolean enable)
|
protected VerticalGridView | findGridViewFromRoot(View view)
|
public RowPresenter.ViewHolder | findRowViewHolderByPosition(int position)
Find row ViewHolder by position in adapter. |
public BrowseSupportFragment.MainFragmentAdapter | getMainFragmentAdapter()
|
public BrowseSupportFragment.MainFragmentRowsAdapter | getMainFragmentRowsAdapter()
|
public BaseOnItemViewClickedListener | getOnItemViewClickedListener()
Returns the item clicked listener. |
public BaseOnItemViewSelectedListener | getOnItemViewSelectedListener()
Returns an item selection listener. |
public RowPresenter.ViewHolder | getRowViewHolder(int position)
Get row ViewHolder at adapter position. |
public boolean | isScrolling()
|
public void | onDestroyView()
Called when the view previously created by Fragment.onCreateView(LayoutInflater, ViewGroup, Bundle) has
been detached from the fragment. |
public void | onTransitionEnd()
|
public boolean | onTransitionPrepare()
|
public void | onViewCreated(View view, Bundle savedInstanceState)
Called immediately after Fragment.onCreateView(LayoutInflater, ViewGroup, Bundle)
has returned, but before any saved state has been restored in to the view. |
public void | setAlignment(int windowAlignOffsetFromTop)
|
public void | setEntranceTransitionState(boolean afterTransition)
For rows that willing to participate entrance transition, this function
hide views if afterTransition is true, show views if afterTransition is false. |
public void | setExpand(boolean expand)
Set the visibility of titles/hovercard of browse rows. |
public void | setOnItemViewClickedListener(BaseOnItemViewClickedListener listener)
Sets an item clicked listener on the fragment. |
public void | setOnItemViewSelectedListener(BaseOnItemViewSelectedListener listener)
Sets an item selection listener. |
public void | setSelectedPosition(int rowPosition, boolean smooth, Presenter.ViewHolderTask rowHolderTask)
Selects a Row and perform an optional task on the Row. |
from androidx.leanback.app.BaseRowSupportFragment | getAdapter, getBridgeAdapter, getPresenterSelector, getSelectedPosition, getVerticalGridView, onCreateView, onSaveInstanceState, onTransitionStart, setAdapter, setPresenterSelector, setSelectedPosition, setSelectedPosition |
from Fragment | dump, equals, getActivity, getAllowEnterTransitionOverlap, getAllowReturnTransitionOverlap, getArguments, getChildFragmentManager, getContext, getDefaultViewModelCreationExtras, getDefaultViewModelProviderFactory, getEnterTransition, getExitTransition, getFragmentManager, getHost, getId, getLayoutInflater, getLayoutInflater, getLifecycle, getLoaderManager, getParentFragment, getParentFragmentManager, getReenterTransition, getResources, getRetainInstance, getReturnTransition, getSavedStateRegistry, getSharedElementEnterTransition, getSharedElementReturnTransition, getString, getString, getTag, getTargetFragment, getTargetRequestCode, getText, getUserVisibleHint, getView, getViewLifecycleOwner, getViewLifecycleOwnerLiveData, getViewModelStore, hashCode, hasOptionsMenu, instantiate, instantiate, isAdded, isDetached, isHidden, isInLayout, isMenuVisible, isRemoving, isResumed, isStateSaved, isVisible, onActivityCreated, onActivityResult, onAttach, onAttach, onAttachFragment, onConfigurationChanged, onContextItemSelected, onCreate, onCreateAnimation, onCreateAnimator, onCreateContextMenu, onCreateOptionsMenu, onDestroy, onDestroyOptionsMenu, onDetach, onGetLayoutInflater, onHiddenChanged, onInflate, onInflate, onLowMemory, onMultiWindowModeChanged, onOptionsItemSelected, onOptionsMenuClosed, onPause, onPictureInPictureModeChanged, onPrepareOptionsMenu, onPrimaryNavigationFragmentChanged, onRequestPermissionsResult, onResume, onStart, onStop, onViewStateRestored, postponeEnterTransition, postponeEnterTransition, registerForActivityResult, registerForActivityResult, registerForContextMenu, requestPermissions, requireActivity, requireArguments, requireContext, requireFragmentManager, requireHost, requireParentFragment, requireView, setAllowEnterTransitionOverlap, setAllowReturnTransitionOverlap, setArguments, setEnterSharedElementCallback, setEnterTransition, setExitSharedElementCallback, setExitTransition, setHasOptionsMenu, setInitialSavedState, setMenuVisibility, setReenterTransition, setRetainInstance, setReturnTransition, setSharedElementEnterTransition, setSharedElementReturnTransition, setTargetFragment, setUserVisibleHint, shouldShowRequestPermissionRationale, startActivity, startActivity, startActivityForResult, startActivityForResult, startIntentSenderForResult, startPostponedEnterTransition, toString, unregisterForContextMenu |
from java.lang.Object | clone, finalize, getClass, notify, notifyAll, wait, wait, wait |
Constructors
public
RowsSupportFragment()
Methods
Sets an item clicked listener on the fragment.
OnItemViewClickedListener will override that
item presenter sets during Presenter.onCreateViewHolder(ViewGroup).
So in general, developer should choose one of the listeners but not both.
Returns the item clicked listener.
public void
enableRowScaling(boolean enable)
Deprecated: use BrowseSupportFragment.enableRowScaling(boolean) instead.
Parameters:
enable: true to enable row scaling
public void
setExpand(boolean expand)
Set the visibility of titles/hovercard of browse rows.
Sets an item selection listener.
Returns an item selection listener.
Get row ViewHolder at adapter position. Returns null if the row object is not in adapter or
the row object has not been bound to a row view.
Parameters:
position: Position of row in adapter.
Returns:
Row ViewHolder at a given adapter position.
public void
onViewCreated(View view, Bundle savedInstanceState)
Called immediately after Fragment.onCreateView(LayoutInflater, ViewGroup, Bundle)
has returned, but before any saved state has been restored in to the view.
This gives subclasses a chance to initialize themselves once
they know their view hierarchy has been completely created. The fragment's
view hierarchy is not however attached to its parent at this point.
Parameters:
view: The View returned by Fragment.onCreateView(LayoutInflater, ViewGroup, Bundle).
savedInstanceState: If non-null, this fragment is being re-constructed
from a previous saved state as given here.
public void
onDestroyView()
Called when the view previously created by Fragment.onCreateView(LayoutInflater, ViewGroup, Bundle) has
been detached from the fragment. The next time the fragment needs
to be displayed, a new view will be created. This is called
after Fragment.onStop() and before Fragment.onDestroy(). It is called
regardless of whether Fragment.onCreateView(LayoutInflater, ViewGroup, Bundle) returned a
non-null view. Internally it is called after the view's state has
been saved but before it has been removed from its parent.
public boolean
onTransitionPrepare()
public void
onTransitionEnd()
public void
setEntranceTransitionState(boolean afterTransition)
For rows that willing to participate entrance transition, this function
hide views if afterTransition is true, show views if afterTransition is false.
Selects a Row and perform an optional task on the Row. For example
setSelectedPosition(10, true, new ListRowPresenterSelectItemViewHolderTask(5))
Scroll to 11th row and selects 6th item on that row. The method will be ignored if
RowsSupportFragment has not been created (i.e. before onCreateView
).
Parameters:
rowPosition: Which row to select.
smooth: True to scroll to the row, false for no animation.
rowHolderTask: Task to perform on the Row.
public boolean
isScrolling()
public void
setAlignment(int windowAlignOffsetFromTop)
Find row ViewHolder by position in adapter.
Parameters:
position: Position of row.
Returns:
ViewHolder of Row.
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.app;
import android.animation.TimeAnimator;
import android.animation.TimeAnimator.TimeListener;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.leanback.R;
import androidx.leanback.widget.BaseOnItemViewClickedListener;
import androidx.leanback.widget.BaseOnItemViewSelectedListener;
import androidx.leanback.widget.HorizontalGridView;
import androidx.leanback.widget.ItemBridgeAdapter;
import androidx.leanback.widget.ListRowPresenter;
import androidx.leanback.widget.ObjectAdapter;
import androidx.leanback.widget.OnItemViewClickedListener;
import androidx.leanback.widget.OnItemViewSelectedListener;
import androidx.leanback.widget.Presenter;
import androidx.leanback.widget.PresenterSelector;
import androidx.leanback.widget.RowPresenter;
import androidx.leanback.widget.VerticalGridView;
import androidx.leanback.widget.ViewHolderTask;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
/**
* An ordered set of rows of leanback widgets.
* <p>
* A RowsSupportFragment renders the elements of its
* {@link androidx.leanback.widget.ObjectAdapter} as a set
* of rows in a vertical list. The Adapter's {@link PresenterSelector} must maintain subclasses
* of {@link RowPresenter}.
* </p>
*/
public class RowsSupportFragment extends BaseRowSupportFragment implements
BrowseSupportFragment.MainFragmentRowsAdapterProvider,
BrowseSupportFragment.MainFragmentAdapterProvider {
private MainFragmentAdapter mMainFragmentAdapter;
private MainFragmentRowsAdapter mMainFragmentRowsAdapter;
@Override
public BrowseSupportFragment.MainFragmentAdapter getMainFragmentAdapter() {
if (mMainFragmentAdapter == null) {
mMainFragmentAdapter = new MainFragmentAdapter(this);
}
return mMainFragmentAdapter;
}
@Override
public BrowseSupportFragment.MainFragmentRowsAdapter getMainFragmentRowsAdapter() {
if (mMainFragmentRowsAdapter == null) {
mMainFragmentRowsAdapter = new MainFragmentRowsAdapter(this);
}
return mMainFragmentRowsAdapter;
}
/**
* Internal helper class that manages row select animation and apply a default
* dim to each row.
*/
static final class RowViewHolderExtra implements TimeListener {
static final Interpolator sSelectAnimatorInterpolator = new DecelerateInterpolator(2);
final RowPresenter mRowPresenter;
final Presenter.ViewHolder mRowViewHolder;
final TimeAnimator mSelectAnimator = new TimeAnimator();
final int mSelectAnimatorDurationInUse;
final Interpolator mSelectAnimatorInterpolatorInUse;
float mSelectLevelAnimStart;
float mSelectLevelAnimDelta;
RowViewHolderExtra(ItemBridgeAdapter.ViewHolder ibvh) {
mRowPresenter = (RowPresenter) ibvh.getPresenter();
mRowViewHolder = ibvh.getViewHolder();
mSelectAnimator.setTimeListener(this);
// Select animation and interpolator are not intended to be
// exposed at this moment. They might be synced with vertical scroll
// animation later.
mSelectAnimatorDurationInUse = ibvh.itemView.getResources().getInteger(
R.integer.lb_browse_rows_anim_duration);
mSelectAnimatorInterpolatorInUse = sSelectAnimatorInterpolator;
}
@Override
public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
if (mSelectAnimator.isRunning()) {
updateSelect(totalTime, deltaTime);
}
}
void updateSelect(long totalTime, long deltaTime) {
float fraction;
if (totalTime >= mSelectAnimatorDurationInUse) {
fraction = 1;
mSelectAnimator.end();
} else {
fraction = (float) (totalTime / (double) mSelectAnimatorDurationInUse);
}
if (mSelectAnimatorInterpolatorInUse != null) {
fraction = mSelectAnimatorInterpolatorInUse.getInterpolation(fraction);
}
float level = mSelectLevelAnimStart + fraction * mSelectLevelAnimDelta;
mRowPresenter.setSelectLevel(mRowViewHolder, level);
}
void animateSelect(boolean select, boolean immediate) {
mSelectAnimator.end();
final float end = select ? 1 : 0;
if (immediate) {
mRowPresenter.setSelectLevel(mRowViewHolder, end);
} else if (mRowPresenter.getSelectLevel(mRowViewHolder) != end) {
mSelectLevelAnimStart = mRowPresenter.getSelectLevel(mRowViewHolder);
mSelectLevelAnimDelta = end - mSelectLevelAnimStart;
mSelectAnimator.start();
}
}
}
static final String TAG = "RowsSupportFragment";
static final boolean DEBUG = false;
static final int ALIGN_TOP_NOT_SET = Integer.MIN_VALUE;
ItemBridgeAdapter.ViewHolder mSelectedViewHolder;
private int mSubPosition;
boolean mExpand = true;
boolean mViewsCreated;
private int mAlignedTop = ALIGN_TOP_NOT_SET;
boolean mAfterEntranceTransition = true;
boolean mFreezeRows;
BaseOnItemViewSelectedListener mOnItemViewSelectedListener;
BaseOnItemViewClickedListener mOnItemViewClickedListener;
private RecyclerView.RecycledViewPool mRecycledViewPool;
private ArrayList<Presenter> mPresenterMapper;
ItemBridgeAdapter.AdapterListener mExternalAdapterListener;
@Override
protected VerticalGridView findGridViewFromRoot(View view) {
return (VerticalGridView) view.findViewById(R.id.container_list);
}
/**
* Sets an item clicked listener on the fragment.
* OnItemViewClickedListener will override {@link View.OnClickListener} that
* item presenter sets during {@link Presenter#onCreateViewHolder(ViewGroup)}.
* So in general, developer should choose one of the listeners but not both.
*/
public void setOnItemViewClickedListener(BaseOnItemViewClickedListener listener) {
mOnItemViewClickedListener = listener;
if (mViewsCreated) {
throw new IllegalStateException(
"Item clicked listener must be set before views are created");
}
}
/**
* Returns the item clicked listener.
*/
public BaseOnItemViewClickedListener getOnItemViewClickedListener() {
return mOnItemViewClickedListener;
}
/**
* @deprecated use {@link BrowseSupportFragment#enableRowScaling(boolean)} instead.
*
* @param enable true to enable row scaling
*/
@Deprecated
public void enableRowScaling(boolean enable) {
}
/**
* Set the visibility of titles/hovercard of browse rows.
*/
public void setExpand(boolean expand) {
mExpand = expand;
VerticalGridView listView = getVerticalGridView();
if (listView != null) {
final int count = listView.getChildCount();
if (DEBUG) Log.v(TAG, "setExpand " + expand + " count " + count);
for (int i = 0; i < count; i++) {
View view = listView.getChildAt(i);
ItemBridgeAdapter.ViewHolder vh =
(ItemBridgeAdapter.ViewHolder) listView.getChildViewHolder(view);
setRowViewExpanded(vh, mExpand);
}
}
}
/**
* Sets an item selection listener.
*/
public void setOnItemViewSelectedListener(BaseOnItemViewSelectedListener listener) {
mOnItemViewSelectedListener = listener;
VerticalGridView listView = getVerticalGridView();
if (listView != null) {
final int count = listView.getChildCount();
for (int i = 0; i < count; i++) {
View view = listView.getChildAt(i);
ItemBridgeAdapter.ViewHolder ibvh = (ItemBridgeAdapter.ViewHolder)
listView.getChildViewHolder(view);
getRowViewHolder(ibvh).setOnItemViewSelectedListener(mOnItemViewSelectedListener);
}
}
}
/**
* Returns an item selection listener.
*/
public BaseOnItemViewSelectedListener getOnItemViewSelectedListener() {
return mOnItemViewSelectedListener;
}
@Override
void onRowSelected(RecyclerView parent, RecyclerView.ViewHolder viewHolder,
int position, int subposition) {
if (mSelectedViewHolder != viewHolder || mSubPosition != subposition) {
if (DEBUG) Log.v(TAG, "new row selected position " + position + " subposition "
+ subposition + " view " + viewHolder.itemView);
mSubPosition = subposition;
if (mSelectedViewHolder != null) {
setRowViewSelected(mSelectedViewHolder, false, false);
}
mSelectedViewHolder = (ItemBridgeAdapter.ViewHolder) viewHolder;
if (mSelectedViewHolder != null) {
setRowViewSelected(mSelectedViewHolder, true, false);
}
}
// When RowsSupportFragment is embedded inside a page fragment, we want to show
// the title view only when we're on the first row or there is no data.
if (mMainFragmentAdapter != null) {
mMainFragmentAdapter.getFragmentHost().showTitleView(position <= 0);
}
}
/**
* Get row ViewHolder at adapter position. Returns null if the row object is not in adapter or
* the row object has not been bound to a row view.
*
* @param position Position of row in adapter.
* @return Row ViewHolder at a given adapter position.
*/
public RowPresenter.ViewHolder getRowViewHolder(int position) {
VerticalGridView verticalView = getVerticalGridView();
if (verticalView == null) {
return null;
}
return getRowViewHolder((ItemBridgeAdapter.ViewHolder)
verticalView.findViewHolderForAdapterPosition(position));
}
@Override
int getLayoutResourceId() {
return R.layout.lb_rows_fragment;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
if (DEBUG) Log.v(TAG, "onViewCreated");
super.onViewCreated(view, savedInstanceState);
// Align the top edge of child with id row_content.
// Need set this for directly using RowsSupportFragment.
getVerticalGridView().setItemAlignmentViewId(R.id.row_content);
getVerticalGridView().setSaveChildrenPolicy(VerticalGridView.SAVE_LIMITED_CHILD);
setAlignment(mAlignedTop);
mRecycledViewPool = null;
mPresenterMapper = null;
if (mMainFragmentAdapter != null) {
mMainFragmentAdapter.getFragmentHost().notifyViewCreated(mMainFragmentAdapter);
}
}
@Override
public void onDestroyView() {
mViewsCreated = false;
mSelectedViewHolder = null;
mRecycledViewPool = null;
super.onDestroyView();
}
void setExternalAdapterListener(ItemBridgeAdapter.AdapterListener listener) {
mExternalAdapterListener = listener;
}
static void setRowViewExpanded(ItemBridgeAdapter.ViewHolder vh, boolean expanded) {
((RowPresenter) vh.getPresenter()).setRowViewExpanded(vh.getViewHolder(), expanded);
}
static void setRowViewSelected(ItemBridgeAdapter.ViewHolder vh, boolean selected,
boolean immediate) {
RowViewHolderExtra extra = (RowViewHolderExtra) vh.getExtraObject();
extra.animateSelect(selected, immediate);
((RowPresenter) vh.getPresenter()).setRowViewSelected(vh.getViewHolder(), selected);
}
private final ItemBridgeAdapter.AdapterListener mBridgeAdapterListener =
new ItemBridgeAdapter.AdapterListener() {
@Override
public void onAddPresenter(Presenter presenter, int type) {
if (mExternalAdapterListener != null) {
mExternalAdapterListener.onAddPresenter(presenter, type);
}
}
@Override
public void onCreate(ItemBridgeAdapter.ViewHolder vh) {
VerticalGridView listView = getVerticalGridView();
if (listView != null) {
// set clip children false for slide animation
listView.setClipChildren(false);
}
setupSharedViewPool(vh);
mViewsCreated = true;
vh.setExtraObject(new RowViewHolderExtra(vh));
// selected state is initialized to false, then driven by grid view onChildSelected
// events. When there is rebind, grid view fires onChildSelected event properly.
// So we don't need do anything special later in onBind or onAttachedToWindow.
setRowViewSelected(vh, false, true);
if (mExternalAdapterListener != null) {
mExternalAdapterListener.onCreate(vh);
}
}
@Override
public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder vh) {
if (DEBUG) Log.v(TAG, "onAttachToWindow");
// All views share the same mExpand value. When we attach a view to grid view,
// we should make sure it pick up the latest mExpand value we set early on other
// attached views. For no-structure-change update, the view is rebound to new data,
// but again it should use the unchanged mExpand value, so we don't need do any
// thing in onBind.
setRowViewExpanded(vh, mExpand);
RowPresenter rowPresenter = (RowPresenter) vh.getPresenter();
RowPresenter.ViewHolder rowVh = rowPresenter.getRowViewHolder(vh.getViewHolder());
rowPresenter.setEntranceTransitionState(rowVh, mAfterEntranceTransition);
rowVh.setOnItemViewSelectedListener(mOnItemViewSelectedListener);
rowVh.setOnItemViewClickedListener(mOnItemViewClickedListener);
// freeze the rows attached after RowsSupportFragment#freezeRows() is called
rowPresenter.freeze(rowVh, mFreezeRows);
if (mExternalAdapterListener != null) {
mExternalAdapterListener.onAttachedToWindow(vh);
}
}
@Override
public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder vh) {
if (mSelectedViewHolder == vh) {
setRowViewSelected(mSelectedViewHolder, false, true);
mSelectedViewHolder = null;
}
RowPresenter rowPresenter = (RowPresenter) vh.getPresenter();
RowPresenter.ViewHolder rowVh = rowPresenter.getRowViewHolder(vh.getViewHolder());
rowVh.setOnItemViewSelectedListener(null);
rowVh.setOnItemViewClickedListener(null);
if (mExternalAdapterListener != null) {
mExternalAdapterListener.onDetachedFromWindow(vh);
}
}
@Override
public void onBind(ItemBridgeAdapter.ViewHolder vh) {
if (mExternalAdapterListener != null) {
mExternalAdapterListener.onBind(vh);
}
}
@Override
public void onUnbind(ItemBridgeAdapter.ViewHolder vh) {
setRowViewSelected(vh, false, true);
if (mExternalAdapterListener != null) {
mExternalAdapterListener.onUnbind(vh);
}
}
};
void setupSharedViewPool(ItemBridgeAdapter.ViewHolder bridgeVh) {
RowPresenter rowPresenter = (RowPresenter) bridgeVh.getPresenter();
RowPresenter.ViewHolder rowVh = rowPresenter.getRowViewHolder(bridgeVh.getViewHolder());
if (rowVh instanceof ListRowPresenter.ViewHolder) {
HorizontalGridView view = ((ListRowPresenter.ViewHolder) rowVh).getGridView();
// Recycled view pool is shared between all list rows
if (mRecycledViewPool == null) {
mRecycledViewPool = view.getRecycledViewPool();
} else {
view.setRecycledViewPool(mRecycledViewPool);
}
ItemBridgeAdapter bridgeAdapter =
((ListRowPresenter.ViewHolder) rowVh).getBridgeAdapter();
if (mPresenterMapper == null) {
mPresenterMapper = bridgeAdapter.getPresenterMapper();
} else {
bridgeAdapter.setPresenterMapper(mPresenterMapper);
}
}
}
@Override
void updateAdapter() {
super.updateAdapter();
mSelectedViewHolder = null;
mViewsCreated = false;
ItemBridgeAdapter adapter = getBridgeAdapter();
if (adapter != null) {
adapter.setAdapterListener(mBridgeAdapterListener);
}
}
@Override
public boolean onTransitionPrepare() {
boolean prepared = super.onTransitionPrepare();
if (prepared) {
freezeRows(true);
}
return prepared;
}
@Override
public void onTransitionEnd() {
super.onTransitionEnd();
freezeRows(false);
}
private void freezeRows(boolean freeze) {
mFreezeRows = freeze;
VerticalGridView verticalView = getVerticalGridView();
if (verticalView != null) {
final int count = verticalView.getChildCount();
for (int i = 0; i < count; i++) {
ItemBridgeAdapter.ViewHolder ibvh = (ItemBridgeAdapter.ViewHolder)
verticalView.getChildViewHolder(verticalView.getChildAt(i));
RowPresenter rowPresenter = (RowPresenter) ibvh.getPresenter();
RowPresenter.ViewHolder vh = rowPresenter.getRowViewHolder(ibvh.getViewHolder());
rowPresenter.freeze(vh, freeze);
}
}
}
/**
* For rows that willing to participate entrance transition, this function
* hide views if afterTransition is true, show views if afterTransition is false.
*/
public void setEntranceTransitionState(boolean afterTransition) {
mAfterEntranceTransition = afterTransition;
VerticalGridView verticalView = getVerticalGridView();
if (verticalView != null) {
final int count = verticalView.getChildCount();
for (int i = 0; i < count; i++) {
ItemBridgeAdapter.ViewHolder ibvh = (ItemBridgeAdapter.ViewHolder)
verticalView.getChildViewHolder(verticalView.getChildAt(i));
RowPresenter rowPresenter = (RowPresenter) ibvh.getPresenter();
RowPresenter.ViewHolder vh = rowPresenter.getRowViewHolder(ibvh.getViewHolder());
rowPresenter.setEntranceTransitionState(vh, mAfterEntranceTransition);
}
}
}
/**
* Selects a Row and perform an optional task on the Row. For example
* <code>setSelectedPosition(10, true, new ListRowPresenterSelectItemViewHolderTask(5))</code>
* Scroll to 11th row and selects 6th item on that row. The method will be ignored if
* RowsSupportFragment has not been created (i.e. before {@link #onCreateView(LayoutInflater,
* ViewGroup, Bundle)}).
*
* @param rowPosition Which row to select.
* @param smooth True to scroll to the row, false for no animation.
* @param rowHolderTask Task to perform on the Row.
*/
public void setSelectedPosition(int rowPosition, boolean smooth,
final Presenter.ViewHolderTask rowHolderTask) {
VerticalGridView verticalView = getVerticalGridView();
if (verticalView == null) {
return;
}
ViewHolderTask task = null;
if (rowHolderTask != null) {
// This task will execute once the scroll completes. Once the scrolling finishes,
// we will get a success callback to update selected row position. Since the
// update to selected row position happens in a post, we want to ensure that this
// gets called after that.
task = new ViewHolderTask() {
@Override
public void run(final RecyclerView.ViewHolder rvh) {
rvh.itemView.post(new Runnable() {
@Override
public void run() {
rowHolderTask.run(
getRowViewHolder((ItemBridgeAdapter.ViewHolder) rvh));
}
});
}
};
}
if (smooth) {
verticalView.setSelectedPositionSmooth(rowPosition, task);
} else {
verticalView.setSelectedPosition(rowPosition, task);
}
}
static RowPresenter.ViewHolder getRowViewHolder(ItemBridgeAdapter.ViewHolder ibvh) {
if (ibvh == null) {
return null;
}
RowPresenter rowPresenter = (RowPresenter) ibvh.getPresenter();
return rowPresenter.getRowViewHolder(ibvh.getViewHolder());
}
public boolean isScrolling() {
if (getVerticalGridView() == null) {
return false;
}
return getVerticalGridView().getScrollState() != HorizontalGridView.SCROLL_STATE_IDLE;
}
@Override
public void setAlignment(int windowAlignOffsetFromTop) {
if (windowAlignOffsetFromTop == ALIGN_TOP_NOT_SET) {
return;
}
mAlignedTop = windowAlignOffsetFromTop;
final VerticalGridView gridView = getVerticalGridView();
if (gridView != null) {
gridView.setItemAlignmentOffset(0);
gridView.setItemAlignmentOffsetPercent(
VerticalGridView.ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
gridView.setItemAlignmentOffsetWithPadding(true);
gridView.setWindowAlignmentOffset(mAlignedTop);
// align to a fixed position from top
gridView.setWindowAlignmentOffsetPercent(
VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
gridView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_NO_EDGE);
}
}
/**
* Find row ViewHolder by position in adapter.
* @param position Position of row.
* @return ViewHolder of Row.
*/
public RowPresenter.ViewHolder findRowViewHolderByPosition(int position) {
if (mVerticalGridView == null) {
return null;
}
return getRowViewHolder((ItemBridgeAdapter.ViewHolder) mVerticalGridView
.findViewHolderForAdapterPosition(position));
}
public static class MainFragmentAdapter extends BrowseSupportFragment.MainFragmentAdapter<RowsSupportFragment> {
public MainFragmentAdapter(RowsSupportFragment fragment) {
super(fragment);
setScalingEnabled(true);
}
@Override
public boolean isScrolling() {
return getFragment().isScrolling();
}
@Override
public void setExpand(boolean expand) {
getFragment().setExpand(expand);
}
@Override
public void setEntranceTransitionState(boolean state) {
getFragment().setEntranceTransitionState(state);
}
@Override
public void setAlignment(int windowAlignOffsetFromTop) {
getFragment().setAlignment(windowAlignOffsetFromTop);
}
@Override
public boolean onTransitionPrepare() {
return getFragment().onTransitionPrepare();
}
@Override
public void onTransitionStart() {
getFragment().onTransitionStart();
}
@Override
public void onTransitionEnd() {
getFragment().onTransitionEnd();
}
}
/**
* The adapter that RowsSupportFragment implements
* BrowseSupportFragment.MainFragmentRowsAdapter.
* @see #getMainFragmentRowsAdapter().
*/
public static class MainFragmentRowsAdapter
extends BrowseSupportFragment.MainFragmentRowsAdapter<RowsSupportFragment> {
public MainFragmentRowsAdapter(RowsSupportFragment fragment) {
super(fragment);
}
@Override
public void setAdapter(ObjectAdapter adapter) {
getFragment().setAdapter(adapter);
}
/**
* Sets an item clicked listener on the fragment.
*/
@Override
public void setOnItemViewClickedListener(OnItemViewClickedListener listener) {
getFragment().setOnItemViewClickedListener(listener);
}
@Override
public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) {
getFragment().setOnItemViewSelectedListener(listener);
}
@Override
public void setSelectedPosition(int rowPosition,
boolean smooth,
final Presenter.ViewHolderTask rowHolderTask) {
getFragment().setSelectedPosition(rowPosition, smooth, rowHolderTask);
}
@Override
public void setSelectedPosition(int rowPosition, boolean smooth) {
getFragment().setSelectedPosition(rowPosition, smooth);
}
@Override
public int getSelectedPosition() {
return getFragment().getSelectedPosition();
}
@Override
public RowPresenter.ViewHolder findRowViewHolderByPosition(int position) {
return getFragment().findRowViewHolderByPosition(position);
}
}
}