注意 似乎这个功能现在在leanback 支持库的22.1.1 版本中可用,这使得这个问题稍微过时了。但是,问题仍然存在,为什么公共标准文档要先于公共可用的库版本?
我正在浏览 API 文档,我看到有这个接口: OnChildLaidOutListener然后还有这个方法HorizontalGridView#setOnChildLaidOutListener。我尝试使用它们,但 Android Studio 说不存在这样的东西。我查看了 HorizontalGridView 的源代码(在 Studio 中),里面没有这样的东西。我尝试搜索不同版本的兼容性库,但没有一个具有此功能。从这里我可以看到此提交中添加了此功能减少 DPAD 滚动多列网格的内存消耗。
这一切是怎么回事?他们在官方 Android API 文档中记录了所有未来某一天无法使用的 API,或者为什么会在此处记录?还是我的 Android Studio 安装/配置有问题,只是我在那里有旧版本的支持库或发生了什么?
我真的很想使用这些东西……这正是我所需要的。
编辑:详细说明我在做什么的示例代码(尽管我仍然不明白这与为什么根据 API 文档这些方法应该存在的问题有关,但至少我不能使用它们)。因此,我要解决的问题是以编程方式将 GridView 初始化为选定的项目,然后在其上调用 requestLayout,否则放大的视图将从底部截断。
public class MinimalisticLeanbackFragment extends Fragment {
private HorizontalGridView gridView;
private boolean positionInitied = false;
public SimplifiedEpgFragment() {
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(android.support.v17.leanback.R.layout.lb_list_row, container, false);
}
public ItemBridgeAdapter initItemBridgeAdapter(ObjectAdapter objectAdapter) {
ItemBridgeAdapter iba = new ItemBridgeAdapter(objectAdapter);
ItemBridgeAdapter.Wrapper mWrapper = new ItemBridgeAdapter.Wrapper() {
@Override
public View createWrapper(View root) {
ShadowOverlayContainer wrapper = new ShadowOverlayContainer(root.getContext());
wrapper.setLayoutParams(
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
wrapper.initialize(needsDefaultShadow(), true, false);
return wrapper;
}
@Override
public void wrap(View wrapper, View wrapped) {
((ShadowOverlayContainer) wrapper).wrap(wrapped);
}
};
iba.setWrapper(mWrapper);
FocusHighlightHelper.setupBrowseItemFocusHighlight(iba, FocusHighlight.ZOOM_FACTOR_LARGE, false);
return iba;
}
private boolean needsDefaultShadow() {
return true;
}
private ObjectAdapter initObjectAdapter() {
ContentsPresenter contentsPresenter = new ContentsPresenter();
ArrayObjectAdapter contentsAdapter = new ArrayObjectAdapter(contentsPresenter);
contentsAdapter.addAll(0, ProgramList.collectionList());
return contentsAdapter;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
gridView = initGridView((HorizontalGridView) view.findViewById(R.id.row_content));
ItemBridgeAdapter mBridgeAdapter = initItemBridgeAdapter(initObjectAdapter());
gridView.setAdapter(mBridgeAdapter);
}
private HorizontalGridView initGridView(final HorizontalGridView gridView) {
gridView.isLaidOut();
ShadowOverlayContainer.prepareParentForShadow(gridView);
gridView.setClipChildren(false);
gridView.setFocusDrawingOrderEnabled(false); //Or?
gridView.setOnChildSelectedListener(new OnChildSelectedListener() {
@Override
public void onChildSelected(ViewGroup parent, View view, int position, long id) {
Log.d(Configs.TAG, "Child selected");
}
});
gridView.setFadingLeftEdge(false);
gridView.setFadingRightEdge(false);
//TODO: wtf? It seems the only way to do this would be to rewrite the entire HorizontalGridView and all of its dependencies injecting these newer
//features this updated version.
/*
gridView.setOnChildLaidOutListener(new android.support.v17.leanback.widget.OnChildLaidOutListener() {
@Override
public void onChildLaidOut(ViewGroup parent, View view, int position, long id) {
initGridState();
}
});
*/
//Maybe this could work then...
final ViewTreeObserver viewTreeObserver = gridView.getViewTreeObserver();
viewTreeObserver.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
@Override
public void onDraw() {
if (initGridState()) {
Log.d(Configs.TAG, "state init succeeded!");
viewTreeObserver.removeOnDrawListener(this);
} else {
Log.d(Configs.TAG, "onDraw of the gridview, children not ready yet..");
}
}
});
return gridView;
}
private boolean initGridState() {
int position = gridView.getSelectedPosition();
if (position == RecyclerView.NO_POSITION) {
position = 0;
gridView.setSelectedPosition(0);
}
if (!this.positionInitied) {
View child = gridView.getChildAt(position);
if (child != null) {
Log.d(Configs.TAG, "Child available, requesting focus the the selected position...");
child.requestFocus();
gridView.requestLayout();
} else {
Log.e(Configs.TAG, "Could not focus to child... grid has: " + gridView.getChildCount()+" children, is " + (gridView.isActivated() ? "" : " not ") + "activated");
return false;
}
} else {
Log.d(Configs.TAG, "Child focus already inited... doing nothing..");
}
return true;
}
}