Android - view id
Android中,在java代码中new的控件是没有有效ID的(默认的ID都为-1,无效),这种情况下,如果设置多个控件的点击事件的时候会出现响应异常。
这个时候就需要我们给new出来的控件设置一个viewid,并且需要保证该id唯一(在范围内唯一???)。sdk在API17之后在View类中添加了generateViewId()方法来生成满足条件的ID。
对于小于17的API需要我们做API版本适配,我们通过一下方法进行实现:
public class TestActivity extends AppCompatActivity {
private final String TAG = getClass().getSimpleName() + "---";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
setContentView(layout);
Button buttonNoId = new Button(this);
buttonNoId.setText("没有ID");
buttonNoId.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e(TAG, "onClick: 没有ID->" + v.getId());
}
});
Button buttonHaveId = new Button(this);
buttonHaveId.setId(generateSelfViewId());
buttonHaveId.setText("有ID");
buttonHaveId.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e(TAG, "onClick: 有ID->" + v.getId());
}
});
layout.addView(buttonNoId);
layout.addView(buttonHaveId);
}
/**
* 生成viewId
*
* @return
*/
private int generateSelfViewId() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
return View.generateViewId();
} else {
//系统的实现方法
///API中sNextGeneratedId 是静态常量,本文中设置局部变量暂么有问题,待研究过AtomicInteger 之后再做确认!!!
AtomicInteger sNextGeneratedId = new AtomicInteger(1);
for (; ; ) {
int result = sNextGeneratedId.get();
// aapt-generated IDs have the high byte nonzero; clamp to the range under that.
int newValue = result + 1;
if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
if (sNextGeneratedId.compareAndSet(result, newValue)) {
return result;
}
}
}
}
}
通过点击两个按钮可以得到如下结果
TestActivity—: onClick: 有ID->1
TestActivity—: onClick: 没有ID->-1
对于API小于17使用的是,将API大于17中generateViewId()方法的实现拷贝出来的。通过源码可查看系统generateViewId()方法的实现。
对于上面实现的实现,在不均不设置viewId的情况下,如果将两个按钮的监听事件放在一起的时候,是不能正确监听到按钮的点击事件的。