先查看CellLayout的构造函数:
public CellLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mDragEnforcer = new DropTarget.DragEnforcer(context);
// A ViewGroup usually does not draw, but CellLayout needs to draw a rectangle to show
// the user where a dragged item will land when dropped.
setWillNotDraw(false);
setClipToPadding(false);
mLauncher = (Launcher) context;
LauncherAppState app = LauncherAppState.getInstance();
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0);
mCellWidth = mCellHeight = -1;
mFixedCellWidth = mFixedCellHeight = -1;
mWidthGap = mOriginalWidthGap = 0;
mHeightGap = mOriginalHeightGap = 0;
mMaxGap = Integer.MAX_VALUE;
// mCountX = (int) grid.numColumns;
// mCountY = (int) grid.numRows;
mCountX = 4; // x方向icon的个数 //add by Garment:修改celllayout的行列数
mCountY = 4; //y方向icon的个数
Log.i("Garment2", "mCountX:"+mCountX+";mCountY:"+mCountY);
mOccupied = new boolean[mCountX][mCountY];
mTmpOccupied = new boolean[mCountX][mCountY];
mPreviousReorderDirection[0] = INVALID_DIRECTION;
mPreviousReorderDirection[1] = INVALID_DIRECTION;
a.recycle();
setAlwaysDrawnWithCacheEnabled(false);
final Resources res = getResources();
mHotseatScale = (float) grid.hotseatIconSizePx / grid.iconSizePx;
//change by sarah
mNormalBackground = res.getDrawable(R.drawable.edit_screen_bg);
mActiveGlowBackground = res.getDrawable(R.drawable.screenpanel_hover);
mOverScrollLeft = res.getDrawable(R.drawable.overscroll_glow_left);
mOverScrollRight = res.getDrawable(R.drawable.overscroll_glow_right);
mForegroundPadding =
res.getDimensionPixelSize(R.dimen.workspace_overscroll_drawable_padding);
mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE *
grid.iconSizePx);
mNormalBackground.setFilterBitmap(true);
mActiveGlowBackground.setFilterBitmap(true);
// Initialize the data structures used for the drag visualization.
mEaseOutInterpolator = new DecelerateInterpolator(2.5f); // Quint ease out
mDragCell[0] = mDragCell[1] = -1;
for (int i = 0; i < mDragOutlines.length; i++) {
mDragOutlines[i] = new Rect(-1, -1, -1, -1);
}
// When dragging things around the home screens, we show a green outline of
// where the item will land. The outlines gradually fade out, leaving a trail
// behind the drag path.
// Set up all the animations that are used to implement this fading.
final int duration = res.getInteger(R.integer.config_dragOutlineFadeTime);
final float fromAlphaValue = 0;
final float toAlphaValue = (float)res.getInteger(R.integer.config_dragOutlineMaxAlpha);
Arrays.fill(mDragOutlineAlphas, fromAlphaValue);
for (int i = 0; i < mDragOutlineAnims.length; i++) {
final InterruptibleInOutAnimator anim =
new InterruptibleInOutAnimator(this, duration, fromAlphaValue, toAlphaValue);
anim.getAnimator().setInterpolator(mEaseOutInterpolator);
final int thisIndex = i;
anim.getAnimator().addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
final Bitmap outline = (Bitmap)anim.getTag();
// If an animation is started and then stopped very quickly, we can still
// get spurious updates we've cleared the tag. Guard against this.
if (outline == null) {
@SuppressWarnings("all") // suppress dead code warning
final boolean debug = false;
if (debug) {
Object val = animation.getAnimatedValue();
Log.d(TAG, "anim " + thisIndex + " update: " + val +
", isStopped " + anim.isStopped());
}
// Try to prevent it from continuing to run
animation.cancel();
} else {
mDragOutlineAlphas[thisIndex] = (Float) animation.getAnimatedValue();
CellLayout.this.invalidate(mDragOutlines[thisIndex]);
}
}
});
// The animation holds a reference to the drag outline bitmap as long is it's
// running. This way the bitmap can be GCed when the animations are complete.
anim.getAnimator().addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if ((Float) ((ValueAnimator) animation).getAnimatedValue() == 0f) {
anim.setTag(null);
}
}
});
mDragOutlineAnims[i] = anim;
}
mBackgroundRect = new Rect();
mForegroundRect = new Rect();
mShortcutsAndWidgets = new ShortcutAndWidgetContainer(context);
mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap,
mCountX, mCountY);
addView(mShortcutsAndWidgets);
}
从上面的代码可知,
mCountX = (int) grid.numColumns;
mCountY = (int) grid.numRows;
这两行代码就是得到workspace中应用的行列数。在我的机台上系统直接返回的是6*5,就是五行六列。
暂时的做法就是直接给这两个变量赋值,达到修改workspace应用行列数的目的。
分析上面的grid.numColumns和grid.numRows的获取:
for (DeviceProfile p : profiles) {
points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.numRows));
}
numRows = Math.round(invDistWeightedInterpolate(minWidth, minHeight, points));
Log.i("Garment2", "DeviceProfile---numRows:"+numRows);
// Interpolate the columns
points.clear();
for (DeviceProfile p : profiles) {
points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.numColumns));
}
numColumns = Math.round(invDistWeightedInterpolate(minWidth, minHeight, points));
Log.i("Garment2", "DeviceProfile---numColumns:"+numColumns);
以上代码是在DeviceProfile的构造函数当中,其中numRows和numColumns是得到的行列数,由invDistWeightedInterpolate()函数算得。