【问题标题】:Android - Get id of dynamically generated buttonsAndroid - 获取动态生成的按钮的 id
【发布时间】:2013-05-31 17:10:31
【问题描述】:

我正在尝试在我的应用中实现一项功能,用户可以在其中向屏幕添加按钮,然后长按将其删除。

我能够完成第一部分,用户可以添加按钮并且用户可以删除最近添加的按钮。但是,如果您尝试删除任何其他按钮,则会出现 NullPointerException。

这是我创建新按钮的方法:

    public Button makeButton(Context context, String label, final GestureDetector gdt, int buttonId) {



    btn = new Button(context);

    v = new TextView(context);
    v.setText("");
    v.setHeight(10);


    ScrollView s = (ScrollView) homeView.findViewById(R.id.mainScroll);
    s.setVerticalScrollBarEnabled(false);

    btn.setText(label);
    btn.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
    btn.setHeight(70);
    btn.setId(buttonId);
    btn.setBackgroundColor(Color.GREEN);
    btn.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            id = btn.getId();

            gdt.onTouchEvent(event);



            switch(event.getAction()) {

            case(MotionEvent.ACTION_DOWN):

                ColorDrawable color = (ColorDrawable) btn.getBackground();
                int backgroundColor = color.getColor();

                if(backgroundColor == Color.GREEN) {
                    btn.setBackgroundColor(Color.YELLOW);
                    showToast("Running late??");
                }

            }

            return true;

        }

    });




    Ll.addView(btn);
    Ll.addView(v);


    return btn;


}

这里是用于创建新按钮的按钮的 onClickListener():

    addButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            factory.inflate(R.layout.eventadd, null);
            final View addEvent = factory.inflate(R.layout.eventadd, null);
            final EditText eventTime = (EditText) addEvent.findViewById(R.id.editText1);
            AlertDialog.Builder createEvent = new AlertDialog.Builder(context);

            createEvent.setTitle("Add new event");
            createEvent.setView(addEvent);
            (createEvent).setPositiveButton("Add Event", new DialogInterface.OnClickListener(){

                @Override
                public void onClick(DialogInterface arg0, int arg1) {
                    // TODO Auto-generated method stub
                    String getTxt = eventTime.getText().toString();
                    makeButton(context, getTxt, gestureDetector, id);
                    id++;
                }



            });
            createEvent.show();

        }

    });

最后这是我的 GestureListener:

    private class GestureListener extends SimpleOnGestureListener {



    @Override
    public void onLongPress(MotionEvent event) {


        showToast("Button " + btn.getId() + " deleted");
        btn.setVisibility(View.GONE);
        ((LinearLayout)btn.getParent()).removeViewAt(id);
        ((LinearLayout)v.getParent()).removeView(v);
    }

}

我很确定错误与按钮的 ID 以及它们在 GestureListener 中的删除方式有关。当然我很可能是错的。感谢所有的帮助:)

【问题讨论】:

  • 您在 GestureListener 上的哪个位置设置到您的按钮? GestureListener 将如何始终引用正确的 v 和 id 字段?
  • 在makeButton方法的onTouch()中(gdt.onTouchEvent(event));这是我认为可能是问题的一件事。

标签: java android nullpointerexception


【解决方案1】:

问题在于您的 GestureListener。

您正在执行((LinearLayout)btn.getParent()).removeViewAt(id); 这将删除特定索引处的视图。我相信你想要

View view = ((LinearLayout)btn.getParent()).findViewById(id) 向您返回一个视图,然后您应该将该视图传递给

((LinearLayout)btn.getParent()).removeView(view);

编辑

看起来您为Button 保留了一个私有类变量。这意味着那里的按钮将始终是您制作的最后一个按钮。在您的 onTouch() 方法中,您引用了 btn 变量,这是您创建的最后一个按钮。如果您将onTouch() 方法中的第一行更改为id = v.getId(),它应该会给您正确的按钮。

【讨论】:

  • @DanielScott 您要将 GestureListener 附加到什么位置?
  • @DanielScott 我可能会推荐的其他东西,而不是使用 id,是使用视图的 setTag(Object obj) 方法。这将让您将对象而不是 Id 绑定到视图。然后,您可以传递一个常量字符串作为标记,然后使用findViewByTag(Object obj) 根据该字符串查找视图。
  • 好的,我会尝试使用标签。另一个问题,我将 GestureListener 绑定到什么是什么意思?如果措辞不同,我可能会理解。感谢您的所有帮助:)
  • 标签似乎不是问题。在稍微摆弄之后,我认为这与我在 onTouch 上分配按钮的方式有关,因为当添加多个按钮时,无论我在哪里触摸,动作只会发生在添加的最后一个按钮上。希望这会有所帮助:)
  • @DanielScott 我只是把它扔在那里,但请注意将id = btn.getId(); 更改为id = v.getId();。这将迫使您获取所触摸视图的 ID。在 onTouch 方法中,您正在引用范围之外的按钮。我现在看到了,我想。我将编辑我的答案。
【解决方案2】:

使用一堆按钮 ID。 每当您创建按钮时,将其 id 保存在该堆栈中 当你按下删除按钮时,从堆栈中获取最后一个当前的 id 并删除按钮 - >然后从堆栈中删除它的 id。

【讨论】:

  • 是的,我认为没有分配给每个按钮并保存在那里的 id 存在问题。但是,由于按钮可以随机删除,我该如何解决这个问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
  • 1970-01-01
  • 2016-09-01
  • 1970-01-01
  • 2013-01-21
  • 1970-01-01
相关资源
最近更新 更多