5

I want to use a ViewStub with ButterKnife, This is what I've done:

public class ExampleFragment extends Fragment {

    @InjectView ( R.id.stub )
    ViewStub mStub;

    /* A TextView in the ViewStub */
    @InjectView ( R.id.text )
    @Optional
    TextView mText;

    @Override
    public View onCreateView ( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {

        View rootView = inflater.inflate ( R.layout.rootview, container, false );
        ButterKnife.inject ( this, rootView );

        mStub.setLayoutResource ( R.layout.stub_layout );
        View inflated = mStub.inflate ();
        ButterKnife.inject ( mStub, inflated );

        mText.setText("test.");    

        return rootView;
    }
}

and the log says:

mText is a null object reference

I have no idea now, any advice is welcome. Thanks!

RockerFlower
  • 727
  • 2
  • 10
  • 28
  • 1
    Try `View inflated = mStub.inflate (); ButterKnife.inject (this, inflated );` – Nikola Despotoski Dec 26 '14 at 04:12
  • @NikolaDespotoski I've tried, and this injection replaced the first injection `ButterKnife.inject ( this, rootView );`, so `mStub` becomes null. Now I use `TextView mText = ( TextView ) inflated.findViewById ( R.id.text );` instead :( Thanks anyway! – RockerFlower Dec 26 '14 at 04:18
  • @RockerFlower, why you need the ViewStub object after load its layout, anyway? – Renascienza Sep 25 '15 at 00:42

2 Answers2

7

You can create a nested class which holds the views inside the stub.

public class ExampleFragment extends Fragment {

    @InjectView ( R.id.stub )
    ViewStub mStub;

    @Override
    public View onCreateView ( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {

        View rootView = inflater.inflate ( R.layout.rootview, container, false );
        ButterKnife.inject ( this, rootView );

        mStub.setLayoutResource ( R.layout.stub_layout );
        View inflated = mStub.inflate ();
        MyStubView stubView = new MyStubView(inflated); 
        stubView.mText.setText("test.");    

        return rootView;
    }

    // class (inner in this example) that has stuff from your stub
    public class MyStubView {
        @InjectView(R.id.text)
        TextView mText;

        public MyStubView(View view) {
            Butterknife.inject(this, view);
        }
    }
}
JChord
  • 128
  • 1
  • 7
4

Here is the answer from Jake for this request:

Create a nested class which holds the views inside the stub and then call inject on an instance of that class using the viewstub as the root.

For code refer to this Github issue.

CodeFury
  • 1,520
  • 16
  • 29