1.概述
在14.0的系统产品rom定制化开发中,进行Tv设备定制化开发中,配置的有遥控器需要使用遥控器来移动来控制点击功能,所以需要给app 的Icon 和hotseat
添加背景来显示选中状态原生的Launcher的背景没有支持遥控器的焦点事件,所以就需要在Launcher3中给Item 添加默认背景直接焦点样式背景,
接下来就来实现相关功能
2.Launcher3 app图标和hotseat 添加背景(焦点选中背景)的核心类
/packages/apps/Launcher3/src/com/android/launcher3/ShortcutAndWidgetContainer.java
3.Launcher3 app图标和hotseat 添加背景(焦点选中背景)核心功能分析和实现
功能实现分析:
Launcher顾名思义,就是桌面的意思,也是android系统启动后第一个启动的应用程序,
:Launcher3负责管理和展示用户手机桌面上的各个应用程序图标。它通过GridView或者LinearLayout等布局管理器将
图标进行排列,并支持滑动、放大缩小等手势操作
在原生Launcher3中主页面的布局是由Workspace 构造的 每一个页面由一个CellLayout组成,CellLayout还不是真正容纳图标的ViewGroup,每个CellLayout会包含一个ShortcutAndWidgetContainer,这才是真正容纳图标和Widget的ViewGroup。
接下来具体看ShortcutAndWidgetContainer.java 的源码分析问题
3.1 ShortcutAndWidgetContainer.java 的源码关于源码背景分析问题
在实现Launcher3 app图标和hotseat 添加背景(焦点选中背景)核心功能中,通过上述的分析得知,在ShortcutAndWidgetContainer.java中的上述源码中,这里就是具体定义每个app图标和hotseat等相关控制的核心类,接下来看下相关核心代码
-
public class ShortcutAndWidgetContainer extends ViewGroup {
-
static final String TAG = "ShortcutAndWidgetContainer";
-
....
-
public ShortcutAndWidgetContainer(Context context, @ContainerType int containerType) {
-
super(context);
-
mActivity = ActivityContext.lookupContext(context);
-
mWallpaperManager = WallpaperManager.getInstance(context);
-
mContainerType = containerType;
-
}
-
-
public void setCellDimensions(int cellWidth, int cellHeight, int countX, int countY) {
-
mCellWidth = cellWidth;
-
mCellHeight = cellHeight;
-
mCountX = countX;
-
}
-
-
public View getChildAt(int x, int y) {
-
final int count = getChildCount();
-
for (int i = 0; i < count; i++) {
-
View child = getChildAt(i);
-
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
-
-
if ((lp.cellX <= x) && (x < lp.cellX + lp.cellHSpan) &&
-
(lp.cellY <= y) && (y < lp.cellY + lp.cellVSpan)) {
-
return child;
-
}
-
}
-
return null;
-
}
-
-
@Override
-
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-
int count = getChildCount();
-
-
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
-
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
-
setMeasuredDimension(widthSpecSize, heightSpecSize);
-
-
for (int i = 0; i < count; i++) {
-
View child = getChildAt(i);
-
if (child.getVisibility() != GONE) {
-
measureChild(child);
-
}
-
}
-
}
-
-
public void setupLp(View child) {
-
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
-
if (child instanceof LauncherAppWidgetHostView) {
-
DeviceProfile profile = mActivity.getWallpaperDeviceProfile();
-
lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX,
-
profile.appWidgetScale.x, profile.appWidgetScale.y);
-
} else {
-
lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX);
-
}
-
}
-
-
-
@Override
-
protected void onLayout(boolean changed, int l, int t, int r, int b) {
-
int count = getChildCount();
-
for (int i = 0; i < count; i++) {
-
final View child = getChildAt(i);
-
if (child.getVisibility() != GONE) {
-
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
-
layoutChild(child);
-
}
-
}
-
}
-
-
@Override
-
public boolean onInterceptTouchEvent(MotionEvent ev) {
-
if (ev.getAction() == ACTION_DOWN && getAlpha() == 0) {
-
// Dont let children handle touch, if we are not visible.
-
return true;
-
}
-
return super.onInterceptTouchEvent(ev);
-
}
-
-
....
-
}
在实现Launcher3 app图标和hotseat 添加背景(焦点选中背景)核心功能中,通过上述的分析得知,
在ShortcutAndWidgetContainer.java中的上述源码中,是继承自View的自定义布局,所以可以
从源码中可以看出 onMeasure(int widthMeasureSpec, int heightMeasureSpec) 和onLayout(boolean changed, int l, int t, int r, int b) 负责绘制子Item的
所以要想给app 和 hotseat 添加背景 就得在这里添加就好了
所以修改如下:
在measureChild(View child) 中添加背景
编译launcher3 发现功能已经实现了
-
public void measureChild(View child) {
-
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
-
final DeviceProfile profile = mActivity.getWallpaperDeviceProfile();
-
-
if (child instanceof LauncherAppWidgetHostView) {
-
lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX,
-
profile.appWidgetScale.x, profile.appWidgetScale.y);
-
// Widgets have their own padding
-
} else {
-
lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX);
-
// Center the icon/folder
-
int cHeight = getCellContentHeight();
-
int cellPaddingY = (int) Math.max(0, ((lp.height - cHeight) / 2f));
-
int cellPaddingX = mContainerType == CellLayout.WORKSPACE
-
? profile.workspaceCellPaddingXPx
-
: (int) (profile.edgeMarginPx / 2f);
-
child.setPadding(cellPaddingX, cellPaddingY, cellPaddingX, 0);
-
}
-
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
-
int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
-
child.measure(childWidthMeasureSpec, childheightMeasureSpec);
-
-
// 添加背景颜色
-
child.setBackgroundResource(R.drawable.shape_button);
-
}
在实现Launcher3 app图标和hotseat 添加背景(焦点选中背景)核心功能中,通过上述的分析得知,在ShortcutAndWidgetContainer.java中的上述源码中,在实现功能中,需要
添加新的背景布局具体如下
shape_button.xml 为:
-
<?xml version="1.0" encoding="utf-8"?>
-
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
-
<item android:state_pressed="true">
-
<shape>
-
<solid android:color="#CFCFCF"/>
-
</shape>
-
</item>
-
<item android:state_focused="true">
-
<shape>
-
<solid android:color="#CFCFCF"/>
-
</shape>
-
</item>
-
<item android:state_selected="true">
-
<shape>
-
<solid android:color="#E8E8E8"/>
-
</shape>
-
</item>
-
<item android:state_selected="false">
-
<shape>
-
<solid android:color="#00000000"/>
-
</shape>
-
</item>
-
<item android:state_pressed="false">
-
<shape>
-
<solid android:color="#00000000"/>
-
</shape>
-
</item>
-
<item android:state_focused="false">
-
<shape>
-
<solid android:color="#00000000"/>
-
</shape>
-
</item>
-
</selector>
在实现Launcher3 app图标和hotseat 添加背景(焦点选中背景)核心功能中,通过上述的分析得知,
在ShortcutAndWidgetContainer.java中的上述源码中,通过上述在ShortcutAndWidgetContainer.java中的
measureChild(View child)中添加shape_button.xml背景就可以实现相关功能