Search code examples
javaandroidlayoutwidthlayoutparams

How to get the actual width of view in values in any adapter class if it is define as match parent in xml file in Android


How can I get width in values for any layout or card view inside an adapter class? I have a layout file which I am using for a custom adapter class, where I had taken a view that is card view and given width as match parent now in adapter class I want card view width in values. I have tried multiple methods, for example, using post method with card view or view tree observer.

CardView mCardView;
int width=0;
int rootWidth,rootHeight;
mCardView = itemview.findViewById(R.id.mCardView);

// Method in Recyclerview Adapter Class
public void onBindHolder(final ViewHolder holder, final int position)
{
    // using viewtreeobserver to get width of view 
    ViewTreeObserver vto = mCardView.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new 
        ViewTreeObserver.OnGlobalLayoutListener()
            {
                @Override
                public void onGlobalLayout() {
                    rootHeight = mCardView.getHeight();
                    rootWidth = mCardView.getWidth();
                }
            });
    }

    //Another method tried to get the width of the view 

    mCardView.post(new Runnable() {
        @Override
        public void run() {
            rootHeight = mCardView.getHeight();
            rootWidth = mCardView.getWidth();
        }
    });

     width = rootWidth;  //always return 0 in both th cases

}

Solution

  • Reason you're getting null value.

    For this i'll provide example :

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            holder.card?.viewTreeObserver?.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener{
                override fun onGlobalLayout() {
                    holder.card?.getViewTreeObserver()?.removeGlobalOnLayoutListener(this);
                    Log.e("widths", holder.card?.measuredWidth.toString())
                }
            })
            Log.e("text","i am here")
        }
    

    Output of this code is :

    E/text: i am here
    E/text: i am here
    E/widths: 1080
    E/widths: 1080
    

    as per example you can see my text Log runs before getting width. The reason behind is my bindviewholder is in progress to set the data to view. After process complete it will provide proper value of my width.

    Same issue happening with you. as you commented you're values return 0 outside function. it because outside the function your onbindviewholder in process.

    Better method for you're problem is

    You can use SharedPreferences to store your width in Local. For explanation you can check this answer he provided proper way to do it.

    If there's anything i can help just comment your problem