Изображение AppWidget с закругленными углами

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

В настоящее время я создаю свою сцену в RelativeLayout, беря изображение макета как растровое изображение, а затем сохраняю растровое изображение в SD, доступ к которому можно получить через appuidget через uri.

Это все работает отлично, но... в attmept для создания закругленных углов для изображения appwidget, я попытался использовать эти два фрагмента, которые я нашел здесь.

Моя проблема:

заключается в том, что этот метод генерирует drawable (закругленные углы выглядят идеально, если отображаются как доступные), но мне нужно экспортировать эти прозрачные углы в виде файла изображения. Метод drawToBitmap в CustomView ниже генерирует растровое изображение, но углы полны и квадратны.

/**
 * shows a bitmap as if it had rounded corners. based on :
 * http://rahulswackyworld.blogspot.co.il/2013/04/android-drawables-with-rounded_7.html
 */
public class RoundedCornersDrawable extends BitmapDrawable {

    private final BitmapShader bitmapShader;
    private final Paint p;
    private final RectF rect;
    private final float borderRadius;

    public RoundedCornersDrawable(final Resources resources, final Bitmap bitmap, final float     borderRadius) {
        super(resources, bitmap);
        bitmapShader = new BitmapShader(getBitmap(), Shader.TileMode.CLAMP,     Shader.TileMode.CLAMP);
        final Bitmap b = getBitmap();
        p = getPaint();
        p.setAntiAlias(true);
        p.setShader(bitmapShader);
        final int w = b.getWidth(), h = b.getHeight();
        rect = new RectF(0, 0, w, h);
        this.borderRadius = borderRadius < 0 ? 0.15f * Math.min(w, h) : borderRadius;
    }

    @Override
    public void draw(final Canvas canvas) {
        canvas.drawRoundRect(rect, borderRadius, borderRadius, p);
    }
}

и

public class CustomView extends ImageView {
    private FrameLayout mMainContainer;
    private boolean mIsDirty=false;

    // TODO for each change of views/content, set mIsDirty to true and call invalidate

    @Override
    protected void onDraw(final Canvas canvas) {
        if (mIsDirty) {
            mIsDirty = false;
            drawContent();
            return;
        }
        super.onDraw(canvas);
    }

    /**
     * draws the view content to a bitmap. code based on :
     * http://nadavfima.com/android-snippet-inflate-a-layout-draw-to-a-bitmap/
     */
    public static Bitmap drawToBitmap(final View viewToDrawFrom, final int width, final int height) {
        // Create a new bitmap and a new canvas using that bitmap
        final Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(bmp);
        viewToDrawFrom.setDrawingCacheEnabled(true);
        // Supply measurements
        viewToDrawFrom.measure(MeasureSpec.makeMeasureSpec(canvas.getWidth(),     MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(canvas.getHeight(), MeasureSpec.EXACTLY));
        // Apply the measures so the layout would resize before drawing.
        viewToDrawFrom.layout(0, 0, viewToDrawFrom.getMeasuredWidth(),    viewToDrawFrom.getMeasuredHeight());
        // and now the bmp object will actually contain the requested layout
        canvas.drawBitmap(viewToDrawFrom.getDrawingCache(), 0, 0, new Paint());
        return bmp;
     }

    private void drawContent() {
        if (getMeasuredWidth() <= 0 || getMeasuredHeight() <= 0)
            return;
        final Bitmap bitmap = drawToBitmap(mMainContainer, getMeasuredWidth(), getMeasuredHeight());
        final RoundedCornersDrawable drawable = new RoundedCornersDrawable(getResources(),     bitmap, 15);
        setImageDrawable(drawable);
    }
}

Я понимаю, что растровое изображение не несет альфа-информации, которая необходима, чтобы иметь прозрачные округлые углы в изображении, Поэтому я попытался сохранить файл как PNG;

RCD_test - RoundedCornersDrawable

Bitmap bitmap = RCD_test.getBitmap();
bitmap.setHasAlpha(true);
OutputStream stream = new          
FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/test/screenshottest.png");
bitmap.compress(CompressFormat.PNG, 100, stream);
stream.close();

но безрезультатно. Весь этот подход может показаться непрозрачным, но это то, что я придумал, чтобы устранить ограничения в AppWidget RemoteViews.

Мой вопрос:

Как я могу взять этот RoundedCornersDrawable и экспортировать его как файл PNG, который правильно отображает его красивые прозрачные углы?

заблаговременно за помощь, и я открыт для любых предложений по различным подходам к проблеме в целом!

Ответ 1

В дополнение к этой проблеме:

'Оказывается, размер моего AppWidget обрезал изображение все время. Обрезать его достаточно, чтобы удалить закругленные углы, и просто так мало, чтобы не быть явно обрезанным. Так для любого что сталкивается с этим вопросом... все эти методы работают для этого (просто не забудьте сделать свой AppWidget достаточно большим, чтобы увидеть результаты).

Ответ:

Я обнаружил, что было важно также передать RoundedCornersDrawable с помощью метода CustomView.drawToBitMap(), прежде чем экспортировать его в файл PNG.

Я надеюсь, что все это когда-нибудь поможет кому-нибудь в дороге!

Ответ 2

К сожалению, AppWidgets довольно ограничены в плане просмотров. вы можете использовать только те представления, которые поддерживает Android.

Причина в том, что код представления должен запускаться в контейнере AppWidget и что это риск для безопасности, поскольку вы могли бы взглянуть на частные данные приложения, которое показывает его. Так что Google сделал то, что вам нужно подготовить, что показывать, и когда вы закончите, сообщите ограниченному API, как показать AppWidget.

Таким образом, решение должно заключаться в том, чтобы очистить изображение, как оно должно быть показано, до изображения или чего-то подобного. Я предлагаю сделать это в фоновом режиме, если у него есть много возможностей для подготовки.

Все зависит от ваших потребностей.