N.B。看来这个功能现在可以在leanback支持库的22.1.1版本中使用,这使得这个问题略显过时。但是,问题仍然存在,为什么公共标准文档要先于公开的库版本?
我正在浏览API文档,我看到有这样的界面: OnChildLaidOutListener然后还有这个方法HorizontalGridView#setOnChildLaidOutListener。我尝试使用它们,但Android Studio说没有这样的东西存在。我查看了HorizontalGridView的源代码(在Studio中),那里没有这样的东西。我尝试搜索兼容库的不同版本,但没有一个具有此功能。从这里我可以看到此功能已添加到此提交Reduce memory consumption of DPAD scroll multiple column grid。
这一切是怎么回事?他们在官方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;
}
}