您的位置:首页 > 其它

findViewById已经过时了

2016-08-07 01:42 176 查看
每次写代码的时候都会遇到TextView name= (TextView) findViewById(R.id.name);而且每次都要写很多遍,是不是很烦。不过现在这些都不是问题了

DataBinding

DataBinding是谷歌一个数据绑定框架,谷歌出品,必属佳品

他的主要思想是mvvm(Model-View-ViewModel,恩,这个我也是不太明白)

设置使用dataBindind

要求你的gradule版本>=1.5

在app的build.gradule==>android下添加

dataBinding {
enabled = true
}


布局

activity_main.xml在外面加一个layout标签就好了,控件的id也要设好

<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn"
android:text="button"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler_view"></android.support.v7.widget.RecyclerView>
</LinearLayout>
</layout>


主布局的逻辑代码

ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
LinearLayoutManager manager=new LinearLayoutManager(this);
binding.recycler_view.setLayoutManager(manager);
binding.recycler_view.setAdapter(new RecAdapter(data,this));
binding.btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"click",Toast.LENGTH_SHORT).show();
}
});
}


这种访问views的机制不但相较于findViewById更加简单,而且速度也更加快。绑定的过程对于一个布局上的所有Views只需要一次遍历,就可以注册对应的作用域。若你使用findViewById,你的view层级需要在每一次的调用中都去寻找。

RecyclerView中

写一个实体类

public class Person {
private String name;
public Person () {
}

public Person (String name) {
this.name = name;

}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}


item的布局

<layout xmlns:android="http://schemas.android.com/apk/res/android">

<data>
<variable
name="person"
type="com.jkgeekjack.usedatabinding.Person" />
</data>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{person.name}"
android:layout_alignParentLeft="true"/>

</RelativeLayout>
</layout>


这里和我们平时用的有很大不同,首先声明你要放置的数据类型并起个名字,类型要加上包名,然后什么地方放这个实体的什么属性都设置好,到时传入一个实例就会自动把属性放到相应的位置

Adapter

public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
List<Person> data=new ArrayList<Person>();
Context context;
public Adapter(List<Person>data,Context context){
this.data=data;
this.context=context;
}
@Override
public Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(context),R.layout.item_user,parent,false);
//binding.getRoot()就是获取binding的view
ViewHolder viewHolder=new ViewHolder(binding.getRoot());
//让viewholder和binding绑定起来
viewHolder.setBinding(binding);
return viewHolder;
}

@Override
public void onBindViewHolder(RecAdapter.ViewHolder holder, final int position) {
//包名+.BR+.name,接下来传入数据
holder.getBinding().setVariable(com.jkgeekjack.usedatabinding.BR.person,data.get(position));
//设置item的监听
holder.getBinding().getRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context,data.get(position).getName(),Toast.LENGTH_LONG).show();
}
});
}

@Override
public int getItemCount() {
return data.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
ViewDataBinding binding;
public ViewHolder(View itemView) {
super(itemView);
}

public void setBinding(ViewDataBinding binding) {
this.binding = binding;
}

public ViewDataBinding getBinding() {
return binding;
}
}
}


到这里就设置好了。

以上在adapter直接传入一个实例,在Activity中同样可以,而且更简单

布局

<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="person"
type="org.loader.androiddatabinding.Person" />
</data>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{person.name}"/>

</LinearLayout>
</layout>


主布局的逻辑代码

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setPerson(new Person("jack"));
}


setPerson是自动生成的,你输入bingind.set会提示你布局里你个实例的名字以大写开头,然后就直接传入数据就可以了

再介绍一下之前一直在使用依赖注入框架ButterKnife [官网](http://jakewharton.github.io/butterknife

ButterKnife是一个支持View注入的框架,并且对性能基本没有损失。ButterKnife用到的注解并不是在运行时反射的,而是在编译的时候生成新的class。

支持 Activity 中的 View 注入

支持 View 中的 View 注入

支持 View 事件回调函数注入 (@OnLongClick 、 @OnFocusChanged、@OnEditorAction、@OnItemClick 、@OnItemLongClick and @OnCheckedChanged)

使用:

配置 在gradle中添加依赖(现在最新版本是8.0.1)

compile 'com.jakewharton:butterknife:7.0.1'


Activity

ButterKnife.bind(this);必须在setContentView();之后,且父类bind绑定后,子类不需要再bind

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hello);
// 须在setContentView之后调用
ButterKnife.bind(this);
}


Fragment

ButterKnife.bind(this, mRootView);同样必须在setContentView();之后,且父类bind绑定后,子类不需要再bind

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_hello,container,false);
ButterKnife.bind(this,view);
initView(inflater,container,savedInstanceState);
return view;
}


然后光标移到布局文件上(
R.layout.activity_hello
)使用组合键Ctrl+Shift+B或者鼠标右键,点击Generate,在点击Generate ButterKnife Injections然后选择你需要的控件。(需要插件ButterKnifeZelezny)

@Bind(R.id.background)
ImageView background;
@Bind(R.id.avatar)
CircleImageView avatar;
@Bind(R.id.name)
TextView name;
@Bind(R.id.name_editor)
ImageView nameEditor;
@Bind(R.id.toolbar)
Toolbar toolbar;
@Bind(R.id.collapsinglayout)
CollapsingToolbarLayout collapsinglayout;
@Bind(R.id.appbarlayout)
AppBarLayout appbarlayout;
@Bind(R.id.recyclerview)
RecyclerView recyclerview;


所有的想要的都生成了,很方便

点击事件的绑定:不用声明view,不用setOnClickLisener()就可以绑定点击事件

@OnClick({R.id.logon_input_btn, R.id.login_register, R.id.login_forgetPassword})
public void onClick(View view) {

switch (view.getId()) {
case R.id.logon_input_btn:
Toast.makeText(this,"登录",Toast.LENGTH_SHORT).show();
detectionText();
break;
case R.id.login_register:
intent = new Intent(this,Register.class);
startActivity(intent);
break;
case R.id.login_forgetPassword:
break;
}
}


ViewHolder

在ViewHolder中添加了一个有View参数的构造方法,以后再也不需要在getView方法中findViewById了

class ViewHolder {
@Bind(R.id.person_name)
TextView name;
public ViewHolder(View view) {
//绑定
ButterKnife.Bind(this, view);
}
}


还有一些其它的用法(平时也没怎么用到)就不一一列出了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: