you786
you786

Reputation: 3550

Using View.getParent() in View's constructor

Why doesn't this work?

private ScrollView findScrollParent(View v)
{

    if(v==null)
    {
        return null;
    }
    else if(v instanceof ScrollView)
    {
        return (ScrollView) v;
    }
    else
    {
        return findScrollParent((View)v.getParent());
    }
}

CustomView(Context context, AttributeSet as)
{
     super(context,as);
     ScrollView sv = findScrollParent(this);
}

This is my xml file which is inflated:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent">
<ScrollView
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">

  <LinearLayout android:layout_height="wrap_content"
        android:layout_width="wrap_content">

       <com.myapp.CustomView android:layout_height="wrap_content"
               android:layout_width="wrap_content"/>

  </LinearLayout>

</ScrollView>
</RelativeLayout>

I want to have a reference to the scrollView in the custom View. My findScrollParent method finds the LinearLayout then returns null. I call this method in the View v's constructor, is that the problem?

Upvotes: 7

Views: 14936

Answers (2)

LanDenLabs
LanDenLabs

Reputation: 1656

You can safely access your parent in onAttachedToWindow() method.

See View Life Cycle.

Upvotes: 15

Paul.s
Paul.s

Reputation: 38728

If you are calling it in the view's constructor then surely it will not have it's parent assigned yet?

As far as I can see from skimming the source the parent attribute is not set until the view is added to the parent at which point it will do something like:

child.mParent = this;

So if you are in the constructor for the view then my guess is it is too early and the view will be added after it is constructed. I was not 100% sure what combination of classes you were talking about / how you had them fitting together so may have looked at the wrong source.

EDIT

Just to clarify with pseudo code the process might look like this

View view = new View();  // Inside here you are calling your method - which won't work
addView(view);           // The parent is only just being set as a result of this method
view.getParent();        // At this point we can now return the expected result

EDIT 2 - @codelark 's suggestion

private _scrollView; // member variable

private ScrollView getScrollView()
{
   if (null == _scrollView) {
       _scrollView = findScrollParent(this);
   }
   return _scrollView;
}

Upvotes: 4

Related Questions