How to set 9-patch background for ViewPager, that will put the pages inside, and keep aspect ratio?

夙愿已清 提交于 2019-12-11 03:25:20

问题


Background

I have a ViewPager (of images pages), which needs to show its content inside an image that should keep its aspect ratio.

The problem

Problem is, when I just set a 9-patch for any kind of ViewGroup (including the ViewPager), the image just stretches (not keeping the aspect-ratio), and for some reason, it doesn't even respect the content bounding box I've set to it (in the 9-patch).

It occurs even if I put the ViewPager in a FrameLayout that has the 9-patch background instead.

What I've tried

I've tried to overcome this by not using 9-patch at all. I used a RelativeLayout with ImageView (of the image) , and the ViewPager set to align exactly to the ImageView.

Of course, this wasn't enough, since the ImageView doesn't take the same space as what it shows, so I had to calculate the padding needed to fix it, based on the image size and the imageView size, and then set it on a FrameLayout that includes the ViewPager. This almost works, but it has issues too (not precise calculations, which could cause one pixel row to show/hide of the viewPager).

The question

Is it possible to set a background for ViewPager (or any other ViewGroup), that will keep its aspect ratio, yet also allow padding using 9-patch?


回答1:


ok, so what I did is this:

  1. set the 9-patch as a background to the parent of the ViewPager, or to the ViewPager itself.
  2. right when you get the size of the view, calculate what should be the width or height of it, depending on the bitmap size and the restrictions you have, and set it to the view.

In my case, the restrictions were to fill it to the height of the parent, so what I needed is to calculate the needed width...

Weird thing, is that I still see artefacts. The bottom of the viewpager has about 1-2 pixels rows of the background instead of being of itself (the "hole" of the 9-patch is at the bottom of the image).

EDIT: fixed it too. Seems to be an issue with various screen pixels-densities. Here's a snippet:

public static void runJustBeforeBeingDrawn(final View view, final Runnable runnable) {
    final OnPreDrawListener preDrawListener = new OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            view.getViewTreeObserver().removeOnPreDrawListener(this);
            runnable.run();
            return true;
        }
    };
    view.getViewTreeObserver().addOnPreDrawListener(preDrawListener);
}

public static BitmapFactory.Options getBitmapOptions(final Resources res, final int resId) {
    final BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
    bitmapOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, bitmapOptions);
    return bitmapOptions;
}


    final Options bitmapOptions = getBitmapOptions(getResources(), R.drawable.nine_patch_image);
    final View viewPagerContainer = ...;
    runJustBeforeBeingDrawn(viewPagerContainer, new Runnable() {
        @Override
        public void run() {
            int neededWidth = (int)Math.ceil((float) bitmapOptions.outWidth * viewPagerContainer.getHeight() / bitmapOptions.outHeight);
            final LayoutParams layoutParams = viewPagerContainer.getLayoutParams();
            layoutParams.width=neededWidth;
            viewPagerContainer.setLayoutParams(layoutParams);
        }
    });

EDIT: Alternative to runJustBeforeBeingDrawn: https://stackoverflow.com/a/28136027/878126



来源:https://stackoverflow.com/questions/31229007/how-to-set-9-patch-background-for-viewpager-that-will-put-the-pages-inside-and

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!