DEBUG/Tools

Android Butter Knife 적용하기

에디83 2017. 2. 4. 00:18

Android Activity를 개발 할 때 제일 먼저 하는 일이 무엇일까?


바로 새로운 Layout을 만들어서 적용하고 Layout에 포함되어 있는 view에 event listener를 달아주거나

view들을 읽어와서 business logic에 맞게 개발을 할 것이다.

 

Layout에 포함된 view에 접근하기 위해서는 아래와 같이 작업을 하게 된다.


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

ImageView settingsImage = (ImageView) findViewById(R.id.image_settings);
LinearLayout referencerLayout = (LinearLayout) findViewById(R.id.layout_reference);
TextView helloWorldText1 = (TextView) findViewById(R.id.text_hello_world1);
TextView helloWorldText2 = (TextView) findViewById(R.id.text_hello_world2);
TextView helloWorldText3 = (TextView) findViewById(R.id.text_hello_world3);
TextView helloWorldText4 = (TextView) findViewById(R.id.text_hello_world4);
TextView helloWorldText5 = (TextView) findViewById(R.id.text_hello_world5);
TextView helloWorldText6 = (TextView) findViewById(R.id.text_hello_world6);
TextView helloWorldText7 = (TextView) findViewById(R.id.text_hello_world7);
}


물론 간단한 화면은 사용되는 view가 적기 때문에 해당이 되진 않겠지만

10개이상 넘어가게 되면 쓰기에도 불편하고 소스 라인도 늘어나게 되고 가독성도 떨어지게 된다.

이부분을 해결하기 위해 annotation을 활용하여 view를 injection하는 plugin을 사용해보자


butterknife라는 plugin이며 공식 홈페이지는 아래와 같다

http://jakewharton.github.io/butterknife/



먼저 build.gradle에 추가한다.

//for Butter Knife
compile 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'


그리고 

ButterKnife.bind를 호출해준다.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}


그리고

view객체를 선언할때 아래 처럼 annotation을 지정해준다.

@BindView(R.id.image_settings)
ImageView settingsImage;

@BindView(R.id.layout_reference)
LinearLayout referencerLayout;

@BindView(R.id.text_hello_world1)
TextView helloWorldText1;


이렇게만 하면 된다. 복잡하게 findViewById를 하지 않아도 view를 이용할 수 있다.



그외

리소스에 대한 바인딩도 할 수 있으며


RESOURCE BINDING

Bind pre-defined resources with @BindBool@BindColor@BindDimen@BindDrawable@BindInt@BindString, which binds an R.bool ID (or your specified type) to its corresponding field.

class ExampleActivity extends Activity {
  @BindString(R.string.title) String title;
  @BindDrawable(R.drawable.graphic) Drawable graphic;
  @BindColor(R.color.red) int red; // int or ColorStateList field
  @BindDimen(R.dimen.spacer) Float spacer; // int (for pixel size) or float (for exact value) field
  // ...
}

Activity가 아닌 곳에서는 아래와 같이 view를 넘겨줘서 바인딩 할 수 있고


public class FancyFragment extends Fragment {
  @BindView(R.id.button1) Button button1;
  @BindView(R.id.button2) Button button2;

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fancy_fragment, container, false);
    ButterKnife.bind(this, view);
    // TODO Use fields...
    return view;
  }
}
static class ViewHolder {
    @BindView(R.id.title) TextView name;
    @BindView(R.id.job_title) TextView jobTitle;

    public ViewHolder(View view) {
      ButterKnife.bind(this, view);
    }
  }

Listener도 바로 바인딩할 수있다.

LISTENER BINDING

Listeners can also automatically be configured onto methods.

@OnClick(R.id.submit)
public void submit(View view) {
  // TODO submit data to server...
}

이 외에 기능도 많으니 공식홈페이지에서 확인을 하면 된다.

마지막으로 주의해야 할 점은 반드시 bind할 view를 먼저 생성하고 bind를 해야하는 점이다.

(예를 들어 setContentView를 먼저 호출하고 bind를 해야한다.)


순서가 바뀌게 되면 Runtime Exception이 발생하게 된다.