Android 设置viewId

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值