Get ViewPager height and width in pixels only once inside Fragment

849 views Asked by At

I know there are a lot of similar questions, but suggested solutions don't work in my case.
What is my problem.
I have fragment nested inside activity.
Fragment layout includes ViewPager.
What is my idea ? As far as my application won't support landscape (this can cause some additional changes), my ViewPager is loading images from the network.Images can be quietly large and heavy, so I have written server side API which helps to convert image to the desired size on the server and return resized image url.
This will help to get rid of OutOfMemory errors.
But the problem is that I need to send ViewPager's height and width in my request.
I am finding it by id in onViewCreated

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mBannerSlider = (AutoScrollViewPager) view.findViewById(R.id.banner_slider);
    mBannerSlider.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener(){

                @Override
                public void onGlobalLayout() {
                    mSliderHeight = mBannerSlider.getHeight();
                    mSliderWidth = mBannerSlider.getWidth();
                    Toast.makeText(getActivity(),"View " + mSliderHeight + " " + mSliderWidth,Toast.LENGTH_SHORT).show();
                }
               requestBannerImages(mSliderHeight........);
            });

The problem here is that this method is called on every page change.
Of course I can use some helper variable to determine if it is first time or not.
Also there is way to send callback from activity to the fragment using this activitiy's method.

@Override
 public void onWindowFocusChanged(boolean hasFocus) {
  // TODO Auto-generated method stub
  super.onWindowFocusChanged(hasFocus);
  //Here you can get the size!
 }

What is the best solution in this way, maybe I can do this better in another way.
Thanks in advance.

EDIT

I have a plenty of view where I need to get dimensions, so I need to add listener to every view and that after first measurement remove it ?

2

There are 2 answers

0
The Original Android On

I understand your dilemma, mainly because I have implemented a multimedia app. However setting dimensions in every view or many UI elements related to icons/images is time consuming. If not so, then you end up with lots of code doing the same stuff.

In my opinion, you don't have to set dimensions for every view, for the sake of looks. You may set max height of a view/UI or/and set setAdjustViewBound to true, let the UI framework handle the images. There is a cost of performance though if the image is large, in your case probably not.

You may refer to Google notes on setMaxHeight of ImageView. Let me know of your view on this, interested to know.

1
Franklin On

I would do it with the tree observer. To avoid repeated calls I would remove the listeners once i get the value. This assures you that you will get the dimensions and it wont get call anymore.

if (Build.VERSION.SDK_INT < 16) {
    v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
} else {
    v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}

I took the code from: https://stackoverflow.com/a/16190337/2051397