Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getWidth() & getHeight() returning 0 inside RecyclerView/Fragment

I'm calling the populating method for the RecyclerView inside the OnCreateView method in several fragments, they are then directed to the adapter for which populates the feeds (depending on the context of the Fragment).

At the minute, I am adding tags to an uploaded image from a user on the feed. Those tags require an x and y value (position), in which is a percentage of the container (which is set and saved to a BaaS when they upload). At the moment, the pixel to percentage formula works perfectly but when I try and grab the dimensions of the container, every option I have tried returns 0 every time.

RecyclerViewHolderAllFeeds(View view) {
    ...
    this.imageContainer = (RelativeLayout) view
                .findViewById(R.id.image_container);
}

Tag Snippet: (This function is called inside the bind, to bind all the tags to the uploaded image)

  float x = containerWidth - Float.parseFloat(model.getXpoints(o)) / 100 * containerWidth;
            float y = containerHeight - Float.parseFloat(model.getYpoints(o)) / 100 * containerHeight;
            Log.e("measuredWidth", "" + containerHeight + "" + containerWidth);
            Log.e("getPointX", "" + model.getXpoints(o) + "" + model.getYpoints(o));
            Log.e("x", "x" + x + "y" + y);
            tag.setX(x);
            tag.setY(y);

I set the values for containerWidth at the moment in the OnCreateViewHolder method:

RecyclerViewHolderAllFeeds holder = null;
    LayoutInflater mInflater = LayoutInflater.from(viewGroup.getContext());
    if (viewType == 1) {
        // This method will inflate the custom layout and return as viewholde
        ViewGroup mainGroup = (ViewGroup) mInflater.inflate(R.layout.feed_and_search_feed_item_row, viewGroup, false);
        holder =  new RecyclerViewHolderAllFeeds(mainGroup);
        containerWidth = getContainerWidth(holder);
        containerHeight = getContainerHeight(holder);
    } else {
        ViewGroup mainGroup = (ViewGroup) mInflater.inflate(R.layout.progress_item, viewGroup, false);
        holder =  new ProgressViewHolder(mainGroup);
    }
    return  holder;

I have also tried this way inside the onViewAttchedToWindow method:

   @Override
   public void onViewAttachedToWindow(RecyclerViewHolderAllFeeds holder) {
       super.onViewAttachedToWindow(holder);
       containerWidth = getContainerWidth(holder);
       containerHeight = getContainerHeight(holder);
   }

But again x and y values equate to zero.

GetContainerWidth(ViewHolder holder) method:

 float getContainerWidth(final RecyclerViewHolderAllFeeds h) {
        final int[] width = new int[1];
        final ViewTreeObserver observer = h.imageContainer.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                width[0] = h.imageContainer.getWidth();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    h.imageContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                } else {
                    h.imageContainer.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }
            }
        });
        return width[0];
    }

the same logic is applied to the getContainerHeight(ViewHolder holder) method.

I have also tried it without a global listener on the tree observer and with a listener on the preDraw parameters.

observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                height[0] = h.imageContainer.getHeight();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    h.imageContainer.getViewTreeObserver().removeOnPreDrawListener(this);
                }
                return false;
            }
        });

Log:

E/measuredWidth&Height: 0.0 0.0
E/getPointX&Y: 70.13 88.00
E/x: x 0.0 y 0.0

Could there be a work around in regards to initializing the layout somewhere else and gathering the information and storing it somewhere? I've exhausted plenty of options. I just feel I haven't seen enough around Fragments and RecyclerViews within the SO community.

Any help will be appreciated.

like image 594
BIW Avatar asked Nov 11 '16 14:11

BIW


People also ask

What does getHeight() do?

getHeight. Returns the height of this Dimension in double precision. Returns: the height of this Dimension .

Where the width and height of the applet is specified?

The width and height of the applet are coded in the <applet> tag. The code that draws the applet uses the two methods to get these values at run time. So now, different <applet> tags can ask for the same applet to paint different sized rectangles.

What is the use of height field in applet code?

HEIGHT-specifies the height of the applet window. ALIGN-This could be set to LEFT, RIGHT, MIDDLE, TOP. HSPACE-Controls the horizontal space to the left and right of the applet.

What are the variables defined in dimension class?

Dimensional variables are those physical quantities which have dimensions of the form [M^a L^b T^c]… {where,M,L,T are fundamental physical quantities which are Mass,Length and Time respectively.


1 Answers

As @Enzokie mentioned you have to calculate your x and y inside callback after you will know width and height of your imageContainer. So all you need is to move your OnGlobalLayoutListener to onBindViewHolder method, like this:

@Override
public void onBindViewHolder(RecyclerViewHolderAllFeeds h, int position) {
    ...
    final ViewTreeObserver observer = h.imageContainer.getViewTreeObserver();
    observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                h.imageContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                h.imageContainer.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }

            int containerWidth = h.imageContainer.getWidth();
            int containerHeight = h.imageContainer.getHeight();
            float x = containerWidth - Float.parseFloat(model.getXpoints(o)) / 100 * containerWidth;
            float y = containerHeight - Float.parseFloat(model.getYpoints(o)) / 100 * containerHeight;
            Log.e("measuredWidth", "" + containerHeight + "" + containerWidth);
            Log.e("getPointX", "" + model.getXpoints(o) + "" + model.getYpoints(o));
            Log.e("x", "x" + x + "y" + y);

            h.tag.setX(x);
            h.tag.setY(y);
            h.tag.requestLayout();
        }
    });
    ...
}

Hope that helps!

like image 82
romtsn Avatar answered Nov 01 '22 22:11

romtsn