{"id":1289,"date":"2023-03-18T10:16:01","date_gmt":"2023-03-18T02:16:01","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=1289"},"modified":"2023-04-29T09:19:46","modified_gmt":"2023-04-29T01:19:46","slug":"introduction-to-using-butterknife-10-annotations-for-android","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/03\/18\/introduction-to-using-butterknife-10-annotations-for-android\/","title":{"rendered":"Android\u6ce8\u89e3\u4f7f\u7528\u4e4bButterKnife 10\u6ce8\u89e3\u4f7f\u7528\u4ecb\u7ecd"},"content":{"rendered":"<h2>ButterKnife\u4ecb\u7ecd<\/h2>\n<p>App\u9879\u76ee\u5f00\u53d1\u5927\u90e8\u5206\u65f6\u5019\u8fd8\u662f\u4ee5UI\u9875\u9762\u4e3a\u4e3b\uff0c\u8fd9\u65f6\u6211\u4eec\u9700\u8981\u8c03\u7528\u5927\u91cf\u7684findViewById\u4ee5\u53casetOnClickListener\u7b49\u4ee3\u7801\uff0c\u63a7\u4ef6\u7684\u5c11\u7684\u65f6\u5019\u6211\u4eec\u8fd8\u80fd\u63a5\u53d7\uff0c\u63a7\u4ef6\u591a\u8d77\u6765\u6709\u65f6\u5019\u5c31\u4f1a\u6709\u4e00\u79cd\u60f3\u7838\u952e\u76d8\u7684\u51b2\u52a8\u3002\u6240\u4ee5\u8fd9\u4e2a\u65f6\u5019\u6211\u4eec\u60f3\u7740\u53ef\u4ee5\u501f\u52a9\u6ce8\u89e3\u7684\u65b9\u5f0f\u8ba9\u6211\u4eec\u4ece\u8fd9\u79cd\u7e41\u91cd\u7684\u5de5\u4f5c\u4e2d\u8131\u79bb\u51fa\u6765\uff0c\u4e5f\u8ba9\u4ee3\u7801\u53d8\u5f97\u66f4\u52a0\u7b80\u6d01\uff0c\u4fbf\u4e8e\u7ef4\u62a4\uff0c\u4eca\u5929\u4e3b\u8981\u5b66\u4e60\u4e00\u4e0b\u53ea\u4e13\u6ce8View\u3001Resource\u3001Action\u6ce8\u89e3\u6846\u67b6ButterKnife\u3002<\/p>\n<p><!-- more --><\/p>\n<p>ButterKnife\u662f\u4e00\u4e2a\u4e13\u6ce8\u4e8eAndroid\u7cfb\u7edf\u7684View\u3001Resource\u3001Action\u6ce8\u5165\u6846\u67b6\u3002<\/p>\n<ul>\n<li>\u5b98\u7f51\uff1a<a target=\"_blank\" rel=\"noopener\" href=\"http:\/\/jakewharton.github.io\/butterknife\/\">http:\/\/jakewharton.github.io\/butterknife\/<\/a><\/li>\n<li>GitHub\uff1a<a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/github.com\/JakeWharton\/butterknife\/\">https:\/\/github.com\/JakeWharton\/butterknife\/<\/a><\/li>\n<\/ul>\n<h2>\u57fa\u672c\u4f7f\u7528<\/h2>\n<pre><code class=\"language-java\">public class ButterKnifeActivity extends AppCompatActivity {\n    private final static String TAG = ButterKnifeActivity.class.getSimpleName();\n    private Unbinder unbinder;\n    @BindString(R.string.butter_knife)\n    String butterKnifeStr;\n    @BindDrawable(R.mipmap.ic_launcher)\n    Drawable butterKnifeDrawable;\n    @BindView(R.id.btn_butter_knife)\n    Button butterKnifeBtn;\n    @BindView(R.id.iv_butter_knife)\n    ImageView butterKnifeIv;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_butter_knife);\n        unbinder = ButterKnife.bind(this);\n        initViews();\n    }\n\n    private void initViews() {\n        butterKnifeBtn.setText(butterKnifeStr);\n        butterKnifeIv.setImageDrawable(butterKnifeDrawable);\n    }\n\n    @OnClick(R.id.btn_butter_knife)\n    public void onButterKnifeBtnClick(View view) {\n        Log.e(TAG, &quot;onButterKnifeBtnClick&quot;);\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        unbinder.unbind();\n    }\n}<\/code><\/pre>\n<h2>ButterKnife\u4f18\u52bf<\/h2>\n<ul>\n<li>\u5f3a\u5927\u7684View\u7ed1\u5b9a\u548cClick\u4e8b\u4ef6\u5904\u7406\u529f\u80fd\uff0c\u7b80\u5316\u4ee3\u7801\uff0c\u63d0\u5347\u5f00\u53d1\u6548\u7387<\/li>\n<li>\u65b9\u4fbf\u7684\u5904\u7406Adapter\u91cc\u7684ViewHolder\u7ed1\u5b9a\u95ee\u9898<\/li>\n<li>\u8fd0\u884c\u65f6\u4e0d\u4f1a\u5f71\u54cdAPP\u6548\u7387\uff0c\u4f7f\u7528\u914d\u7f6e\u65b9\u4fbf<\/li>\n<li>\u4ee3\u7801\u6e05\u6670\uff0c\u53ef\u8bfb\u6027\u5f3a<\/li>\n<\/ul>\n<h2>ButterKnife\u4f7f\u7528<\/h2>\n<h3>\u5728Project\u7684build.gradle\u4e2d\u6dfb\u52a0\u914d\u7f6e<\/h3>\n<pre><code>buildscript {\n  repositories {\n    mavenCentral()\n    google()\n   }\n  dependencies {\n    classpath &#039;com.jakewharton:butterknife-gradle-plugin:10.2.0&#039;\n  }\n}<\/code><\/pre>\n<h3>\u5728Module\u7684build.gradle\u6dfb\u52a0\u914d\u7f6e<\/h3>\n<pre><code>apply plugin: &#039;com.android.library&#039;\napply plugin: &#039;com.jakewharton.butterknife&#039;\n\nandroid {\n  ...\n  \/\/ Butterknife requires Java 8.\n  compileOptions {\n    sourceCompatibility JavaVersion.VERSION_1_8\n    targetCompatibility JavaVersion.VERSION_1_8\n  }\n}\n\ndependencies {\n  implementation &#039;com.jakewharton:butterknife:10.2.0&#039;\n  annotationProcessor &#039;com.jakewharton:butterknife-compiler:10.2.0&#039;\n}<\/code><\/pre>\n<h3>\u6ce8\u5165\u548c\u91cd\u7f6e\u6ce8\u5165<\/h3>\n<h4>Activity<\/h4>\n<pre><code class=\"language-java\">class ExampleActivity extends Activity {\n  private Unbinder unbinder;\n  @BindView(R.id.title) TextView title;\n  @BindView(R.id.subtitle) TextView subtitle;\n  @BindView(R.id.footer) TextView footer;\n\n  @Override public void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.simple_activity);\n    ButterKnife.bind(this);\n    \/\/ TODO Use fields...\n  }\n\n  @Override protected void onDestroy() {\n    super.onDestroy();\n    unbinder.unbind();\n  }\n}<\/code><\/pre>\n<h4>Fragment<\/h4>\n<p>\u7531\u4e8e\u4e0d\u540c\u7684\u89c6\u56fe\u751f\u547d\u5468\u671f\uff0c\u6240\u4ee5\u9700\u8981\u5728onCreateView bind\uff0c\u5728onDestroyView unbind<\/p>\n<pre><code class=\"language-java\">public class FancyFragment extends Fragment {\n  @BindView(R.id.button1) Button button1;\n  @BindView(R.id.button2) Button button2;\n  private Unbinder unbinder;\n\n  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n    View view = inflater.inflate(R.layout.fancy_fragment, container, false);\n    unbinder = ButterKnife.bind(this, view);\n    \/\/ TODO Use fields...\n    return view;\n  }\n\n  @Override public void onDestroyView() {\n    super.onDestroyView();\n    unbinder.unbind();\n  }\n}<\/code><\/pre>\n<h4>ViewHolder<\/h4>\n<pre><code class=\"language-java\">public class MyAdapter extends BaseAdapter {\n  @Override public View getView(int position, View view, ViewGroup parent) {\n    ViewHolder holder;\n    if (view != null) {\n      holder = (ViewHolder) view.getTag();\n    } else {\n      view = inflater.inflate(R.layout.whatever, parent, false);\n      holder = new ViewHolder(view);\n      view.setTag(holder);\n    }\n\n    holder.name.setText(&quot;John Doe&quot;);\n    \/\/ etc...\n\n    return view;\n  }\n\n  static class ViewHolder {\n    @BindView(R.id.title) TextView name;\n    @BindView(R.id.job_title) TextView jobTitle;\n\n    public ViewHolder(View view) {\n      ButterKnife.bind(this, view);\n    }\n  }\n}<\/code><\/pre>\n<h4>view\u6ce8\u5165 @BindView\uff0c@BindViews<\/h4>\n<pre><code class=\"language-java\">@BindView(R.id.btn_butter_knife)\nButton butterKnifeBtn;\n@BindViews({R.id.tv_butter_knife1, R.id.tv_butter_knife2, R.id.tv_butter_knife3})\nList&lt;TextView&gt; textViews;<\/code><\/pre>\n<h4>Resource\u6ce8\u5165<\/h4>\n<pre><code class=\"language-java\">@BindString(R.string.title_btn_butter_knife)\nString butterKnifeStr;  \/\/string\u6ce8\u89e3\u4f7f\u7528\n@BindDrawable(R.mipmap.ic_launcher)\nDrawable butterKnifeDrawable;  \/\/Drawable\u6ce8\u89e3\u4f7f\u7528\n@BindBitmap(R.mipmap.ic_launcher)\nBitmap butterKnifeBitmap;;  \/\/Bitmap\u6ce8\u89e3\u4f7f\u7528\n@BindArray(R.array.day_of_week)\nString weeks[];  \/\/\u6570\u7ec4\n@BindColor(R.color.colorPrimary)\nint colorPrimary;  \/\/color\u6ce8\u89e3\u4f7f\u7528\n@BindDimen(R.dimen.activity_horizontal_margin)\nFloat spacer;<\/code><\/pre>\n<h4>\u5355\u4e8b\u4ef6\u6ce8\u5165<\/h4>\n<p>\u4e00\u4e2a\u63a7\u4ef6\u6307\u5b9a\u4e00\u4e2a\u4e8b\u4ef6\u56de\u8c03<\/p>\n<pre><code class=\"language-java\">\/**\n * \u4e0d\u5e26\u53c2\u6570\n *\/\n@OnClick(R.id.btn_butter_knife)\npublic void onButterKnifeBtnClick() {\n}\n\n\/**\n * \u5e26\u53c2\u6570\n *\/\n@OnClick(R.id.btn_butter_knife)\npublic void onButterKnifeBtnClick(View view) {\n  Log.e(TAG, &quot;onButterKnifeBtnClick&quot;);\n}\n\n\/**\n * \u5e26\u53c2\u6570\n * @param button\n *\/\n@OnClick(R.id.btn_butter_knife)\npublic void onButterKnifeBtnClick(Button button) {\n  Log.e(TAG, &quot;onButterKnifeBtnClick&quot;);\n}<\/code><\/pre>\n<p>\u4e5f\u53ef\u4ee5\u591a\u4e2a\u63a7\u4ef6\u6307\u5b9a\u4e00\u4e2a\u4e8b\u4ef6\u56de\u8c03<\/p>\n<pre><code class=\"language-java\">\/**\n * \u4e24\u4e2a\u4e0d\u540c\u7684button\u90fd\u76f8\u5e94onButterKnifeBtnClick\u4e8b\u4ef6\u56de\u8c03\n *\n * @param button\n *\/\n@OnClick({R.id.btn_butter_knife, R.id.btn_butter_knife1})\npublic void onButterKnifeBtnClick(Button button) {\n  Log.e(TAG, &quot;onButterKnifeBtnClick&quot;);\n}<\/code><\/pre>\n<p>\u81ea\u5b9a\u4e49\u7684\u63a7\u4ef6\u4e0d\u901a\u8fc7ID\u4e5f\u53ef\u4ee5\u7ed1\u5b9a\u5230\u81ea\u5df1\u7684\u4e8b\u4ef6<\/p>\n<pre><code class=\"language-java\">public class FancyButton extends Button {\n  @OnClick\n  public void onClick() {\n    \/\/ TODO do something!\n  }\n}<\/code><\/pre>\n<h4>\u591a\u4e8b\u4ef6\u56de\u8c03<\/h4>\n<p>\u6709\u4e00\u4e9bView\u7684listener\u662f\u6709\u591a\u4e2a\u56de\u8c03\u65b9\u6cd5\u7684\uff0c\u6bd4\u5982EditText\u6dfb\u52a0addTextChangedListener<\/p>\n<pre><code class=\"language-java\">editText.addTextChangedListener(new TextWatcher() {\n  @Override\n  public void beforeTextChanged(CharSequence s, int start, int count, int after) {\n\n  }\n\n  @Override\n  public void onTextChanged(CharSequence s, int start, int before, int count) {\n\n  }\n\n  @Override\n  public void afterTextChanged(Editable s) {\n\n  }\n});<\/code><\/pre>\n<p>\u53ef\u4ee5\u4f7f\u7528\u6ce8\u89e3\u65b9\u5f0f\u6539\u6210\u5982\u4e0b<\/p>\n<pre><code class=\"language-java\">@OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED)\nvoid beforeTextChanged(CharSequence s, int start, int count, int after) {\n\n}\n@OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.TEXT_CHANGED)\nvoid onTextChanged(CharSequence s, int start, int before, int count) {\n\n}\n@OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)\nvoid afterTextChanged(Editable s) {\n\n}<\/code><\/pre>\n<h4>\u9009\u62e9\u6027\u6ce8\u5165<\/h4>\n<p>\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cBind\u548clistener\u7684\u6ce8\u5165\u90fd\u662f\u5fc5\u987b\u7684\uff0c\u5982\u679ctarget view\u6ca1\u6709\u88ab\u53d1\u73b0\uff0c\u5219\u4f1a\u62a5\u9519\u3002\u4e3a\u4e86\u6291\u5236\u8fd9\u79cd\u884c\u4e3a\uff0c\u53ef\u4ee5\u7528<code>@Optional<\/code>\u6ce8\u89e3\u6765\u6807\u8bb0field\u548c\u65b9\u6cd5\uff0c\u8ba9\u6ce8\u5165\u53d8\u6210\u9009\u62e9\u6027\u7684\uff0c\u5982\u679ctargetView\u5b58\u5728\uff0c\u5219\u6ce8\u5165\uff0c\u4e0d\u5b58\u5728\uff0c\u5219\u4ec0\u4e48\u4e8b\u60c5\u90fd\u4e0d\u505a\u3002\u6216\u8005\u4f7f\u7528<code>Android&#039;s &quot;support-annotations&quot; library<\/code>\u4e2d\u7684<code>@Nullable<\/code>\u6765\u4fee\u9970<\/p>\n<pre><code class=\"language-java\">@Nullable @BindView(R.id.might_not_be_there)\nTextView mightNotBeThere;\n\n@Optional @OnClick(R.id.maybe_missing) \nvoid onMaybeMissingClicked() {\n  \/\/ TODO ...\n}<\/code><\/pre>\n<h4>ButterKnife.apply()\u51fd\u6570<\/h4>\n<p>\u53ef\u4ee5\u901a\u8fc7<code>ButterKnife.apply()<\/code>\u51fd\u6570\u5bf9view\u96c6\u5408\u5143\u7d20\u6216\u8005\u5355\u4e2aview\u7684Action\u3001Setter\u548cProperty\u8fdb\u884c\u4fee\u6539<\/p>\n<blockquote>\n<p>\u6ce8\uff1a10.0\u53ca\u4ee5\u4e0a\u7248\u672c\u5df2\u5e9f\u5f03<\/p>\n<\/blockquote>\n<pre><code class=\"language-java\">ButterKnife.apply(nameViews, DISABLE);\nButterKnife.apply(nameViews, ENABLED, false);\n\nstatic final ButterKnife.Action&lt;View&gt; DISABLE = new ButterKnife.Action&lt;View&gt;() {\n  @Override public void apply(View view, int index) {\n    view.setEnabled(false);\n  }\n};\nstatic final ButterKnife.Setter&lt;View, Boolean&gt; ENABLED = new ButterKnife.Setter&lt;View, Boolean&gt;() {\n  @Override public void set(View view, Boolean value, int index) {\n    view.setEnabled(value);\n  }\n};\n\nButterKnife.apply(nameViews, View.ALPHA, 0.0f);<\/code><\/pre>\n<h4>ButterKnife.findById()<\/h4>\n<p>ButterKnife \u4e5f\u63d0\u4f9b\u4e86findById\u51fd\u6570\uff0c\u901a\u8fc7findById()\u53ef\u4ee5\u83b7\u53d6Activity\u3001Dialog\u3001View\u4e2d\u7684view\uff0c\u5e76\u4e14\u662f\u6cdb\u578b\u7c7b\u578b\u4e0d\u9700\u8981\u5f3a\u8f6c<\/p>\n<blockquote>\n<p>\u6ce8\uff1a10.0\u53ca\u4ee5\u4e0a\u7248\u672c\u5df2\u5e9f\u5f03<\/p>\n<\/blockquote>\n<pre><code>View view = LayoutInflater.from(context).inflate(R.layout.thing, null);\nTextView firstName = ButterKnife.findById(view, R.id.first_name);\nTextView lastName = ButterKnife.findById(view, R.id.last_name);\nImageView photo = ButterKnife.findById(view, R.id.photo);<\/code><\/pre>\n<h3>ButterKnife\u81ea\u52a8\u751f\u6210\u63d2\u4ef6\u5b89\u88c5\uff1a<\/h3>\n<p>\u5728<code>Android Studio<\/code> -&gt; <code>File<\/code> -&gt; <code>Settings<\/code> -&gt; <code>Plugins<\/code> -&gt; \u641c\u7d22<code>Zelezny<\/code>\u4e0b\u8f7d\u6dfb\u52a0\u5373\u53ef\uff0c\u53ef\u4ee5\u5feb\u901f\u751f\u6210\u5bf9\u5e94\u7ec4\u4ef6\u7684\u5b9e\u4f8b\u5bf9\u8c61\uff0c\u4e0d\u7528\u624b\u52a8\u5199\u3002\u4f7f\u7528\u65f6\uff0c\u5728\u8981\u5bfc\u5165\u6ce8\u89e3\u7684Activity \u6216 Fragment \u6216 ViewHolder\u7684layout\u8d44\u6e90\u4ee3\u7801\u4e0a\uff0c\u53f3\u952e -&gt; <code>Generate<\/code> -&gt; <code>Generate ButterKnife Injections<\/code>\u3002<\/p>\n<p>\u63d2\u4ef6\u5730\u5740\uff1a<a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/github.com\/avast\/android-butterknife-zelezny\">https:\/\/github.com\/avast\/android-butterknife-zelezny<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>ButterKnife\u4ecb\u7ecd App\u9879\u76ee\u5f00\u53d1\u5927\u90e8\u5206\u65f6\u5019\u8fd8\u662f\u4ee5UI\u9875\u9762\u4e3a\u4e3b\uff0c\u8fd9\u65f6\u6211\u4eec\u9700\u8981\u8c03\u7528\u5927\u91cf\u7684findView [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[117],"tags":[],"class_list":["post-1289","post","type-post","status-publish","format-standard","hentry","category-butterknife"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1289","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=1289"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1289\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=1289"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=1289"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=1289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}