下面列出了怎么用android.appwidget.AppWidgetHostView的API类实例代码及写法,或者点击链接到github查看源代码。
void addAppWidgetImpl(int appWidgetId, ItemInfo info,
AppWidgetHostView boundWidget, WidgetAddFlowHandler addFlowHandler, int delay) {
if (!addFlowHandler.startConfigActivity(this, appWidgetId, info, REQUEST_CREATE_APPWIDGET)) {
// If the configuration flow was not started, add the widget
Runnable onComplete = new Runnable() {
@Override
public void run() {
// Exit spring loaded mode if necessary after adding the widget
exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,
null);
}
};
completeAddAppWidget(appWidgetId, info, boundWidget, addFlowHandler.getProviderInfo(this));
mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);
}
}
public LauncherAppWidgetHostView(Context context) {
super(context);
mContext = context;
mLongPressHelper = new CheckLongPressHelper(this, this);
mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
mInflater = LayoutInflater.from(context);
setAccessibilityDelegate(Launcher.getLauncher(context).getAccessibilityDelegate());
setBackgroundResource(R.drawable.widget_internal_focus_bg);
if (AndroidVersion.isAtLeastOreo()) {
try {
Method asyncMethod = AppWidgetHostView.class
.getMethod("setExecutor", Executor.class);
asyncMethod.invoke(this, Utilities.THREAD_POOL_EXECUTOR);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static Bundle getDefaultOptionsForWidget(Context context, PendingAddWidgetInfo info) {
Rect rect = new Rect();
AppWidgetResizeFrame.getWidgetSizeRanges(context, info.spanX, info.spanY, rect);
Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context,
info.componentName, null);
float density = context.getResources().getDisplayMetrics().density;
int xPaddingDips = (int) ((padding.left + padding.right) / density);
int yPaddingDips = (int) ((padding.top + padding.bottom) / density);
Bundle options = new Bundle();
options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH,
rect.left - xPaddingDips);
options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT,
rect.top - yPaddingDips);
options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH,
rect.right - xPaddingDips);
options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT,
rect.bottom - yPaddingDips);
return options;
}
private AppWidgetHostView createWidgetFromId(int widget_id) {
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widget_id);
if (appWidgetInfo==null) {
return null;
}
// if (checkBindPermission(widget_id, appWidgetInfo.provider)) return null;
AppWidgetHostView hostView = getLoadedAppWidgetHostView(appWidgetInfo.provider);
if (hostView==null || hostView.getAppWidgetId()!=widget_id) {
// Create the host view
hostView = mAppWidgetHost.createView(mContext, widget_id, appWidgetInfo);
hostView.setAppWidget(widget_id, appWidgetInfo);
}
return hostView;
}
public AppWidgetHostView configureWidget(Activity parent, int appWidgetId){
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
if (appWidgetInfo!=null) {
if (appWidgetInfo.configure != null) {
// If the widget wants to be configured then start its configuration activity
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
intent.setComponent(appWidgetInfo.configure);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
parent.startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
} else {
// Otherwise simply create it
return createWidgetFromId(appWidgetId);
}
}
return null;
}
@Thunk void completeTwoStageWidgetDrop(
final int resultCode, final int appWidgetId, final PendingRequestArgs requestArgs) {
CellLayout cellLayout = mWorkspace.getScreenWithId(requestArgs.screenId);
Runnable onCompleteRunnable = null;
int animationType = 0;
AppWidgetHostView boundWidget = null;
if (resultCode == RESULT_OK) {
animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;
final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,
requestArgs.getWidgetHandler().getProviderInfo(this));
boundWidget = layout;
onCompleteRunnable = new Runnable() {
@Override
public void run() {
completeAddAppWidget(appWidgetId, requestArgs, layout, null);
exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),
EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
}
};
} else if (resultCode == RESULT_CANCELED) {
mAppWidgetHost.deleteAppWidgetId(appWidgetId);
animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;
}
if (mDragLayer.getAnimatedView() != null) {
mWorkspace.animateWidgetDrop(requestArgs, cellLayout,
(DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,
animationType, boundWidget, true);
} else if (onCompleteRunnable != null) {
// The animated view may be null in the case of a rotation during widget configuration
onCompleteRunnable.run();
}
}
/**
* Add a widget to the workspace.
*
* @param appWidgetId The app widget id
*/
@Thunk void completeAddAppWidget(int appWidgetId, ItemInfo itemInfo,
AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {
if (appWidgetInfo == null) {
appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(appWidgetId);
}
if (appWidgetInfo.isCustomWidget) {
appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;
}
LauncherAppWidgetInfo launcherInfo;
launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);
launcherInfo.spanX = itemInfo.spanX;
launcherInfo.spanY = itemInfo.spanY;
launcherInfo.minSpanX = itemInfo.minSpanX;
launcherInfo.minSpanY = itemInfo.minSpanY;
launcherInfo.user = appWidgetInfo.getUser();
getModelWriter().addItemToDatabase(launcherInfo,
itemInfo.container, itemInfo.screenId, itemInfo.cellX, itemInfo.cellY);
if (hostView == null) {
// Perform actual inflation because we're live
hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
}
hostView.setVisibility(View.VISIBLE);
prepareAppWidget(hostView, launcherInfo);
mWorkspace.addInScreen(hostView, launcherInfo);
}
/**
* Process a widget drop.
*/
private void addAppWidgetFromDrop(PendingAddWidgetInfo info) {
AppWidgetHostView hostView = info.boundWidget;
int appWidgetId;
WidgetAddFlowHandler addFlowHandler = info.getHandler();
if (hostView != null) {
// In the case where we've prebound the widget, we remove it from the DragLayer
getDragLayer().removeView(hostView);
appWidgetId = hostView.getAppWidgetId();
addAppWidgetFromDropImpl(appWidgetId, info, hostView, addFlowHandler);
// Clear the boundWidget so that it doesn't get destroyed.
info.boundWidget = null;
} else {
// In this case, we either need to start an activity to get permission to bind
// the widget, or we need to start an activity to configure the widget, or both.
appWidgetId = getAppWidgetHost().allocateAppWidgetId();
Bundle options = info.bindOptions;
boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(
appWidgetId, info.info, options);
if (success) {
addAppWidgetFromDropImpl(appWidgetId, info, null, addFlowHandler);
} else {
addFlowHandler.startBindFlow(this, appWidgetId, info, REQUEST_BIND_APPWIDGET);
}
}
}
void initSpans(Context context) {
InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
Point paddingLand = idp.landscapeProfile.getTotalWorkspacePadding();
Point paddingPort = idp.portraitProfile.getTotalWorkspacePadding();
// Always assume we're working with the smallest span to make sure we
// reserve enough space in both orientations.
float smallestCellWidth = DeviceProfile.calculateCellWidth(Math.min(
idp.landscapeProfile.widthPx - paddingLand.x,
idp.portraitProfile.widthPx - paddingPort.x),
idp.numColumns);
float smallestCellHeight = DeviceProfile.calculateCellWidth(Math.min(
idp.landscapeProfile.heightPx - paddingLand.y,
idp.portraitProfile.heightPx - paddingPort.y),
idp.numRows);
// We want to account for the extra amount of padding that we are adding to the widget
// to ensure that it gets the full amount of space that it has requested.
Rect widgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(
context, provider, null);
spanX = Math.max(1, (int) Math.ceil(
(minWidth + widgetPadding.left + widgetPadding.right) / smallestCellWidth));
spanY = Math.max(1, (int) Math.ceil(
(minHeight + widgetPadding.top + widgetPadding.bottom) / smallestCellHeight));
minSpanX = Math.max(1, (int) Math.ceil(
(minResizeWidth + widgetPadding.left + widgetPadding.right) / smallestCellWidth));
minSpanY = Math.max(1, (int) Math.ceil(
(minResizeHeight + widgetPadding.top + widgetPadding.bottom) / smallestCellHeight));
}
public AppWidgetHostView createView(Context context, int appWidgetId,
LauncherAppWidgetProviderInfo appWidget) {
if (appWidget.isCustomWidget) {
LauncherAppWidgetHostView lahv = new LauncherAppWidgetHostView(context);
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(appWidget.initialLayout, lahv);
lahv.setAppWidget(0, appWidget);
lahv.updateLastInflationOrientation();
return lahv;
} else {
try {
return super.createView(context, appWidgetId, appWidget);
} catch (Exception e) {
if (!Utilities.isBinderSizeError(e)) {
throw new RuntimeException(e);
}
// If the exception was thrown while fetching the remote views, let the view stay.
// This will ensure that if the widget posts a valid update later, the view
// will update.
LauncherAppWidgetHostView view = mViews.get(appWidgetId);
if (view == null) {
view = onCreateView(mLauncher, appWidgetId, appWidget);
}
view.setAppWidget(appWidgetId, appWidget);
view.switchToErrorView();
return view;
}
}
}
/**
* When we bind the widget, we should notify the widget that the size has changed if we have not
* done so already (only really for default workspace widgets).
*/
void onBindAppWidget(Launcher launcher, AppWidgetHostView hostView) {
if (!mHasNotifiedInitialWidgetSizeChanged) {
AppWidgetResizeFrame.updateWidgetSizeRanges(hostView, launcher, spanX, spanY);
mHasNotifiedInitialWidgetSizeChanged = true;
}
}
public void onWidgetRemoved(ComponentName provider, AppWidgetHostView view) {
AppLauncher app = AppLauncher.getAppLauncher(provider);
if (app!=null) {
mAppLauncherViews.remove(app);
db().deleteApp(app.getComponentName());
}
AppLauncher.removeAppLauncher(provider);
repopulateIconSheet(mCategory);
}
private void addWidget(AppWidgetHostView appwid) {
if (mChildLock) return;
ComponentName cn = appwid.getAppWidgetInfo().provider;
String actvname = cn.getClassName();
String pkgname = cn.getPackageName();
String catId = db().getAppCategory(cn);
if (mActionCategory==null) mActionCategory = mCategory;
if (catId == null || catId.equals(mActionCategory)) {
//Log.d(TAG, actvname + " " + pkgname);
mWidgetHelper.saveLoadedWidget(cn,appwid);
// mLoadedWidgets.put(actvname, appwid);
// mPrefs.edit().putInt(actvname, appwid.getAppWidgetId()).apply();
AppLauncher.removeAppLauncher(cn);
AppLauncher app = AppLauncher.createAppLauncher(actvname, pkgname, pkgname, mActionCategory, true);
db().addApp(app);
db().addAppCategoryOrder(mActionCategory, app.getComponentName());
} else {
Toast.makeText(this, getString(R.string.widget_alreay,db().getCategoryDisplay(catId)), Toast.LENGTH_LONG).show();
}
}
public AppWidgetHostView getOrCreateWidget(Activity parent, ComponentName provider) {
AppWidgetHostView hostView = getLoadedAppWidgetHostView(provider);
if (hostView == null) {
int id = getWidgetId(provider);
if (id!=-1) {
Log.d(TAG, "loading widget from id " + provider);
hostView =createWidgetFromId(id);
if (hostView==null) {
removeWidget(provider);
return null;
}
}
if (hostView==null) {
Log.d(TAG, "creating new widget " + provider);
hostView = loadWidget(parent, provider);
}
if (hostView==null) {
Log.d(TAG, "AppWidgetHostView was null for " + provider);
// db().deleteApp(app.getActivityName());
return null;
}
saveLoadedWidget(provider, hostView);
}
return hostView;
}
public void removeWidget(ComponentName cn) {
int id = getWidgetId(cn);
mAppWidgetHost.deleteAppWidgetId(id);
mPrefs.edit().remove(cn.toShortString()).apply();
AppWidgetHostView widv = mLoadedWidgets.remove(cn);
for (WidgetChangedListener wl: mWidgetChangedListeners) {
wl.onWidgetRemoved(cn, widv);
}
}
public void updateWidgetId(int oldId, int newId) {
AppWidgetProviderInfo provider = mAppWidgetManager.getAppWidgetInfo(newId);
AppWidgetHostView w = mLoadedWidgets.get(provider.provider);
if (w!=null) {
w.setAppWidget(newId, provider);
}
saveWidgetId(provider.provider, newId);
mAppWidgetHost.deleteAppWidgetId(oldId);
}
private AppWidgetHostView loadWidget(Activity parent, ComponentName cn) {
//Log.d(TAG, "Loaded from db: " + cn.getClassName() + " - " + cn.getPackageName());
// Check that there actually is a widget in the database
if (cn.getPackageName().isEmpty() && cn.getClassName().isEmpty()) {
Log.d(TAG, "DB was empty");
return null;
}
final List<AppWidgetProviderInfo> infos = mAppWidgetManager.getInstalledProviders();
// Get AppWidgetProviderInfo
AppWidgetProviderInfo appWidgetInfo = null;
// Iterate through all infos, trying to find the desired one
for (final AppWidgetProviderInfo info : infos) {
if (info.provider.equals(cn)) {
// We found it!
appWidgetInfo = info;
break;
}
}
if (appWidgetInfo == null) {
Log.d(TAG, "app info was null");
return null; // Stop here
}
return loadWidget(parent, appWidgetInfo);
}
private AppWidgetHostView configureWidget(Activity parent, Intent data) {
// Get the selected widget information
try {
int appWidgetId = getAppWidgetIdFromIntent(data);
return configureWidget(parent, appWidgetId);
} catch (Exception | Error e) {
Log.e(TAG, e.getMessage(), e);
}
return null;
}
public AppWidgetHostView onActivityResult(Activity parent, int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult: requestCode=" + requestCode + " resultCode=" + resultCode);
// listen for widget manager response
if (resultCode == Activity.RESULT_OK) {
if (requestCode == REQUEST_PICK_APPWIDGET) {
Log.d(TAG, "configureWidget");
return configureWidget(parent, data);
} else if (requestCode == REQUEST_CREATE_APPWIDGET || requestCode == REQUEST_BIND_APPWIDGET) {
Log.d(TAG, "createWidget");
return createWidget(data);
} else {
Log.d(TAG, "unknown RESULT_OK");
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Log.d(TAG, "RESULT_CANCELED");
if (data!=null) {
int appWidgetId = getAppWidgetIdFromIntent(data);
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
if (appWidgetId != -1) {
if (appWidgetInfo==null || getWidgetId(appWidgetInfo.provider)==-1) {
mAppWidgetHost.deleteAppWidgetId(appWidgetId);
}
}
}
}
return null;
}
@Override public void onCreateContextMenu(@NonNull ContextMenu menu, @NonNull View v, @Nullable ContextMenu.ContextMenuInfo menuInfo) {
// Set the calling view.
callingView = (AppWidgetHostView) v;
int index = appWidgetContainer.indexOfChild(v);
// Workaround for DialogFragment issue with context menu.
// Taken from: https://stackoverflow.com/a/18853634
MenuItem.OnMenuItemClickListener listener = new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
onContextItemSelected(item);
return true;
}
};
// Generate menu.
// TODO: Maybe a more robust and automated way can be done for this.
menu.clear();
menu.add(1, 0, 100, getString(R.string.action_remove_widget));
menu.add(1, 1, 100, getString(R.string.action_up_widget));
menu.add(1, 2, 100, getString(R.string.action_down_widget));
menu.getItem(0).setOnMenuItemClickListener(listener);
// Move actions should only be added when there is more than one widget.
menu.getItem(1).setVisible(appWidgetContainer.getChildCount() > 1 && index > 0);
menu.getItem(2).setVisible(appWidgetContainer.getChildCount() != index + 1);
if (appWidgetContainer.getChildCount() > 1) {
if (index > 0) {
menu.getItem(1).setOnMenuItemClickListener(listener);
}
if (index + 1 != appWidgetContainer.getChildCount()) {
menu.getItem(2).setOnMenuItemClickListener(listener);
}
}
}
/**
* Adds a widget to the desktop.
*
* @param data Intent used to receive the ID of the widget being added.
*/
private void addWidget(Intent data, int index, boolean newWidget) {
int widgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
WIDGET_CONFIG_DEFAULT_CODE);
AppWidgetProviderInfo appWidgetInfo = appWidgetManager.getAppWidgetInfo(widgetId);
AppWidgetHostView appWidgetHostView = appWidgetHost.createView(
requireActivity().getApplicationContext(),
widgetId, appWidgetInfo);
// Prevents crashing when the widget info can't be found.
// https://github.com/Neamar/KISS/commit/f81ae32ef5ff5c8befe0888e6ff818a41d8dedb4
if (appWidgetInfo == null) {
removeWidget(appWidgetHostView, widgetId);
} else {
// Notify widget of the available minimum space.
appWidgetHostView.setMinimumHeight(appWidgetInfo.minHeight);
appWidgetHostView.setAppWidget(widgetId, appWidgetInfo);
if (Utils.sdkIsAround(16)) {
appWidgetHostView.updateAppWidgetSize(null, appWidgetInfo.minWidth,
appWidgetInfo.minHeight, appWidgetInfo.minWidth, appWidgetInfo.minHeight);
}
// Remove existing widget if any and then add the new widget.
appWidgetContainer.addView(appWidgetHostView, index);
// Immediately listens for the widget.
appWidgetHost.startListening();
addWidgetActionListener(index);
registerForContextMenu(appWidgetContainer.getChildAt(index));
if (newWidget) {
// Update our list.
widgetsList.add(String.valueOf(widgetId));
// Apply preference changes.
PreferenceHelper.updateWidgets(widgetsList);
}
}
}
@Override public void onCreateContextMenu(@NonNull ContextMenu menu, @NonNull View v, @Nullable ContextMenu.ContextMenuInfo menuInfo) {
// Set the calling view.
callingView = (AppWidgetHostView) v;
int index = appWidgetContainer.indexOfChild(v);
// Workaround for DialogFragment issue with context menu.
// Taken from: https://stackoverflow.com/a/18853634
MenuItem.OnMenuItemClickListener listener = new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
onContextItemSelected(item);
return true;
}
};
// Generate menu.
// TODO: Maybe a more robust and automated way can be done for this.
menu.clear();
menu.add(1, 0, 100, getString(R.string.action_remove_widget));
menu.add(1, 1, 100, getString(R.string.action_up_widget));
menu.add(1, 2, 100, getString(R.string.action_down_widget));
menu.getItem(0).setOnMenuItemClickListener(listener);
// Move actions should only be added when there is more than one widget.
menu.getItem(1).setVisible(appWidgetContainer.getChildCount() > 1 && index > 0);
menu.getItem(2).setVisible(appWidgetContainer.getChildCount() != index + 1);
if (appWidgetContainer.getChildCount() > 1) {
if (index > 0) {
menu.getItem(1).setOnMenuItemClickListener(listener);
}
if (index + 1 != appWidgetContainer.getChildCount()) {
menu.getItem(2).setOnMenuItemClickListener(listener);
}
}
}
/**
* Adds a widget to the desktop.
*
* @param data Intent used to receive the ID of the widget being added.
*/
private void addWidget(Intent data, int index, boolean newWidget) {
int widgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
WIDGET_CONFIG_DEFAULT_CODE);
AppWidgetProviderInfo appWidgetInfo = appWidgetManager.getAppWidgetInfo(widgetId);
AppWidgetHostView appWidgetHostView = appWidgetHost.createView(
requireActivity().getApplicationContext(),
widgetId, appWidgetInfo);
// Prevents crashing when the widget info can't be found.
// https://github.com/Neamar/KISS/commit/f81ae32ef5ff5c8befe0888e6ff818a41d8dedb4
if (appWidgetInfo == null) {
removeWidget(appWidgetHostView, widgetId);
} else {
// Notify widget of the available minimum space.
appWidgetHostView.setMinimumHeight(appWidgetInfo.minHeight);
appWidgetHostView.setAppWidget(widgetId, appWidgetInfo);
if (Utils.sdkIsAround(16)) {
appWidgetHostView.updateAppWidgetSize(null, appWidgetInfo.minWidth,
appWidgetInfo.minHeight, appWidgetInfo.minWidth, appWidgetInfo.minHeight);
}
// Remove existing widget if any and then add the new widget.
appWidgetContainer.addView(appWidgetHostView, index);
// Immediately listens for the widget.
appWidgetHost.startListening();
addWidgetActionListener(index);
registerForContextMenu(appWidgetContainer.getChildAt(index));
if (newWidget) {
// Update our list.
widgetsList.add(String.valueOf(widgetId));
// Apply preference changes.
PreferenceHelper.updateWidgets(widgetsList);
}
}
}
private void initSpans() {
LauncherAppState app = LauncherAppState.getInstance();
InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
// We only care out the cell size, which is independent of the the layout direction.
Rect paddingLand = idp.landscapeProfile.getWorkspacePadding(false /* isLayoutRtl */);
Rect paddingPort = idp.portraitProfile.getWorkspacePadding(false /* isLayoutRtl */);
// Always assume we're working with the smallest span to make sure we
// reserve enough space in both orientations.
float smallestCellWidth = DeviceProfile.calculateCellWidth(Math.min(
idp.landscapeProfile.widthPx - paddingLand.left - paddingLand.right,
idp.portraitProfile.widthPx - paddingPort.left - paddingPort.right),
idp.numColumns);
float smallestCellHeight = DeviceProfile.calculateCellWidth(Math.min(
idp.landscapeProfile.heightPx - paddingLand.top - paddingLand.bottom,
idp.portraitProfile.heightPx - paddingPort.top - paddingPort.bottom),
idp.numRows);
// We want to account for the extra amount of padding that we are adding to the widget
// to ensure that it gets the full amount of space that it has requested.
Rect widgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(
app.getContext(), provider, null);
spanX = Math.max(1, (int) Math.ceil(
(minWidth + widgetPadding.left + widgetPadding.right) / smallestCellWidth));
spanY = Math.max(1, (int) Math.ceil(
(minHeight + widgetPadding.top + widgetPadding.bottom) / smallestCellHeight));
minSpanX = Math.max(1, (int) Math.ceil(
(minResizeWidth + widgetPadding.left + widgetPadding.right) / smallestCellWidth));
minSpanY = Math.max(1, (int) Math.ceil(
(minResizeHeight + widgetPadding.top + widgetPadding.bottom) / smallestCellHeight));
}
@Override
protected AppWidgetHostView onCreateView(Context context, int appWidgetId,
AppWidgetProviderInfo appWidget) {
if (appWidgetId == mQsbWidgetId) {
return new LauncherAppWidgetHostView(context) {
@Override
protected View getErrorView() {
// For the QSB, show an empty view instead of an error view.
return new View(getContext());
}
};
}
return new LauncherAppWidgetHostView(context);
}
public AppWidgetHostView createView(Context context, int appWidgetId,
LauncherAppWidgetProviderInfo appWidget) {
if (appWidget.isCustomWidget) {
LauncherAppWidgetHostView lahv = new LauncherAppWidgetHostView(context);
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(appWidget.initialLayout, lahv);
lahv.setAppWidget(0, appWidget);
lahv.updateLastInflationOrientation();
return lahv;
} else {
return super.createView(context, appWidgetId, appWidget);
}
}
private void completeTwoStageWidgetDrop(final int resultCode,
final int appWidgetId) {
CellLayout cellLayout = (CellLayout) mWorkspace
.getScreenWithId(mPendingAddInfo.screenId);
Runnable onCompleteRunnable = null;
int animationType = 0;
AppWidgetHostView boundWidget = null;
if (resultCode == RESULT_OK) {
animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;
final AppWidgetHostView layout = mAppWidgetHost.createView(this,
appWidgetId, mPendingAddWidgetInfo);
boundWidget = layout;
onCompleteRunnable = new Runnable() {
@Override
public void run() {
completeAddAppWidget(appWidgetId,
mPendingAddInfo.container,
mPendingAddInfo.screenId, layout, null);
exitSpringLoadedDragModeDelayed(
(resultCode != RESULT_CANCELED),
EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
}
};
} else if (resultCode == RESULT_CANCELED) {
mAppWidgetHost.deleteAppWidgetId(appWidgetId);
animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;
}
if (mDragLayer.getAnimatedView() != null) {
mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,
(DragView) mDragLayer.getAnimatedView(),
onCompleteRunnable, animationType, boundWidget, true);
} else if (onCompleteRunnable != null) {
// The animated view may be null in the case of a rotation during
// widget configuration
onCompleteRunnable.run();
}
}
static int[] getSpanForWidget(Context context, ComponentName component,
int minWidth, int minHeight) {
Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context,
component, null);
// We want to account for the extra amount of padding that we are adding
// to the widget
// to ensure that it gets the full amount of space that it has requested
int requiredWidth = minWidth + padding.left + padding.right;
int requiredHeight = minHeight + padding.top + padding.bottom;
return CellLayout.rectToCell(requiredWidth, requiredHeight, null);
}
void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,
final AppWidgetHostView boundWidget,
final AppWidgetProviderInfo appWidgetInfo, int delay) {
if (appWidgetInfo.configure != null) {
mPendingAddWidgetInfo = appWidgetInfo;
mPendingAddWidgetId = appWidgetId;
// Launch over to configure widget, if needed
Intent intent = new Intent(
AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
intent.setComponent(appWidgetInfo.configure);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
Utilities.startActivityForResultSafely(this, intent,
REQUEST_CREATE_APPWIDGET);
} else {
// Otherwise just add it
Runnable onComplete = new Runnable() {
@Override
public void run() {
// Exit spring loaded mode if necessary after adding the
// widget
exitSpringLoadedDragModeDelayed(true,
EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
}
};
completeAddAppWidget(appWidgetId, info.container, info.screenId,
boundWidget, appWidgetInfo);
mWorkspace.removeExtraEmptyScreen(true, onComplete, delay, false);
}
}
private void cleanupWidgetPreloading(boolean widgetWasAdded) {
if (!widgetWasAdded) {
// If the widget was not added, we may need to do further cleanup.
PendingAddWidgetInfo info = mCreateWidgetInfo;
mCreateWidgetInfo = null;
if (mWidgetCleanupState == WIDGET_PRELOAD_PENDING) {
// We never did any preloading, so just remove pending callbacks to do so
removeCallbacks(mBindWidgetRunnable);
removeCallbacks(mInflateWidgetRunnable);
} else if (mWidgetCleanupState == WIDGET_BOUND) {
// Delete the widget id which was allocated
if (mWidgetLoadingId != -1) {
mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId);
}
// We never got around to inflating the widget, so remove the callback to do so.
removeCallbacks(mInflateWidgetRunnable);
} else if (mWidgetCleanupState == WIDGET_INFLATED) {
// Delete the widget id which was allocated
if (mWidgetLoadingId != -1) {
mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId);
}
// The widget was inflated and added to the DragLayer -- remove it.
AppWidgetHostView widget = info.boundWidget;
mLauncher.getDragLayer().removeView(widget);
}
}
mWidgetCleanupState = WIDGET_NO_CLEANUP_REQUIRED;
mWidgetLoadingId = -1;
mCreateWidgetInfo = null;
PagedViewWidget.resetShortPressTarget();
}