Butterknife: Can be used with ViewStub ?

Created on 9 Jan 2015  路  7Comments  路  Source: JakeWharton/butterknife

Hi, it can be used with viewstub? I have my entire application with this library, and i need use a viewstub in many fragments...great library by the way...

greetings.

Most helpful comment

@seba123neo, create a class that has txtDontWork1, txtDontWork2. In the main class have reference to your view stub. When you inflate your viewstub pass that resulting one to that another class. For example:

public class EstadoActual extends Fragment { 

    // this controls work perfect 
    @InjectView(R.id.txtWork1) AutoCompleteTextView txtWork1;
    @InjectView(R.id.txtWork2) EditText txtWork2;

    // this controls are inside the viewstub,
    @InjectView(R.id.viewstub) ViewStub viewStub;

      MyDynamicView  myDynamicView;
.. .. ...
    // class (inner in this example) that has stuff from your stub
    public class MyDynamicView {
      @InjectView(R.id.txtDontWork1) EditText txtDontWork1;
      @InjectView(R.id.txtDontWork1) EditText txtDontWork2;
       public MyDynamicView(View view) {
         Butterknife.inject(this, view);
       }
    }

   @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.festadoactual, container, false);
        ButterKnife.inject(this, rootView);
      ... ..
        View viewFromStub = viewStub.inflate();  
        myDynamicView = new MyDynamicView(viewFromStub); // this is the main point where you configure your view
        Fill(); 
        return rootView;
    } 

   private void Fill(){ 
        txtWork1.setText("Hello 1");
       txtWork2.setText("Hello 2");

        myDynamicView.txtDontWork1.setText("Don't Work 1"); // This should work for you now
        myDynamicView.txtDontWork2.setText("Don't Work 2");
    } 

All 7 comments

As in, you want to inject a ViewStub? Or you want to inject the views inside of the ViewStub?

yes, I need to access the controls that are inside the viewstub, but throws me an error when I want to use any of the controls inside the viewstub because the @InjectView cannot find them.

Well they aren't in the layout so it correct throws an error. 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.

ok, you could show me how? I made this code example of what I have in my application, obviously is not the original code of my app, because the original has 20 EditText controls.

public class EstadoActual extends Fragment {

    // this controls work perfect
    @InjectView(R.id.txtWork1) AutoCompleteTextView txtWork1;
    @InjectView(R.id.txtWork2) EditText txtWork2;

    // this controls are inside the viewstub, don't work
    @InjectView(R.id.txtDontWork1) EditText txtDontWork1;
    @InjectView(R.id.txtDontWork1) EditText txtDontWork2;

    public static EstadoActual newInstance() {
        EstadoActual fragment = new EstadoActual();
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.festadoactual, container, false);
        ButterKnife.inject(this, rootView);
        Fill();
        return rootView;
    }

    private void Fill(){
        txtWork1.setText("Hello 1");
        txtWork2.setText("Hello 2");

        txtDontWork1.setText("Don't Work 1"); // when i use @Optional in the two edittext, the "inject" works, but throw an error Here
        txtDontWork2.setText("Don't Work 2");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        ButterKnife.reset(this);
    }
}

Any help ?

@seba123neo, create a class that has txtDontWork1, txtDontWork2. In the main class have reference to your view stub. When you inflate your viewstub pass that resulting one to that another class. For example:

public class EstadoActual extends Fragment { 

    // this controls work perfect 
    @InjectView(R.id.txtWork1) AutoCompleteTextView txtWork1;
    @InjectView(R.id.txtWork2) EditText txtWork2;

    // this controls are inside the viewstub,
    @InjectView(R.id.viewstub) ViewStub viewStub;

      MyDynamicView  myDynamicView;
.. .. ...
    // class (inner in this example) that has stuff from your stub
    public class MyDynamicView {
      @InjectView(R.id.txtDontWork1) EditText txtDontWork1;
      @InjectView(R.id.txtDontWork1) EditText txtDontWork2;
       public MyDynamicView(View view) {
         Butterknife.inject(this, view);
       }
    }

   @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.festadoactual, container, false);
        ButterKnife.inject(this, rootView);
      ... ..
        View viewFromStub = viewStub.inflate();  
        myDynamicView = new MyDynamicView(viewFromStub); // this is the main point where you configure your view
        Fill(); 
        return rootView;
    } 

   private void Fill(){ 
        txtWork1.setText("Hello 1");
       txtWork2.setText("Hello 2");

        myDynamicView.txtDontWork1.setText("Don't Work 1"); // This should work for you now
        myDynamicView.txtDontWork2.setText("Don't Work 2");
    } 

Yep yep. What @manijshrestha said!

Was this page helpful?
0 / 5 - 0 ratings