Каков правильный способ внедрения Android-виджета с динамическим рисунком?
Для моего первого и самого удивительного Android-проекта я хочу создать виджет главного экрана, который отображает один из тех Arc Clocks, который все дети в эти дни бредят.
Исходя из ограничений RemoteViews, мне кажется, что подходящий способ получить его на самом деле нарисован на экране - использовать ImageView в фактическом макете, а затем, когда он обновляется, создайте ShapeDrawable или два и нарисуйте их на вновь созданный Bitmap. Затем установите Bitmap в качестве источника ImageView.
Есть что-то о том процессе, который я просто не грохочу. Ниже приведен код, который я пытался использовать для обновления виджета. Я вообще ничего не рисую на экране. ImageView имеет образ заполнителя, просто заданный свойством src
. Когда я не запускаю код, чтобы обновить его до моего рисунка, изображение-заполнитель останется на месте. Итак, я знаю, что этот код что-то делает, просто явно не так.
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
ShapeDrawable drawable = new ShapeDrawable(new ArcShape(0, 360));
drawable.getPaint().setColor(0xffff0000);
drawable.getPaint().setStrokeWidth(5.0f);
drawable.setIntrinsicWidth(100);
drawable.setIntrinsicHeight(100);
drawable.draw(canvas);
views.setImageViewBitmap(R.id.ImageView01, bitmap);
appWidgetManager.updateAppWidget(appWidgetId, views);
Я знал, что это не может быть так просто. Итак, я даже направляюсь в правильном направлении?
Обновление
Хорошо, может быть, это было слишком много информации. Вопрос, который я действительно пытаюсь задать, таков:
Если я хочу рисовать фигуры в виджетах, должен ли я использовать ImageView и создавать растровые изображения из моего ShapeDrawable или есть ли более подходящий способ рисовать в виджет, где он ограничен RemoteViews?
Ответы
Ответ 1
На самом деле есть виджет под названием AnalogClock
в SDK, который очень похож на то, что вы пытаетесь сделать.
Он реализуется как класс, который расширяет View
и аннотируется с помощью @RemoteView
. Он регистрирует приемники на Intent.ACTION_TIME_TICK
и Intent.ACTION_TIME_CHANGED
и рисует себя, переопределяя метод onDraw
. Проверьте источник . Стандартное AlarmClock приложение выставляет this посмотреть как виджет, который можно добавить на главный экран.
Я думаю, что это хороший (если не самый лучший) способ реализовать то, что вы описали, и, очевидно, хорошо работает.
Ответ 2
Это отлично работает:
Paint p = new Paint();
p.setAntiAlias(true);
p.setStyle(Style.STROKE);
p.setStrokeWidth(8);
p.setColor(0xFFFF0000);
Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawArc(new RectF(10, 10, 90, 90), 0, 270, false, p);
RemoteViews views = new RemoteViews(updateService.getPackageName(), R.layout.main);
views.setImageViewBitmap(R.id.canvas, bitmap);
ComponentName componentName = new ComponentName(updateService, DashboardAppWidgetProvider.class);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(updateService);
appWidgetManager.updateAppWidget(componentName, views);
Я думаю, проблема с вашим исходным кодом была всего лишь способом рисования дуги - поэтому ничего не появилось.
BTW: вы можете найти настраиваемые "Arc Clock" с очень небольшим объемом памяти на рынке, ища "часы дуги"!
Ответ 3
Чтобы создать пользовательский компонент, я бы увеличил View или любой подкласс View и переопределил метод onDraw (Canvas canvas), чтобы сделать ваш рисунок. На объекте canvas вы можете вызывать такие методы, как drawLine(), drawArc(), drawPicture(), drawPoints(), drawText(), drawRect() и т.д.
Здесь более подробная информация.
Здесь api для холста.
Я считаю, что вы можете добавить свое пользовательское представление к удаленному виду с целью создания виджета.