【问题标题】:Adding onClickListener for a button created dynamically within a for loop为在 for 循环中动态创建的按钮添加 onClickListener
【发布时间】:2014-03-26 07:18:34
【问题描述】:

我有一个 RelativeLayout,它允许游戏玩家输入个人详细信息,例如姓名并定义他们的角色。布局是根据有多少玩家动态创建的(这在活动的前面已定义)。 这都包含在一个 for 循环中以生成每个布局。

我正在尝试添加一个 onclicklistener,以便在每个玩家输入他们的详细信息时存储他们的个人数据。

到目前为止,我使用的代码会产生 ArrayIndexOutOfBoundsException。

能否请您解释一下我应该如何更正此代码,谢谢。

    public void buildDynamicViews(Integer input1) {
        int textId = 10; 
    //Arrays
    groupDetailsList = (RelativeLayout)findViewById(R.id.playersNameLayout);
    row_Number = new TextView[input1];
    spinnerArray = new Spinner[input1];
    groupDetailsContainer = new RelativeLayout[input1];
    firstNameText = new TextView[input1];
    lastNameText = new TextView[input1];
    fNameInput = new EditText[input1];
    lNameInput = new EditText[input1];
    playerDetailsButton = new Button[input1];


    //displays lines of text with instructions
    text = (TextView)findViewById(R.id.displayMessage);
    ViewGroup.LayoutParams params = text.getLayoutParams();
    params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
    text.setId(textId);
    ((MarginLayoutParams) params).setMargins(0,0,0,20);
    text.setLayoutParams(params);
    String txt1 = getResources().getString(R.string.player_details_Title);
    String txt2 = getResources().getString(R.string.players_details_message);
    String txt = txt1+"\n"+txt2;
    text.setText(txt);

     //Scrollview to contain relativeLayouts created in for loop
    ScrollView scroll = (ScrollView)findViewById(R.id.playerNameScroller);
    RelativeLayout.LayoutParams scrollerLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    scrollerLayoutParams.addRule(RelativeLayout.BELOW, text.getId());
    scroll.setLayoutParams(scrollerLayoutParams);


    //Loop
    for ( i = 0; i < input1; i++) {

    //generate relativelayout to house each individual players data input section
    groupDetailsContainer[i] = new RelativeLayout(this);
        groupDetailsContainer[i].setId(20+i);
        RelativeLayout.LayoutParams containerParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        if(i==0){
                containerParams.addRule(RelativeLayout.BELOW ,text.getId());
                }
                else
            {
            containerParams.addRule(RelativeLayout.BELOW, (i+19));
            }
        containerParams.setMargins(0,0,0,20);
        groupDetailsContainer[i].setLayoutParams(containerParams);


        //generate left hand box for player number
        row_Number[i]= new TextView(this);
        LayoutParams rowNumParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        rowNumParams.addRule(RelativeLayout.ALIGN_LEFT);
        if(i ==0)
            rowNumParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        else
        {
            rowNumParams.addRule(RelativeLayout.BELOW, (i-1));

        }
        row_Number[i].setLayoutParams(rowNumParams);
        row_Number[i].setText("Details for Player Number:" + (i+1));
        row_Number[i].setHeight(80);
        row_Number[i].setTextSize(20);
        row_Number[i].setWidth(125);
        row_Number[i].setId((i+1));

        //generate  box for text first name
        RelativeLayout.LayoutParams fNameParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        fNameParams.addRule(RelativeLayout.RIGHT_OF, row_Number[i].getId() );
        firstNameText[i] = new TextView(this);
        firstNameText[i].setTextSize(20);
        firstNameText[i].setHeight(40);
        firstNameText[i].setText("Enter First Name:");
        firstNameText[i].setId(31*(i+1));
        firstNameText[i].setLayoutParams(fNameParams);

        //generate  EditTextbox for first name input
    RelativeLayout.LayoutParams fNameinputParams = new LayoutParams(200, 25);
        fNameinputParams.addRule(RelativeLayout.RIGHT_OF, firstNameText[i].getId());
        fNameinputParams.addRule(RelativeLayout.ALIGN_BASELINE, firstNameText[i].getId());
        fNameinputParams.setMargins(10, 0, 10, 0);
        fNameInput[i] = new EditText(this);
        fNameInput[i].setLayoutParams(fNameinputParams);
        fNameInput[i].setId(32*(i+1));
        fNameInput[i].setTextSize(20);

         //generate  button
   RelativeLayout.LayoutParams detailsButtonParams = new LayoutParams (LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        playerDetailsButton[i] = new Button(this);
        detailsButtonParams.addRule(RelativeLayout.RIGHT_OF, spinnerArray[i].getId());
        detailsButtonParams.addRule(RelativeLayout.ALIGN_BOTTOM, spinnerArray[i].getId());
        detailsButtonParams.setMargins(20, 0, 20, 0);
        playerDetailsButton[i].setLayoutParams(detailsButtonParams);
        playerDetailsButton[i].setWidth(250);
        playerDetailsButton[i].setHeight(20);
        playerDetailsButton[i].setText("Press to save details");

    //generate  OnClick Listener for button
        PlayerDetailsButtonOnClick = new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                String FName = firstNameText[i].toString();
                String LName = lastNameText[i].toString();
                String fullName = FName+" "+LName;
                toast(fullName);

                }
            };


        playerDetailsButton[i].setOnClickListener(PlayerDetailsButtonOnClick);

        //wrap each view to the layout        
    groupDetailsContainer[i].addView(row_Number[i]);
        groupDetailsContainer[i].addView(fNameInput[i]);
        groupDetailsContainer[i].addView(lNameInput[i]);
        groupDetailsContainer[i].addView(firstNameText[i]);
        groupDetailsContainer[i].addView(lastNameText[i]);
        groupDetailsContainer[i].addView(spinnerArray[i]); 
        groupDetailsContainer[i].addView(playerDetailsButton[i]);
        groupDetailsList.addView(groupDetailsContainer[i]);   }

