mercredi 13 mai 2015

Center a sampled Bitmap inside an ImageView

I am at my wits end with this one. I have searched through countless articles and stack overflow posts but I have yet to find anything.

I have a HorizontalScrollView with a LinearLayout (Horizontal orientation) that will hold dynamically created ImageViews that will be the width of the root FrameLayout of the Fragment that this view goes to. Here is the XML.

<HorizontalScrollView
            android:id="@+id/main_scroll_view"
            android:layout_width="match_parent"
            android:layout_height="@dimen/news_images_height"
            android:layout_alignParentBottom="true"
            android:background="#ff4c4c4c"
            android:scrollbars="none">
    <LinearLayout
        android:id="@+id/news_images_container"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:background="#ff4c4c4c"
        android:clipChildren="false"
        >
        <!-- Dynamically created ImageViews here-->
    </LinearLayout>
</HorizontalScrollView>

What I am doing is loading a SAMPLED bitmap from memory to better display it and then creating a new ImageView and inserting that new ImageView into the LinearLayout.

Here is how I'm sampling the resource Bitmap:

public Bitmap getSampledBitmapFromResource(int resId, int reqWidth, int reqHeight){
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(mContext.getResources(), resId, options);

    options = getSampledBitmapOptions(options, reqWidth, reqHeight);

    return BitmapFactory.decodeResource(mContext.getResources(), resId, options);
}

private BitmapFactory.Options getSampledBitmapOptions(BitmapFactory.Options initialOptions,
                                                      int reqWidth, int reqHeight) {


    initialOptions.inSampleSize = calculateInSampleSize(initialOptions, reqWidth, reqHeight);

    // Use this display's density for the image
    WindowManager wm =
            (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    DisplayMetrics metrics = new DisplayMetrics();
    wm.getDefaultDisplay().getMetrics(metrics);
    int density = (int) metrics.density;
    initialOptions.inDensity =
            initialOptions.inScreenDensity = density;
    initialOptions.inTargetDensity = density;

    // Set to decode the whole image
    initialOptions.inJustDecodeBounds = false;
    return initialOptions;
}


private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight){
    // Raw height and width of the image
    final int width = options.outWidth;
    final int height = options.outHeight;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height/2;
        final int halfWidth = width/2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight/inSampleSize) > reqHeight && (halfWidth/inSampleSize) > reqWidth) {
            inSampleSize *= 2; // inSampleSize will always round to a power of 2.
        }

    }

    return inSampleSize;
}

And here is how I'm creating and setting the ImageView:

    //Set the dimensions of the image views based on pre-defined values
    int containerWidth = getActivity().getResources().getDisplayMetrics().widthPixels;
    int containerHeight = (int) getActivity().getResources().getDimension(R.dimen.news_images_height); // 100dp

    for (int i = 0; i < mDrawableIds.length; i++) {
        FrameLayout.LayoutParams layoutParams =
                new FrameLayout.LayoutParams(
                        containerWidth, containerHeight);
        layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER;

        // Add the new ImageView to the Arraylist holding all of the 'news images' at the given position
        mImageViews.add(i, new ImageView(getActivity()));
        ImageView tempView = mImageViews.get(i);
        tempView.setLayoutParams(layoutParams);
        tempView.setId(i);
        tempView.setVisibility(View.VISIBLE);
        tempView.setImageBitmap(
                mFileManager.getSampledBitmapFromResource(
                        mDrawableIds[i],
                        containerWidth,
                        containerHeight));
        tempView.setScaleType(ImageView.ScaleType.FIT_CENTER);


        // Add to the LinearLayout
        mLinearLayout.addView(tempView, i);

    }

The problem is that the Bitmap within the ImageView (which is about 33% the width of the ImageView) does not center! If I change the scaleType to FIT_CENTER then the system aligns this sampled Bitmap to center based off of it's LEFT edge and not its CENTER. I have tried multiple combinations of using various Gravity settings and layout params but nothing seems to be working. I need the Bitmap to be centered around it's center point and not around it's left edge.

Please help!

Aucun commentaire:

Enregistrer un commentaire