12/08/2018, 16:13

Làm việc với thư viện BindingView ButterKnife trong Android

Thư viện Android ButterKnife là một thư viện view injection nó tác động đến các view trong activity, fragment bằng việc sử dụng annotations. Ví dụ: annotation @BindView được dùng để tránh sử dụng phương thức findViewById () Không chỉ view binding, butterknife cung cấp rất nhiều các tùy chọn hữu ...

Thư viện Android ButterKnife là một thư viện view injection nó tác động đến các view trong activity, fragment bằng việc sử dụng annotations. Ví dụ: annotation @BindView được dùng để tránh sử dụng phương thức findViewById ()

Không chỉ view binding, butterknife cung cấp rất nhiều các tùy chọn hữu ích khác như binding strings, dimens, drawables, click events.... Chúng ta sẽ tìm hiểu về mọi thành phần được đưa ra trong bài viết này.

Điều đầu tiên bạn phải làm là thêm ButterKnife trong dự án của bạn bằng cách thêm dependencies bên dưới vào tệp tin app / build.gradle của dự án. Sau khi được thêm vào, chúng ta đồng bộ dự án

dependencies {
    ...
 
    // butter knife
    compile 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}

Sau khi thêm dependency, tất cả các butterknife annotations sẽ có sẵn để import. Để bắt đầu, chúng ta sẽ thấy cách sử dụng annotations @BindView và @OnClick.

Giả sử bạn có layout như ở dưới cho activity có TextView và một Button.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_awidth="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical">
 
    <TextView
        android:id="@+id/lbl_title"
        android:layout_awidth="wrap_content"
        android:layout_height="wrap_content"
        android:text="Enter your email"
        android:textAllCaps="true" />
 
    <EditText
        android:id="@+id/input_name"
        android:layout_awidth="match_parent"
        android:layout_height="wrap_content" />
 
    <Button
        android:id="@+id/btn_enter"
        android:layout_awidth="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/dimen_20"
        android:text="@string/enter" />
</LinearLayout>

Để làm cho các views có sẵn trong activity, chúng ta cần làm theo các bước dưới đây.

Bước 1. Sử dụng @BindView cùng với id (R.id.lbl_title) của view trong khi khai báo biến.

Bước 2. Gọi ButterKnife.bind (this) trong phương thức onCreate () sau khi gọi setContentView ().

View trong layout sẽ được kết nối với biến view mà không cần cách sử dụng phương thức findViewById () nữa. Ngoài ra bạn có thể thấy, sự kiện click được đính kèm bằng cách thêm annotation @OnClick trước phương thức.

public class MainActivity extends AppCompatActivity {
 
    @BindView(R.id.lbl_title)
    TextView lblTitle;
 
    @BindView(R.id.input_name)
    EditText inputName;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // bind the view using butterknife
        ButterKnife.bind(this);
    }
 
    @OnClick(R.id.btn_enter)
    public void onButtonClick(View view) {
        Toast.makeText(getApplicationContext(), "You have entered: " + inputName.getText().toString(),
                Toast.LENGTH_SHORT).show();
    }
}

Sử dụng injection các view trong Fragment giống với Activity trừ phương thức ButterKnife.bind () thay đổi. Ngoài tham số đích, chúng ta cần có tham số để vượt qua inflated view.

Bạn cũng sẽ phải sử dụng Unbinder để unbind view trong onDestroyView () vì các nó thuộc vòng đời của Fragment.

Dưới đây là ví dụ sử dụng ButterKnife trong Fragment.

public class MyFragment extends Fragment {
 
    Unbinder unbinder;
 
    @BindView(R.id.lbl_name)
    TextView lblName;
 
    @BindView(R.id.btn_enter)
    Button btnEnter;
 
    @BindView(R.id.input_name)
    EditText inputName;
 
    public MyFragment() {
        // Required empty public constructor
    }
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
    }
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_my, container, false);
 
        // bind view using butter knife
        unbinder = ButterKnife.bind(this, view);
 
        return view;
    }
 
    @Override
    public void onDestroyView() {
        super.onDestroyView();
 
        // unbind the view to free some memory
        unbinder.unbind();
    }
}

ButterKnife cũng có thể được sử dụng trong list adapters . Dưới đây là ví dụ về @BindView trong class adapter của recyclerview

public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.MyViewHolder> {
 
    private List<Contact> contacts;
 
    public class MyViewHolder extends RecyclerView.ViewHolder {
 
        @BindView(R.id.name)
        TextView name;
 
        @BindView(R.id.mobile)
        TextView mobile;
 
        public MyViewHolder(View view) {
            super(view);
 
            // binding view
            ButterKnife.bind(this, view);
        }
    }
 
    public ContactsAdapter(List<Contact> contacts) {
        this.contacts = contacts;
    }
 
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.contact_list_row, parent, false);
 
        return new MyViewHolder(itemView);
    }
 
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Contact contact = contacts.get(position);
        holder.name.setText(contact.getName());
        holder.mobile.setText(contact.getMobile());
    }
 
    @Override
    public int getItemCount() {
        return contacts.size();
    }
}

