我的问题类似于How to know GridView numColumns before setting up adapter in case of auto_fit?,但它还没有回答,所以试试我的运气,我已经研究了一点点。
简短背景.....我在片段中使用gridview布局,下面是xml:
<GridView
android:id="@android:id/someID"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="@dimen/grid_width"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:visibility="visible" >
</GridView>
现在目标是获取列数很简单,即调用gridview对象的getNumColumns()(http://developer.android.com/reference/android/widget/GridView.html#attr_android:numColumns),但是根据doc它可以返回-1(AUTO_FIT)如果视图尚未布局,我不想要。
因此,为了避免-1条件并确保实际铺设gridview,我在片段的onActivtyCreated()回调中做了类似How can you tell when a layout has been drawn?的事情。
但在这里它变得有趣,我添加了几个日志,并观察到有时我得到适当的值但有时我得到-1。我做了一点点挖掘并检查了gridview的实际代码,其中设置了列数。
//declaration of vars
public static final int AUTO_FIT = -1;
private int mNumColumns = AUTO_FIT;
private boolean determineColumns(int availableSpace) {
final int requestedHorizontalSpacing = mRequestedHorizontalSpacing;
final int stretchMode = mStretchMode;
final int requestedColumnWidth = mRequestedColumnWidth;
boolean didNotInitiallyFit = false;
if (mRequestedNumColumns == AUTO_FIT) {
if (requestedColumnWidth > 0) {
// Client told us to pick the number of columns
mNumColumns = (availableSpace + requestedHorizontalSpacing) /(requestedColumnWidth + requestedHorizontalSpacing);
} else {
// Just make up a number if we don't have enough info
mNumColumns = 2;
}
} else {
// We picked the columns
mNumColumns = mRequestedNumColumns;
}
if (mNumColumns <= 0) {
mNumColumns = 1;
}
此片段仅显示设置mNumColumns值的位置,对于整个代码,您可以看到http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.2_r1/android/widget/GridView.java,现在理论上mNumColumns永远不能获得-1,除非未布置视图。
那么我该怎样做这个场景,有什么建议吗?我可以添加延迟(更糟的案例设计)或者我可以添加一个检查-1并返回1(使用上面的代码片段的想法),这可能会导致竞争条件。可能我错过了一些东西,或者我的假设是错误的。
gridview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
gridview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int num = gridview.getNumColumns();
// do what u need here
}
});