Android 设置viewId

来源:互联网 发布:2016中国人口迁移数据 编辑:程序博客网 时间:2024/06/03 14:08

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的情况下,如果将两个按钮的监听事件放在一起的时候,是不能正确监听到按钮的点击事件的。