还有一个问题可能是如何将字符串值从循环传递到 onClick() 函数。谢谢

【问题讨论】:

  • 请同时粘贴 Log cat 输出,为什么不能使用列表视图列出每个条目的分数?
  • 背后的想法是什么:row_Number = new TextView[input1];?
  • @Aneez,我没有使用 listvew,因为我需要人们在此处输入信息并将编辑视图附加到列表视图,当我最初尝试时似乎没有用
  • @donfuxx [input1] 是定义玩家数量的值,因此是循环次数和要创建的玩家输入框集
  • @Aneez 嗨,Aneez,无法附加整个日志,它太长了这是大部分内容:03-26 09:24:09.124: E/AndroidRuntime(22742): FATAL EXCEPTION: main 03- 26 09:24:09.124:E/AndroidRuntime(22742):java.lang.ArrayIndexOutOfBoundsException:长度=5; index=5 03-26 09:24:09.124: E/AndroidRuntime(22742): at com.example.jscav.GroupDetails1$3.onClick(GroupDetails1.java:263)03-26 09:24:09.124: E/AndroidRuntime( 22742): 在 android.view.View.performClick(View.java:3511) 03-26 09:24:09.124: E/AndroidRuntime(22742): 在 android.view.View$PerformClick.run(View.java:14109 )

标签: android button for-loop onclicklistener buttonclick


【解决方案1】:

pojo 类是一个简单的类(您可以通过 setter 添加数据或制作一个简单的构造函数):

    private class POJOName {
    String firstName;
    String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

这个类可以用来存储名字和姓氏然后你使用playerDetailsButton[i].setTag( here you put the pojo object );然后

//generate  OnClick Listener for button
    PlayerDetailsButtonOnClick = new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            POJOName pojo = (POJOName)v.getTag();
            String fullName = pojo.getFirstName()+" "+pojo.getLastName();
            toast(fullName);

            }
        };

【讨论】:

    【解决方案2】:

    我还设法通过第二种方式解决了这个问题。

    我在 for 循环中为 int i 值分配了一个最终的 int j 变量。

    然后在 OnClick() 中,我引用了相关的编辑视图,例如 [class].this.[viewname][j].gettext().toString(); 所以我的代码如下所示:

            final int j = i;
    
    
            playerDetailsButton[i].setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    Log.d("detailsOnClick", "Button Pressed");
                    inputFName = GroupDetails1.this.fNameInput[j].getText().toString();
                    Log.d("inputFNameOnClick", inputFName);
    
                    inputLName = (GroupDetails1.this.lNameInput[j].getText()).toString();
                    toast(inputFName);
                    toast(inputLName);
        }
    

    感谢您的所有帮助和意见

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-16
      • 1970-01-01
      • 1970-01-01
      • 2017-10-12
      • 1970-01-01
      • 2014-08-27
      • 1970-01-01
      相关资源
      最近更新 更多