improve performance of scrollview in main screen #39

Closed
marc.nause wants to merge 5 commits from marc.nause/TinyWeatherForecastGermany:fixjerkylist into master
3 changed files with 285 additions and 152 deletions

View File

@ -1,14 +1,20 @@
package de.kaffeemitkoffein.tinyweatherforecastgermany;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.*;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.SparseArray;
import android.view.WindowManager;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Objects;
public class ForecastBitmap{
@ -25,6 +31,18 @@ public class ForecastBitmap{
private float fontSize_medium;
private boolean displayWind = false;
private static final Paint POLY_PAINT = new Paint();
static {
POLY_PAINT.setStyle(Paint.Style.FILL_AND_STROKE);
}
private static final Paint TEXT_PAINT = new Paint();
static {
TEXT_PAINT.setAlpha(255);
}
private static final SparseArray<Bitmap> BITMAP_CACHE = new SparseArray<>();
static class Builder{
private ArrayList<Weather.WeatherInfo> weatherInfos;
private Weather.WeatherLocation weatherLocation;
@ -102,6 +120,8 @@ public class ForecastBitmap{
}
}
}
TEXT_PAINT.setColor(getColorFromResource(R.color.textColor));
}
private Bitmap getIconBitmap(Context context, Weather.WeatherInfo weatherInfo, int bitmapWidth, int bitmapHeight){
@ -115,24 +135,34 @@ public class ForecastBitmap{
resource = WeatherCodeContract.getWeatherConditionDrawableResource(weatherInfo.getCondition(), weatherInfo.isDaytime(this.weatherLocation));
}
}
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(context.getResources(),resource),
bitmapWidth,
bitmapHeight,
true);
final int key = Objects.hash(resource, bitmapHeight, bitmapWidth);
Bitmap bitmap = BITMAP_CACHE.get(key);
if (bitmap == null) {
bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(context.getResources(),resource),
bitmapWidth,
bitmapHeight,
true);
BITMAP_CACHE.put(key, bitmap);
}
return bitmap;
}
public static void clearBitmapCache() {
BITMAP_CACHE.clear();
}
private void drawPolygon(Canvas canvas, float[] poly_x, float[] poly_y, int color, int alpha){
Paint poly_paint = new Paint();
poly_paint.setColor(color);
poly_paint.setAlpha(alpha);
poly_paint.setStyle(Paint.Style.FILL_AND_STROKE);
POLY_PAINT.setColor(color);
POLY_PAINT.setAlpha(alpha);
Path path = new Path();
path.moveTo(0,poly_y[0]);
for (int i=0; i<poly_x.length; i++){
path.lineTo(poly_x[i],poly_y[i]);
}
canvas.drawPath(path,poly_paint);
canvas.drawPath(path, POLY_PAINT);
}
public Bitmap getForecastBitmap(){
@ -150,9 +180,7 @@ public class ForecastBitmap{
itemWidth = (float) (bitmapWidth / anticipatedWidth);
fontSize_medium = (float) (bitmapHeight/2.2);
fontSize_small = (float) (bitmapHeight/3.3);
Paint paint = new Paint();
paint.setColor(getColorFromResource(R.color.textColor));
paint.setTextSize(fontSize_medium);
TEXT_PAINT.setTextSize(fontSize_medium);
float x_offset = (bitmapWidth - itemWidth);
// draw polygons for rain and clouds
float[] x_polygon = new float[weatherInfos.size()+4];
@ -200,19 +228,18 @@ public class ForecastBitmap{
Date date = new Date();
date.setTime(weatherInfos.get(position).getTimestamp());
String timetext = format.format(date);
paint.setTextSize(fontSize_small);
paint.setAlpha(255);
canvas.drawText(timetext,x_offset,fontSize_small,paint);
TEXT_PAINT.setTextSize(fontSize_small);
canvas.drawText(timetext,x_offset,fontSize_small,TEXT_PAINT);
// draw icon
Weather.WeatherInfo wi = weatherInfos.get(position);
float iconsize = itemWidth*iconRatio;
if (iconsize>bitmapHeight-fontSize_small-1){
iconsize = bitmapHeight-fontSize_small-1;
}
canvas.drawBitmap(getIconBitmap(context, wi,(int) iconsize,(int) iconsize),x_offset, fontSize_small+1,paint);
canvas.drawBitmap(getIconBitmap(context, wi,(int) iconsize,(int) iconsize),x_offset, fontSize_small+1,TEXT_PAINT);
// place temperature
paint.setTextSize(fontSize_medium);
canvas.drawText(weatherInfos.get(position).getTemperatureInCelsiusInt()+"°",x_offset+itemWidth*iconRatio,(float) (bitmapHeight/2)+fontSize_medium/2,paint);
TEXT_PAINT.setTextSize(fontSize_medium);
canvas.drawText(weatherInfos.get(position).getTemperatureInCelsiusInt()+"°",x_offset+itemWidth*iconRatio,(float) (bitmapHeight/2)+fontSize_medium/2,TEXT_PAINT);
x_offset = x_offset - itemWidth;
position--;
}

View File

@ -57,6 +57,8 @@ public class MainActivity extends Activity {
public final static boolean API_TESTING_ENABLED = false;
private int test_position = 0; //last: 1916
private ForecastAdapter forecastAdapter;
StationsManager stationsManager;
ArrayList<String> spinnerItems;
@ -622,7 +624,7 @@ public class MainActivity extends Activity {
displayUpdateTime(weatherCard);
PrivateLog.log(getApplicationContext(),Tag.MAIN,"displaying: "+weatherCard.getCity()+" sensor: "+weatherCard.weatherLocation.name);
ListView weatherList = (ListView) findViewById(R.id.main_listview);
ForecastAdapter forecastAdapter = new ForecastAdapter(getApplicationContext(),getCustomForecastWeatherInfoArray(weatherCard),weatherCard.forecast1hourly,weatherCard.weatherLocation);
forecastAdapter = new ForecastAdapter(getApplicationContext(),getCustomForecastWeatherInfoArray(weatherCard),weatherCard.forecast1hourly,weatherCard.weatherLocation);
weatherList.setAdapter(forecastAdapter);
UpdateAlarmManager.updateAndSetAlarmsIfAppropriate(getApplicationContext(),UpdateAlarmManager.CHECK_FOR_UPDATE);
}
@ -1053,6 +1055,23 @@ public class MainActivity extends Activity {
}
}
@Override
public void onTrimMemory(final int level) {
switch (level) {
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
if (forecastAdapter != null) {
forecastAdapter.clearBitmapCache();
}
break;
}
}
private void showSimpleLocationAlert(String text){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getApplicationContext().getResources().getString(R.string.geoinput_title));