启动器的代码在packages/apps/Trebuchet下
其中翻页图标用的是WorkspacePageIndicator,其中setScroll用于设置滚动位置,我们在其中计算蝙蝠图标的翻转角度,然后在draw中重新绘制。代码如下
packages/apps/Trebuchet/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
private Bitmap mBatLogo = null; // 绘制的图标资源
private Camera camera = new Camera(); // 用于翻转图标
private Paint paint = new Paint(); // 用于绘制页码
private float mCurrentPage; // 用于记录页面位置,计算翻转角度
@Override
public void setScroll(int currentScroll, int totalScroll) {
Log.e("BAT", "setScroll currentScroll=" + currentScroll + " totalScroll=" + totalScroll);
if (getAlpha() == 0) {
Log.e("BAT", "setScroll Alpha is 0");
return;
}
animateLineToAlpha(mActiveAlpha);
mCurrentScroll = currentScroll;
if (mTotalScroll == 0) {
mTotalScroll = totalScroll;
} else if (mTotalScroll != totalScroll) {
animateToTotalScroll(totalScroll);
} else {
invalidate();
}
Log.v("BAT", "currentScroll:" + currentScroll + " totalScroll:" + totalScroll);
//0 1060 2120
//0.0 0.5 1.0 1.5 2.0
//1 2 3
// 计算mCurrentPage
if(mNumPagesFloat-1 > 0 && mTotalScroll > 0){
mCurrentPage = (float)mCurrentScroll / (mTotalScroll / ((int)mNumPagesFloat-1));
}
if (mShouldAutoHide) {
hideAfterDelay();
}
}
@Override
protected void onDraw(Canvas canvas) {
if (mTotalScroll == 0 || mNumPagesFloat == 0) {
return;
}
// 绘制蝙蝠翻页图标
batDraw(canvas);
// // Compute and draw line rect.
// float progress = Utilities.boundToRange(((float) mCurrentScroll) / mTotalScroll, 0f, 1f);
// int availableWidth = getWidth();
// int lineWidth = (int) (availableWidth / mNumPagesFloat);
// int lineLeft = (int) (progress * (availableWidth - lineWidth));
// int lineRight = lineLeft + lineWidth;
// canvas.drawRoundRect(lineLeft, getHeight() / 2 - mLineHeight / 2, lineRight,
// getHeight() / 2 + mLineHeight / 2, mLineHeight, mLineHeight, mLinePaint);
}
private String int2Roman(int num) {
final String I[] = new String[] { "0","I","II","III","IV","V","VI","VII","VIII","IX", "X"};
if(num >= I.length)
num = I.length-1;
if(num < 0)
num = 0;
return I[num];
}
private void batDraw(Canvas canvas) {
if (mBatLogo == null)
mBatLogo = BitmapFactory.decodeResource(getResources(), R.drawable.batman_icon);
int currentPageInt = (int)mCurrentPage;
// int currentPageInt = (int)mNumPagesFloat;
float currentPagedecimals = mCurrentPage - currentPageInt;
// float currentPagedecimals = mNumPagesFloat - currentPageInt;
String strPageNum = "";
int w = canvas.getWidth();
int h = canvas.getHeight();
camera.save();
final Matrix matrix = new Matrix();
matrix.reset();
if(currentPagedecimals < 0.5) {
camera.rotateY(90 * (currentPagedecimals / 0.5f));
strPageNum = int2Roman(currentPageInt+1);
} else {
camera.rotateY(-90 * ((1.0f - currentPagedecimals)/0.5f));
strPageNum = int2Roman(currentPageInt + 2);
}
camera.getMatrix(matrix);
//matrix.postScale(0.2f, 1.0f);
matrix.preTranslate(-w/2, -h/2);
matrix.postTranslate(w/2, h/2);
camera.restore();
int srcw = mBatLogo.getWidth();
int srch = mBatLogo.getHeight();
Rect destRect = new Rect(0, 0, w, h);
if(w * srch < srcw * h) { //w / h < srcw / srch
int hh = w * srch / srcw;
destRect.top += (h - hh) / 2;
destRect.bottom -= (h - hh) / 2;
} else if(w * srch > srcw * h) { //w / h > srcw / srch
int ww = h * srcw / srch;
destRect.left += (w - ww) / 2;
destRect.right -= (w - ww) / 2;
}
canvas.save();
canvas.concat(matrix);
// 绘制蝙蝠图标
canvas.drawBitmap(mBatLogo, new Rect(0, 0, srcw, srch), destRect, paint);
// 绘制页码
final Paint.FontMetrics fontMetrics = paint.getFontMetrics();
final float top = fontMetrics.top; //为基线到字体上边框的距离,即上图中的top
final float bottom = fontMetrics.bottom; //为基线到字体下边框的距离,即上图中的bottom
final int baseLineY = (int) (h/2 - top/2 - bottom/2);//基线中间点的y轴计算公式
canvas.drawText(strPageNum, w/2, baseLineY, paint);
canvas.restore();
}
最后要在启动器图标加载完之后刷新一次翻页图标,否则翻页图标无法在启动的时候显示
packages/apps/Trebuchet/src/com/android/launcher3/Launcher.java
@Override
protected void onResume() {
Object traceToken = TraceHelper.INSTANCE.beginSection(ON_RESUME_EVT,
TraceHelper.FLAG_UI_EVENT);
super.onResume();
if (mDeferOverlayCallbacks) {
scheduleDeferredCheck();
} else {
mOverlayManager.onActivityResumed(this);
}
TraceHelper.INSTANCE.endSection(traceToken);
Log.e("BAT", "onResume mWorkspace.showPageIndicatorAtCurrentScroll();");
mWorkspace.showPageIndicatorAtCurrentScroll(); // 刷新图标
}
最终效果如下
正常情况下中间显示蝙蝠图标,图标中间的II表示第二页。
向左和向有滑动的时候,下面图标进行翻转。
代码连接https://github.com/1193561652/android_packages_apps_Trebuchet.git