我经常感到困惑的是,是创建实例视图并在不同的方法中使用它还是为了避免使用实例视图并在不同方法之间传递视图?实现onClickListener是一种好习惯吗?最好是单独初始化视图不同的方法,避免使用实例视图? 以下三个中哪个更好?
1. 避免实例变量而不实现onClickListener
FUNCTIONS_EXTENSION_VERSION
2. 创建实例变量并实现OnClickListener
public class XYZActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initViews();
}
private void initViews() {
ImageView ivScanner = (ImageView) findViewById(R.id.ivBanner);
TextView tvName = (TextView) findViewById(R.id.tvOfferName);
TextView tvText = (TextView) findViewById(R.id.tvOfferText);
TextView tvDetail = (TextView) findViewById(R.id.tvOfferDetail);
menthodXYZ(ivScanner,tvName);
tvName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
tvText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
tvDetail.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
}
3. 如果在不同方法中需要变量,则在不同方法中单独初始化它以避免实例变量并实现OnClickListener
public class XYZActivity extends BaseActivity implements View.OnClickListener{
private ImageView ivScanner;
private TextView tvName,tvText,tvDetail;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initViews();
}
private void initViews() {
ivScanner = (ImageView) findViewById(R.id.ivBanner);
tvName = (TextView) findViewById(R.id.tvOfferName);
tvText = (TextView) findViewById(R.id.tvOfferText);
tvDetail = (TextView) findViewById(R.id.tvOfferDetail);
tvName.setOnClickListener(this);
tvText.setOnClickListener(this);
tvDetail.setOnClickListener(this);
ivScanner.setOnClickListener(this);
...
}
@Override
public void onClick(View view) {
switch (view.getId())
{
case R.id.ivScanner:
...
break;
case R.id.tvName:
....
break;
case R.id.tvText:
....
break;
case R.id.tvDetail:
....
break;
}
}
答案 0 :(得分:2)
应避免使用选项#3 - 您不应每findViewById()
次致电View
次。这不仅仅是关于性能(这些调用仅在数十和数百例ListViews
中出现时才会成为性能问题),而且还与代码可读性有关。
我通常会为特定组件中使用的所有Views
定义字段。通过这种方式,您可以(通过查看其字段的定义)来了解组件的功能。您将来可能还需要在其他方法中引用其中一些Views
,因此这种方法可以提高可维护性。
至于是否应该使用匿名侦听器或使封闭组件实现OnClickListener
接口 - 它主要是个人偏好选择。我的经验法则:如果所有感兴趣的Views
的匿名听众都适合单页代码 - 我会匿名;如果不是 - 我使包含组件实现OnClickListener
接口并在单独的方法中处理所有点击。
所以,在你的情况下,我会选择这样的东西:
public class XYZActivity extends BaseActivity {
private ImageView ivScanner;
private TextView tvName;
private TextView tvText;
private TextView tvDetail;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initViews();
}
private void initViews() {
}
ivScanner = (ImageView) findViewById(R.id.ivBanner);
tvName = (TextView) findViewById(R.id.tvOfferName);
tvText = (TextView) findViewById(R.id.tvOfferText);
tvDetail = (TextView) findViewById(R.id.tvOfferDetail);
tvName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
tvText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
tvDetail.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
}
如果我需要向ivScanner
添加一个监听器,那么我会将所有监听器重构为一个方法。
<强>性能:强>
请注意,匿名类具有与之相关的一些性能成本。你可以听this talk by Jake Warthon - 他做了很好的调查和解释。但是,我认为在这种情况下,可读性和可维护性会超过轻微的性能提升。
答案 1 :(得分:1)
首先 - findByView 被认为是一项需要执行一次的昂贵操作,因此从这个角度来看,您的变体3非常昂贵。
其次,如果第二个版本中的 ... 意味着
menthodXYZ(ivScanner,tvName);
tvName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
tvText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
tvDetail.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
- &GT;单个onClick
的代码没有意义=)
但如果这意味着:
menthodXYZ(ivScanner,tvName);
tvName.setOnClickListener(this);
tvText.setOnClickListener(this);
tvDetail.setOnClickListener(this);
- &GT;你可以使用它,我认为这是你最好的变种,因为你:
Activity
findById
方法调用为什么你的第一个变体不好(这只是我个人的意见) - 你把所有的点击处理程序逻辑放在一个地方,如果点击处理程序有很多代码,那就很难调试它。 / p>
...
另外,我可以建议你另一个变种=)你可以使用杰克沃顿的ButterKnife library。它将删除所有用于创建视图实例的样板代码和onClickListeners
:
public class MyActivity extends BaseActivity {
private Unbinder unbinder;
@BindView(R.id.app_version)
TextView appVersionTextView;
@BindView(R.id.my_image_view)
ImageView myImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
unbinder = ButterKnife.bind(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbinder.unbind();
}
@OnClick(R.id.my_need_click_view)
public void clickToMySuperView() {
Log.i("TAG", "click to my super view!");
}
@OnClick(R.id.my_need_click_view_2)
public void clickToMySuperView() {
Log.i("TAG", "click to my super view 2!");
}
...
}
<强>更新强>
请看以下代码的和平:
public class MyActivity extends BaseActivity implements View.OnClickListener {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initView();
}
private void initView() {
ImageView myImageView = (ImageView) findViewById(R.id.my_image_view);
TextView myTextView = (TextView) findViewById(R.id.my_text_view);
myImageView.setOnClickListener(this);
myTextView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.my_image_view:
// special code for image view
break;
case R.id.my_text_view:
// special code for text view.
break;
default:
// no actions.
break;
}
}
}
在这段代码中,我们只将视图实例初始化一次,然后将click侦听器设置为它们。根据{{1}}生命周期,onCreate
方法只调用一次(如果Activity
在第一次创建,或者在销毁后重新创建它的状态)。在Activity
方法中我们的观点未初始化,我们只需要OnClick
参数中的id
。
然后,看看以下代码的和平:
View
在这种情况下,我们初始化视图实例并将它们保存到public class MyActivity extends BaseActivity implements View.OnClickListener {
private ImageView myImageView;
private TextView myTextView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initView();
}
private void initView() {
myImageView = (ImageView) findViewById(R.id.my_image_view);
myTextView = (TextView) findViewById(R.id.my_text_view);
myImageView.setOnClickListener(this);
myTextView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.my_image_view:
// special code for image view
break;
case R.id.my_text_view:
// special code for text view.
break;
default:
// no actions.
break;
}
}
}
对象中。但是,再次,我们只用Activity
方法初始化它们一次。同样,在onCreate
方法中,我们不会通过onClick
方法再次搜索此视图。
希望,这有帮助。