sábado, 24 de janeiro de 2015

How to center crop image from camera or SdCard in android

Setting scaleType to centerCrop is not enough. You actually need to transform your Bitmap. The following method can do that (performance considerations are not taken seriously here, though)

    public static Bitmap scaleCenterCrop(Bitmap source, int newHeight, int newWidth) {
        int sourceWidth = source.getWidth();
        int sourceHeight = source.getHeight();
        // Compute the scaling factors to fit the new height and width, respectively.
        // To cover the final image, the final scaling will be the bigger
        // of these two.
        float xScale = (float) newWidth / sourceWidth;
        float yScale = (float) newHeight / sourceHeight;
        float scale = Math.max(xScale, yScale);
        // Now get the size of the source bitmap when scaled
        float scaledWidth = scale * sourceWidth;
        float scaledHeight = scale * sourceHeight;
        // Let's find out the upper left coordinates if the scaled bitmap
        // should be centered in the new size give by the parameters
        float left = (newWidth - scaledWidth) / 2;
        float top = (newHeight - scaledHeight) / 2;
        // The target rectangle for the new, scaled version of the source bitmap will now
        // be
        RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight);
        // Finally, we create a new bitmap of the specified size and draw our new,
        // scaled bitmap onto it.
        Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig());
        Canvas canvas = new Canvas(dest);
        canvas.drawBitmap(source, null, targetRect, null);
        return dest;
    }

So, remember to always call it before using your bitmap in your CircularImageViews

quarta-feira, 21 de janeiro de 2015

How to center AlertDialog message

You follow some tutorials and stackoverflow answer to code something like this
         final AlertDialog alertDialog = new AlertDialog.Builder(this)
                    .setMessage(getString(R.string.email_invalido))
                    .setNeutralButton(R.string.ok, null)
                    .create();
            TextView messageView = (TextView) alertDialog.findViewById(android.R.id.message);
            if (messageView != null) {
                messageView.setPadding(15, 20, 10, 10);
                messageView.setGravity(Gravity.CENTER_VERTICAL);
            }                                     alertDialog.show(); 

But that produces the following error:

android.util.AndroidRuntimeException: requestFeature() must be called before adding content
            at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:249)
            at com.android.internal.app.AlertController.installContent(AlertController.java:234)
            at android.app.AlertDialog.onCreate(AlertDialog.java:337)
            at android.app.Dialog.dispatchOnCreate(Dialog.java:361)
            at android.app.Dialog.show(Dialog.java:262)
            at xxx.activity.validateMailAndMayRequestRecoverPassword(EsqueciSenhaActivity.java:34)
            at xxx. activity onClickEnviarButton(EsqueciSenhaActivity.java:62)             at xxx.activity$$ViewInjector$1.onClick(EsqueciSenhaActivity$$ViewInjector.java:18)
            at android.view.View.performClick(View.java:4456)
            at android.view.View$PerformClick.run(View.java:18465)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)

Analyzing the PhoneWindow.java source code I've found out that you need to call show before using findViewById() because of some side effects.

So the correct code is

            final AlertDialog alertDialog = new AlertDialog.Builder(this)
                    .setMessage(getString(R.string.email_invalido))
                    .setNeutralButton(R.string.ok, null)
                    .create(); alertDialog.show();             TextView messageView = (TextView) alertDialog.findViewById(android.R.id.message);
            if (messageView != null) {
                messageView.setPadding(15, 20, 10, 10);
                messageView.setGravity(Gravity.CENTER_VERTICAL);
            }