2015-03-27 2 views
0

У меня есть только объект RemoteViews, который содержит мои отдельные виды. У меня есть следующий макет для этого объекта RemoteViews:Как рисовать круг с краем, содержащим изображение?

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal" 
    android:gravity="center"> 

<LinearLayout 
     android:layout_width="50dp" 
     android:layout_height="52dp" 
     android:layout_marginLeft="10dp" 
     android:gravity="center"> 
<ImageView 
     android:contentDescription="icon" 
     android:id="@+id/icon" 
     android:layout_width="30dp" 
     android:layout_height="30dp" 
     android:src="@drawable/dog" 
     /> 
</LinearLayout> 
<TextView 
     android:id="@+id/description" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:textColor="@android:color/white" 
     android:layout_marginLeft="10dp"/> 
</LinearLayout> 

Я пытаюсь нарисовать круг вокруг значка с некоторым пространством между ними; Я не хочу трассировать круг вокруг значка, я хочу, чтобы между ними было какое-то промежуток (например, знак цели).

Я думал, указав радиус большего размера, чем размеры изображения, я мог бы выполнить это, но внешний круг обрезается в некоторых частях; здесь «виды» - это объект RemoteViews:

Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),  
       R.drawable.dog); 
Bitmap workingBitmap = Bitmap.createBitmap(bitmap); 
Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, 
         true); 
Canvas canvas = new Canvas(mutableBitmap); 

Paint paint = new Paint(); 
paint.setAntiAlias(true); 
paint.setColor(Color.WHITE); 
paint.setStyle(Paint.Style.STROKE); 
paint.setStrokeWidth(6); 

int centerCoordinate = mutableBitmap.getWidth()/2; 
canvas.drawCircle(centerCoordinate, centerCoordinate, 
centerCoordinate+15, paint); 

// equivalent to imageView.setImageBitmap 
views.setImageViewBitmap(R.id.icon, mutableBitmap); 

ответ

1

Попробуйте этот модифицированный код. Я попытался объяснить изменения в комментариях. К сожалению, если они являются недостаточными:

 Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),  
       R.drawable.dog); 
     // 
     // vvvv Commented out vvvv 
     /* 
     * Reason: The new Bitmap must be larger than the bitmap around 
     * which the circle must be drawn. 
     */ 
//  Bitmap workingBitmap = Bitmap.createBitmap(bitmap); 
//  Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, 
//    true); 
//  Canvas canvas = new Canvas(mutableBitmap); 
     // ^^^^ Commented out ^^^^ 
     // 
     // vvvv Added vvvv 
     // This is the total (Right + left) extra space on the sides; 
     int padding = 30; 
     // Since the Paint is going to draw a noticeably thick line, the thickness must be included in the calculations 
     int strokeWidth = 6; 
     /* 
     * Calculating single dimension since the bitmap must have a square shape for the circle to fit. 
     * Also account for the padding and the stroke width; 
     */ 
     int bitmapSize = Math.max(bitmap.getWidth(), bitmap.getHeight()) + padding + strokeWidth; 
     Bitmap workingBitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, 
       Bitmap.Config.ARGB_8888); 
     Canvas canvas = new Canvas(workingBitmap); 
     // ^^^^ Added ^^^^ 
     // 
     Paint paint = new Paint(); 
     paint.setAntiAlias(true); 
     paint.setColor(Color.WHITE); 
     paint.setStyle(Paint.Style.STROKE); 
     // 
     // paint.setStrokeWidth(6); 
     paint.setStrokeWidth(strokeWidth); 
     // 
     // canvas.drawCircle(centerCoordinate, centerCoordinate, 
     //   centerCoordinate+15, paint); 
     /* 
     * Calculate exact top left position in the result Bitmap to draw the original Bitmap 
     */ 
     canvas.drawBitmap(bitmap, (bitmapSize - bitmap.getWidth())/2.0f, 
       (bitmapSize - bitmap.getHeight())/2.0f, paint); 
     // 
     // int centerCoordinate = mutableBitmap.getWidth()/2; 
     int centerCoordinate = bitmapSize/2; 
     // 
     //canvas.drawCircle(centerCoordinate, centerCoordinate, 
     // centerCoordinate+15, paint); 
     /* 
     * Draw the circle but account for the stroke width of the paint or else the circle will flatten on the edges of the Bitmap. 
     */ 
     canvas.drawCircle(centerCoordinate, centerCoordinate, 
       centerCoordinate - (strokeWidth/2.0f), paint); 
     // equivalent to imageView.setImageBitmap 
     // views.setImageViewBitmap(R.id.icon, mutableBitmap); 
     views.setImageViewBitmap(R.id.icon, workingBitmap); 

