findViewById() returns null for custom component in layout XML, not for other components

前端 未结 18 1428
情歌与酒
情歌与酒 2020-11-28 10:36

I have a res/layout/main.xml including these elements and others:



        
相关标签:
18条回答
  • 2020-11-28 11:30

    I ran into the same issue a while back when I added a custom View via the layout XML and then tried to attached a callback elsewhere in the application ...

    I created a custom view and added it to my "layout_main.xml"

    public class MUIComponent extends SurfaceView implements SurfaceHolder.Callback {
        public MUIComponent (Context context, AttributeSet attrs ) {
            super ( context, attrs );
        }
        // ..
    }
    

    And in the main Activity I wanted to attach some callbacks and get references to the UI elements from the XML.

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // ...
    
            MUIInitializer muiInit = new MUIInitializer();
            muiInit.setupCallbacks(this);
            muiInit.intializeFields(this);
        }       
    }
    

    The initilizer wasn't doing anything fancy but any changes it tried to make to the custom view (MUIComponent) or other non-custom UI elements simply were not appearing in the application.

    public class MUIInitializer {
    
        // ...
    
        public void setupCallbacks ( Activity mainAct ) {
    
    
            // This does NOT work properly
            // - The object instance returned is technically an instance of my "MUICompnent" view
            //   but it is a *different* instance than the instance created and shown in the UI screen
            // - Callbacks never get triggered, changes don't appear on UI, etc.
            MUIComponent badInst = (MUIComponent) mainAct.findViewById(R.id.MUIComponent_TESTSURF);
    
    
            // ...
            // This works properly
    
            LayoutInflater inflater = (LayoutInflater) mainAct.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View inflatedLayout = inflater.inflate ( R.layout.activity_main, null );
    
            MUIComponent goodInst = (MUIComponent) inflatedLayout.findViewById(R.id.MUIComponent_TESTSURF);
    
    
            // Add callbacks
            // ...
        }
    
    }
    

    The difference between the "badInst" and "goodInst" is:

    • badInst uses the Activity's findViewByID
    • goodInst inflates the layout and uses the inflated layout to do the lookup
    0 讨论(0)
  • 2020-11-28 11:33

    I had the same problem. My mistake was that: I wrote

            LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View layout=inflater.inflate(R.layout.dlg_show_info, null);
            alertDlgShowInfo.setView(layout);
            TableRow trowDesc=(TableRow)findViewById(R.id.trowDesc);
    

    and as I used an inflater to "load" the view from an XML file, the last line was wrong. To solve it, I had to write:

    TableRow trowDesc=(TableRow)layout.findViewById(R.id.trowDesc);
    

    I wrote my solution, in case someone have the same problem.

    0 讨论(0)
  • 2020-11-28 11:33

    In my case findViewById was returning null because my custom view looked something like this in the main XML:

            <com.gerfmarquez.seekbar.VerticalSeekBar  
                android:id="@+id/verticalSeekBar"
                android:layout_width="wrap_content" 
                android:layout_height="fill_parent" 
                />
    

    and I found out that when I added the xmlns stuff it worked like this:

            <com.gerfmarquez.seekbar.VerticalSeekBar  
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/verticalSeekBar"
                android:layout_width="wrap_content" 
                android:layout_height="fill_parent" 
                />
    
    0 讨论(0)
  • 2020-11-28 11:33

    The findViewById() method sometimes returns null when the root of layout has no android:id attribute. Eclipse wizard for generating layout xml file does not automatically generate android:id attribute for the root element.

    0 讨论(0)
  • 2020-11-28 11:34

    This happened to me with a custom component for Wear, but is a generic piece of advice. If you're using a Stub (such as I was using WatchViewStub), you can't just put the call to findViewById() anywhere. Everything inside the stub must be inflated first, which doesn't just happen after setContentView(). Thus, you should write something like this in order to wait for that to happen:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wear);
        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override
            public void onLayoutInflated(WatchViewStub stub) {
                myCustomViewInst = (MyCustomView) findViewById(R.id.my_custom_view);
                ...
    
    0 讨论(0)
  • 2020-11-28 11:36

    i had the same problem because i forgot to update the view id in all my layout folders.

    0 讨论(0)
提交回复
热议问题