Ngoài việc có thể binding view, bạn cũng có thể bind các tài nguyên khác như string (@BindString), màu sắc (@BindColor), kích thước (@BindDimen) và bản vẽ (@BindDrawable).

Ví dụ dưới đây là mẫu cho nhiều annotations và cách sử dụng chúng.

public class MainActivity extends AppCompatActivity {
    @BindView(R.id.logo)
    ImageView imgLogo;
 
    @BindView(R.id.lbl_title)
    TextView lblTitle;
 
    @BindDrawable(R.mipmap.ic_launcher)
    Drawable drawableLogo;
 
    @BindColor(R.color.colorPrimaryDark)
    int colorTitle;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // bind the view using butterknife
        ButterKnife.bind(this);
 
        // setting label color
        lblTitle.setTextColor(colorTitle);
 
        // displaying logo using drawable
        imgLogo.setImageDrawable(drawableLogo);
    }
}

Ví dụ về annotation của @OnClick

// click event with source view params
@OnClick(R.id.btn_enter)
public void onButtonClick(View view) {
    Toast.makeText(getApplicationContext(), "You have entered: " + inputName.getText().toString(),
            Toast.LENGTH_SHORT).show();
}
 
 
// click event without params
@OnClick(R.id.btn_enter)
public void onButtonClick() {
    Toast.makeText(getApplicationContext(), "You have entered: " + inputName.getText().toString(),
            Toast.LENGTH_SHORT).show();
}
 
 
// click event with specific type param
@OnClick(R.id.btn_enter)
public void onButtonClick(Button button) {
    Toast.makeText(getApplicationContext(), "You have entered: " + inputName.getText().toString(),
            Toast.LENGTH_SHORT).show();
}

Có thể có các tình huống mà trong đó bạn muốn áp dụng một số action đối với group view, như áp dụng màu sắc, văn bản cài đặt hoặc chọn tất cả cùng một lúc. Điều này có thể được thực hiện rất dễ dàng bằng cách sử dụng ButterKnife.

Tất cả những điều làm là sử dụng chú thích @BindViews để lưu tất cả các chế độ xem vào danh sách và sử dụng phương thức ButterKnife.Action () để áp dụng một số thao tác cho tất cả các view.

Trong ví dụ dưới đây là hai action được áp dụng cho group các TextViews. Đầu tiên, text đc set từ một dãy các chuỗi. Thứ hai, màu sắc được áp dụng cho tất cả các TextViews trong danh sách.

public class MainActivity extends AppCompatActivity {
    @BindColor(R.color.colorPrimaryDark)
    int colorTitle;
 
    @BindViews({R.id.lbl1, R.id.lbl2, R.id.lbl3})
    List<TextView> lblArray;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // bind the view using butterknife
        ButterKnife.bind(this);
 
        final String[] lblText = new String[]{"Cat", "Dog", "Rat"};
 
        ButterKnife.Action<TextView> APPLY_TEXT = new ButterKnife.Action<TextView>() {
            @Override
            public void apply(TextView view, int index) {
                view.setText(lblText[index]);
            }
        };
 
        // setting text to array of labels
        ButterKnife.apply(lblArray, APPLY_TEXT);
 
        // Applying color to group of labels
        ButterKnife.Action<TextView> APPLY_COLOR = new ButterKnife.Action<TextView>() {
            @Override
            public void apply(@NonNull TextView view, int index) {
                view.setTextColor(colorTitle);
            }
        };
 
        ButterKnife.apply(lblArray, APPLY_COLOR);
    }
}

Dưới đây là lisr các annotations đc cung cấp bởi ButterKnife mà chúng ta có thể sử dụng

Annotation	Description
@BindView	Binds view object. TextView, Button, Spinner or any view object
@BindView(R.id.logo)
ImageView imgLogo;
@BindViews	Binds array of views into List
@BindViews({R.id.lbl_name, R.id.lbl_email, R.id.lbl_address})
List<TextView> lblArray;
@BindDrawable	Binds drawable element. Loads the drawable image from res folder
@BindDrawable(R.mipmap.ic_launcher)
Drawable drawableLogo;
@BindString	Binds string resource
@BindString(R.string.app_name)
String appName;
@BindColor	Binds color resource
@BindColor(R.color.colorPrimaryDark)
int colorTitle;
@BindDimen	Binds dimen resource
@BindDimen(R.id.padding_hori)
float paddingHorizontal;
@BindAnim	Binds animation from anim resource
@BindAnim(R.anim.move_up)
Animation animMoveUp;
@BindBitmap	Binds bitmap object.
@BindBitmap(R.mipmap.ic_launcher)
Bitmap logo;
@BindFont	Binds font resource
@BindViews({R.id.lbl_name, R.id.lbl_email, R.id.lbl_address})
List<TextView> lblArray;
@BindFloat	Binds float value
@BindFloat(R.dimen.radius)
float radius;
@BindInt	Binds int resource
@BindInt(R.integer.distance)

Source

0