Кроме того, в компоновке для ImageView дополнения:

android:scaleType="fitXY"

Редактировать: Чтобы сохранить внутренний размер битовой карты фиксированной и только варьировать размер круга, первый , ImageView и его LinearLayout контейнер не могут имеют фиксированный размер. Измените все эти значения ширины и высоты макета в макете до "wrap_content".

Во-вторых, так как ресурс изображения для "bitmap" является неизвестного размера, bitmap должны быть загружены с уменьшенной версией ресурса, который соответствует максимально допустимый размер для точечного рисунка только, что в вашем случае 30px. Это может быть сделано путем замены:

Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),  
        R.drawable.dog); 

С помощью следующего кода:

// 
// Value to hold the required image dimension; 
int requiredImageDimension = 30; 
// Decode the Bitmap resource with the set options. 
Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), 
     R.drawable.dog); 
// Scaled bitmap reference; 
Bitmap bitmap = null; 
// Check if the largest dimension is the width; 
if (originalBitmap.getWidth() > originalBitmap.getHeight()) { 
    // Force the width to the maximum allowable size and calculate 
    // the scaled height of the Bitmap; 
    bitmap = Bitmap.createScaledBitmap(originalBitmap, 
      requiredImageDimension, 
      originalBitmap.getHeight() * requiredImageDimension 
        /originalBitmap.getWidth(), true); 
} 
// If the width and height are equal; 
else if(originalBitmap.getWidth() == originalBitmap.getHeight()){ 
    // Force the width and height to the maximum allowable size; 
    bitmap = Bitmap.createScaledBitmap(originalBitmap, 
      requiredImageDimension, 
      requiredImageDimension, true); 
} 
// If the largest dimension is the height; 
else { 
    // Force the height to the maximum allowable size and calculate 
    // the scaled width of the Bitmap; 
    bitmap = Bitmap.createScaledBitmap(originalBitmap, 
      originalBitmap.getWidth() * requiredImageDimension 
        /originalBitmap.getHeight(), 
      requiredImageDimension, true); 
} 

Итак, теперь вы получите уменьшенную версию оригинального растрового ресурса, который будет наклеен на больший workingBitmap и загруженный в ImageView, который будет изменять размеры для размещения растрового изображения без масштабирования.

+0

Спасибо, круг больше не обрезается, но прокладка очень минимальная. Увеличение его не влияет. В xml выше я должен был установить конкретные размеры для растрового изображения, так как он был слишком большим. Как увеличить заполнение вокруг моего значка? – MarcusH

+0

В этом коде, если вы увеличиваете «padding» (я пытался удвоить его), размер объекта (размерность) ** битмапа будет увеличиваться, но ваш значок в «ImageView» будет выглядеть меньше. Это связано с тем, что большое изображение вынуждено указывать размер 'ImageView'. Если вы хотите, чтобы ваш ** значок ** имел одинаковый (физический) размер, а ** увеличивая ** размер ** круга **, тогда вам придется разрешить 'ImageView' масштабировать себя на основе размер «битмапа» **, т. е. ** он ** не может иметь фиксированную ширину. Вы хотите **, что **? ... – electrocrat

+0

... Кстати, спасибо за мой ** первый голос ** .... – electrocrat

Смежные вопросы