一、配置:ButterKnife最新9.0 按照官网上的配置会出错
Error:(2, 0) Android Gradle plugin 3.1.4 must not be applied to project 'F:MyApplication7app' since version 3.1.4 was already applied to this project
解决方式:降级使用8.5.1的版本
具体配置如下:
步骤 1:在 project 的 build.gradle 文件中的 dependencies 下添加如下加粗代码: gradle版本根据自己的填写
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.jakewharton:butterknife-gradle-plugin:8.5.1'
}
步骤 2:在 module 的 build.gradle 文件中的 dependecies 下添加如下依赖:
dependencies {......
compile 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1' }
ps:依赖版本可根据添加的 ButterKnife 框架版本自行调整。 这样就解决了空指针异常的问题,可以正常使用 ButterKnife 了。
二、 更多使用方法参考:官网文档
1.注入Textview、Button、事件
View和字符串资源的注入:
注意:不能以private修饰符修饰
public class MainActivity extends AppCompatActivity {
@BindView(R.id.tv_title) TextView tv_title;
@BindView(R.id.btn1) Button mBtn1;
@BindView(R.id.btn2) Button mBtn2;
//资源注入
@BindString(R.string.app_name)
String str;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在这里写上这个才使ButterKnife有效
ButterKnife.bind(this);
tv_title.setText(str);
mBtn1.setText("Btn1");
mBtn2.setText("Btn2");
}
原来的做法:要写一堆的findViewById
点击事件:
/**
* 点击事件的注入
*
* @param view
*/
@OnClick({R.id.btn1, R.id.btn2})
public void BtOnClick(View view) {
switch (view.getId()) {
case R.id.btn1:
Toast.makeText(this, "btn1 onclick!", Toast.LENGTH_SHORT).show();
break;
case R.id.btn2:
Toast.makeText(this, "btn2 onclick!", Toast.LENGTH_SHORT).show();
break;
}
}
效果一样,简化了不少代码:
2.注入ListView
public class CategoryActivity extends AppCompatActivity
{
@BindView(R.id.id_listview)
ListView mListView;
//简单数据源
private List<String> mData = new ArrayList<>(Arrays.asList("Simple Use", "RecyclerView Use"));
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category);
ButterKnife.bind(this);
mListView.setAdapter(new CategoryAdapter(this, mData));
}
/**
ListView点击事件
*/
@OnItemClick(R.id.id_listview)
public void itemClicked(int position)
{
Intent intent = null;
switch (position)
{
case 0:
//页面跳转
intent = new Intent(this, MainActivity.class);
break;
case 1:
intent = new Intent(this, RecyclerViewActivity.class);
break;
}
if (intent != null)
startActivity(intent);
}
}
Adapter使用ButterKnife
public class CategoryAdapter extends ArrayAdapter<String>
{
private LayoutInflater mInflater;
public CategoryAdapter(Context context, List<String> objects)
{
super(context, -1, objects);
mInflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder = null;
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.item_category, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else
{
holder = (ViewHolder) convertView.getTag();
}
holder.mTextView.setText(getItem(position));
return convertView;
}
static class ViewHolder
{
@BindView(R.id.id_title_tv)
TextView mTextView;
public ViewHolder(View view)
{
ButterKnife.bind(this, view);
}
}
}
3.注入RecycleView
1.view中
public class RecyclerViewActivity extends AppCompatActivity
{
@BindView(R.id.id_recyclerview)
RecyclerView mRecyclerView;
private List<String> mDatas = new ArrayList<>(Arrays.asList("Simple Use", "RecyclerView Use"));
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view);
ButterKnife.bind(this);
mRecyclerView.setAdapter(new RvAdapter(this, mDatas));
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
2.RvAdapter使用ButterKnife 基本上和ListView的Adapter使用差不多
public class RvAdapter extends RecyclerView.Adapter<RvAdapter.ViewHolder>
{
private LayoutInflater mInflater;
private List<String> mDatas;
public RvAdapter(Context context, List<String> datas)
{
mInflater = LayoutInflater.from(context);
mDatas = datas;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i)
{
return new RvAdapter.ViewHolder(mInflater.inflate(R.layout.item_category, viewGroup, false));
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i)
{
viewHolder.mTextView.setText(mDatas.get(i));
}
@Override
public int getItemCount()
{
return mDatas.size();
}
static class ViewHolder extends RecyclerView.ViewHolder
{
@BindView(R.id.id_title_tv)
TextView mTextView;
public ViewHolder(View itemView)
{
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
三、ButterKnife Zelezny学习插件 Github
基于BufferKnife的插件,快速生成BufferKnife的注解,不用你手动去敲
使用时需要注意几点:
- layout布局控件需要有id才能被正常引用
- oncreate中记得加上ButterKnife.bind(this)方法
- 怎么安装
- in Android Studio: go to
Preferences → Plugins → Browse repositories
and search forButterKnife Zelezny
找到之后点击 install,安装完成之后点击ok会重启studio(参考下图)
- or 如果搜索不到可以采取以下第二种方法
-
download it and install via
Preferences → Plugins → Install plugin from disk
如何使用:
- Make sure you have latest Butterknife lib on your classpath(确保已经安装插件前往
Preferences → Plugins中查看是否安装
) - Right click on usage of desired layout reference (e.g. R.layout.main in your Activity or Fragment), then
Generate
andGenerate ButterKnife Injections(选中oncreate的布局文件——>鼠标右键——>Generate——>Generate ButterKnife Injections)
- Pick injections you want, you also have an option to create ViewHolder for adapters.
- Click
Confirm
and enjoy injections in your code with no work!
adapter中快速生成viewholder(右键点击item布局文件和之前的一样)
注意:要写id
自动生成的ViewHolder(当 ViewHolder里面有大量的View时可以减轻findViewById的工作量)
原理:可以参考:ButterKnife,你真的了解吗?