Allow the Today widget to resize horizontally, change the default size to 2x1
This commit is contained in:
@@ -24,6 +24,9 @@ import android.content.Intent;
|
|||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.TypedValue;
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
|
|
||||||
import com.example.android.sunshine.app.MainActivity;
|
import com.example.android.sunshine.app.MainActivity;
|
||||||
@@ -38,12 +41,14 @@ public class TodayWidgetIntentService extends IntentService {
|
|||||||
private static final String[] FORECAST_COLUMNS = {
|
private static final String[] FORECAST_COLUMNS = {
|
||||||
WeatherContract.WeatherEntry.COLUMN_WEATHER_ID,
|
WeatherContract.WeatherEntry.COLUMN_WEATHER_ID,
|
||||||
WeatherContract.WeatherEntry.COLUMN_SHORT_DESC,
|
WeatherContract.WeatherEntry.COLUMN_SHORT_DESC,
|
||||||
WeatherContract.WeatherEntry.COLUMN_MAX_TEMP
|
WeatherContract.WeatherEntry.COLUMN_MAX_TEMP,
|
||||||
|
WeatherContract.WeatherEntry.COLUMN_MIN_TEMP
|
||||||
};
|
};
|
||||||
// these indices must match the projection
|
// these indices must match the projection
|
||||||
private static final int INDEX_WEATHER_ID = 0;
|
private static final int INDEX_WEATHER_ID = 0;
|
||||||
private static final int INDEX_SHORT_DESC = 1;
|
private static final int INDEX_SHORT_DESC = 1;
|
||||||
private static final int INDEX_MAX_TEMP = 2;
|
private static final int INDEX_MAX_TEMP = 2;
|
||||||
|
private static final int INDEX_MIN_TEMP = 3;
|
||||||
|
|
||||||
public TodayWidgetIntentService() {
|
public TodayWidgetIntentService() {
|
||||||
super("TodayWidgetIntentService");
|
super("TodayWidgetIntentService");
|
||||||
@@ -75,12 +80,25 @@ public class TodayWidgetIntentService extends IntentService {
|
|||||||
int weatherArtResourceId = Utility.getArtResourceForWeatherCondition(weatherId);
|
int weatherArtResourceId = Utility.getArtResourceForWeatherCondition(weatherId);
|
||||||
String description = data.getString(INDEX_SHORT_DESC);
|
String description = data.getString(INDEX_SHORT_DESC);
|
||||||
double maxTemp = data.getDouble(INDEX_MAX_TEMP);
|
double maxTemp = data.getDouble(INDEX_MAX_TEMP);
|
||||||
|
double minTemp = data.getDouble(INDEX_MIN_TEMP);
|
||||||
String formattedMaxTemperature = Utility.formatTemperature(this, maxTemp);
|
String formattedMaxTemperature = Utility.formatTemperature(this, maxTemp);
|
||||||
|
String formattedMinTemperature = Utility.formatTemperature(this, minTemp);
|
||||||
data.close();
|
data.close();
|
||||||
|
|
||||||
// Perform this loop procedure for each Today widget
|
// Perform this loop procedure for each Today widget
|
||||||
for (int appWidgetId : appWidgetIds) {
|
for (int appWidgetId : appWidgetIds) {
|
||||||
int layoutId = R.layout.widget_today_small;
|
// Find the correct layout based on the widget's width
|
||||||
|
int widgetWidth = getWidgetWidth(appWidgetManager, appWidgetId);
|
||||||
|
int defaultWidth = getResources().getDimensionPixelSize(R.dimen.widget_today_default_width);
|
||||||
|
int largeWidth = getResources().getDimensionPixelSize(R.dimen.widget_today_large_width);
|
||||||
|
int layoutId;
|
||||||
|
if (widgetWidth >= largeWidth) {
|
||||||
|
layoutId = R.layout.widget_today_large;
|
||||||
|
} else if (widgetWidth >= defaultWidth) {
|
||||||
|
layoutId = R.layout.widget_today;
|
||||||
|
} else {
|
||||||
|
layoutId = R.layout.widget_today_small;
|
||||||
|
}
|
||||||
RemoteViews views = new RemoteViews(getPackageName(), layoutId);
|
RemoteViews views = new RemoteViews(getPackageName(), layoutId);
|
||||||
|
|
||||||
// Add the data to the RemoteViews
|
// Add the data to the RemoteViews
|
||||||
@@ -89,7 +107,9 @@ public class TodayWidgetIntentService extends IntentService {
|
|||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||||
setRemoteContentDescription(views, description);
|
setRemoteContentDescription(views, description);
|
||||||
}
|
}
|
||||||
|
views.setTextViewText(R.id.widget_description, description);
|
||||||
views.setTextViewText(R.id.widget_high_temperature, formattedMaxTemperature);
|
views.setTextViewText(R.id.widget_high_temperature, formattedMaxTemperature);
|
||||||
|
views.setTextViewText(R.id.widget_low_temperature, formattedMinTemperature);
|
||||||
|
|
||||||
// Create an Intent to launch MainActivity
|
// Create an Intent to launch MainActivity
|
||||||
Intent launchIntent = new Intent(this, MainActivity.class);
|
Intent launchIntent = new Intent(this, MainActivity.class);
|
||||||
@@ -101,6 +121,29 @@ public class TodayWidgetIntentService extends IntentService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getWidgetWidth(AppWidgetManager appWidgetManager, int appWidgetId) {
|
||||||
|
// Prior to Jelly Bean, widgets were always their default size
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
|
return getResources().getDimensionPixelSize(R.dimen.widget_today_default_width);
|
||||||
|
}
|
||||||
|
// For Jelly Bean and higher devices, widgets can be resized - the current size can be
|
||||||
|
// retrieved from the newly added App Widget Options
|
||||||
|
return getWidgetWidthFromOptions(appWidgetManager, appWidgetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
||||||
|
private int getWidgetWidthFromOptions(AppWidgetManager appWidgetManager, int appWidgetId) {
|
||||||
|
Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
|
||||||
|
if (options.containsKey(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)) {
|
||||||
|
int minWidthDp = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
|
||||||
|
// The width returned is in dp, but we'll convert it to pixels to match the other widths
|
||||||
|
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
|
||||||
|
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, minWidthDp,
|
||||||
|
displayMetrics);
|
||||||
|
}
|
||||||
|
return getResources().getDimensionPixelSize(R.dimen.widget_today_default_width);
|
||||||
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
|
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
|
||||||
private void setRemoteContentDescription(RemoteViews views, String description) {
|
private void setRemoteContentDescription(RemoteViews views, String description) {
|
||||||
views.setContentDescription(R.id.widget_icon, description);
|
views.setContentDescription(R.id.widget_icon, description);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import android.support.annotation.NonNull;
|
|||||||
import com.example.android.sunshine.app.sync.SunshineSyncAdapter;
|
import com.example.android.sunshine.app.sync.SunshineSyncAdapter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provider for a widget showing today's weather.
|
* Provider for a horizontally expandable widget showing today's weather.
|
||||||
*
|
*
|
||||||
* Delegates widget updating to {@link TodayWidgetIntentService} to ensure that
|
* Delegates widget updating to {@link TodayWidgetIntentService} to ensure that
|
||||||
* data retrieval is done on a background thread
|
* data retrieval is done on a background thread
|
||||||
|
|||||||
BIN
app/src/main/res/drawable-nodpi/widget_preview_today.png
Normal file
BIN
app/src/main/res/drawable-nodpi/widget_preview_today.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
66
app/src/main/res/layout/widget_today.xml
Normal file
66
app/src/main/res/layout/widget_today.xml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2015 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="@dimen/widget_margin">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/widget"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/touch_selector_white"
|
||||||
|
android:padding="8dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/widget_icon"
|
||||||
|
android:layout_width="@dimen/widget_today_min_resize_width"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
tools:src="@drawable/art_clear" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toRightOf="@id/widget_icon"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/widget_high_temperature"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:textAppearance="?android:textAppearanceLarge"
|
||||||
|
android:textColor="@color/primary_text"
|
||||||
|
tools:text="48" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/widget_low_temperature"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:textAppearance="?android:textAppearanceSmall"
|
||||||
|
android:textColor="@color/secondary_text"
|
||||||
|
tools:text="28" />
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
</FrameLayout>
|
||||||
82
app/src/main/res/layout/widget_today_large.xml
Normal file
82
app/src/main/res/layout/widget_today_large.xml
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2015 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="@dimen/widget_margin">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/widget"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/touch_selector_white"
|
||||||
|
android:padding="8dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/widget_icon"
|
||||||
|
android:layout_width="@dimen/widget_today_min_resize_width"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
tools:src="@drawable/art_clear" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/widget_description"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toEndOf="@id/widget_icon"
|
||||||
|
android:layout_toRightOf="@id/widget_icon"
|
||||||
|
android:fontFamily="sans-serif-condensed"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:textAppearance="?android:textAppearanceLarge"
|
||||||
|
android:textColor="@color/primary_text"
|
||||||
|
tools:text="Clear" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/widget_low_temperature"
|
||||||
|
android:layout_width="@dimen/forecast_text_width"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:gravity="end"
|
||||||
|
android:fontFamily="sans-serif-light"
|
||||||
|
android:textColor="@color/forecast_low_text"
|
||||||
|
android:textSize="@dimen/forecast_text_size"
|
||||||
|
tools:text="7"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/widget_high_temperature"
|
||||||
|
android:layout_width="@dimen/forecast_text_width"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:gravity="end"
|
||||||
|
android:layout_toLeftOf="@id/widget_low_temperature"
|
||||||
|
android:layout_toStartOf="@id/widget_low_temperature"
|
||||||
|
android:layout_marginRight="@dimen/forecast_temperature_space"
|
||||||
|
android:layout_marginEnd="@dimen/forecast_temperature_space"
|
||||||
|
android:fontFamily="sans-serif-light"
|
||||||
|
android:textColor="@color/primary_text"
|
||||||
|
android:textSize="@dimen/forecast_text_size"
|
||||||
|
tools:text="10"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
</FrameLayout>
|
||||||
@@ -54,6 +54,9 @@
|
|||||||
<dimen name="landscape_forecast_view_width">360dp</dimen>
|
<dimen name="landscape_forecast_view_width">360dp</dimen>
|
||||||
|
|
||||||
<!-- Today Widget -->
|
<!-- Today Widget -->
|
||||||
<dimen name="widget_today_default_width">40dp</dimen>
|
<dimen name="widget_today_default_width">110dp</dimen>
|
||||||
<dimen name="widget_today_default_height">40dp</dimen>
|
<dimen name="widget_today_default_height">40dp</dimen>
|
||||||
|
<dimen name="widget_today_min_resize_width">40dp</dimen>
|
||||||
|
<dimen name="widget_today_min_resize_height">@dimen/widget_today_default_height</dimen>
|
||||||
|
<dimen name="widget_today_large_width">220dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -14,7 +14,13 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:initialLayout="@layout/widget_today_small"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:initialLayout="@layout/widget_today"
|
||||||
android:minHeight="@dimen/widget_today_default_height"
|
android:minHeight="@dimen/widget_today_default_height"
|
||||||
|
android:minResizeHeight="@dimen/widget_today_min_resize_height"
|
||||||
|
android:minResizeWidth="@dimen/widget_today_min_resize_width"
|
||||||
android:minWidth="@dimen/widget_today_default_width"
|
android:minWidth="@dimen/widget_today_default_width"
|
||||||
android:updatePeriodMillis="0" />
|
android:previewImage="@drawable/widget_preview_today"
|
||||||
|
android:resizeMode="horizontal"
|
||||||
|
android:updatePeriodMillis="0"
|
||||||
|
tools:ignore="UnusedAttribute" />
|
||||||
|
|||||||
Reference in New Issue
Block a user