【问题标题】:Modify an object from OnClickListener non-final variable permited允许从 OnClickListener 非最终变量修改对象
【发布时间】:2011-10-21 13:01:00
【问题描述】:

我有一个适配器,用于加载我的用户和一个按钮/文本文件用于发送邀请。在适配器中我这样做:

    @Override
public View getView(int position, View convertView, ViewGroup parent) {                 
    UserAgenda ua = getItem(position);  

    ViewHolder holder;      
    if (convertView == null) {          
        //...         
        convertView.setTag(holder);            
    } else {
        holder = (ViewHolder) convertView.getTag();
    }           

        if(ua.getInvited() != null){
            if(ua.getInvited().equals("true")){
                addTextViewInvited(convertView);//add a textview as the user is invited
            }
            else if(ua.getInvited().equals("false")){
                addButton2Invite(convertView,ua);//add the button to invite
            }
        }       
    return convertView;
}

在 addButton2Invite 方法上,我将邀请发送为:

   private void addButton2Invite(final View convertView, UserAgenda ua) {       

    bt2Invited.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(final View v) {

            final Button bt2Invited = (Button) convertView.findViewById(R.id.bt2invite);
            final ProgressBar pbar = (ProgressBar) convertView.findViewById(R.id.progress);
            new Thread(){
                @Override
                public void run() { 
                    if(networkWork())
                       ua.setInvited("true"); //Error, NOT PERMITED! ua need to be final.
                };
            }.start();
        }
    });     
}

当networkWork正常时,我想设置ua.setInvited("true");,但如果我不将ua声明为final,这是不允许的。但是我不能改变它的值,下次适配器进入 getView 时会找到ua.getInvited() = "false"。当我向下/向上滚动 textview 并且按钮出现在行上时。

有什么想法可以更改 onClicklistener 中的对象 UserAgenda ua 的值吗?

谢谢!

【问题讨论】:

  • 您是否尝试过将其设为最终值和更改值,然后检查其值..?
  • final 使您无法重新分配变量。我看不到您在此代码中分配 ua 的位置。如果一个变量是final,你仍然可以调用它的变异方法。也许你确实在某个时候重新分配了ua,我只是在这段代码中看不到它,所以我不明白你为什么不能将它标记为final
  • +1 同意@nicholas.hauschild

标签: java android anonymous-inner-class


【解决方案1】:

声明 ua final 因为在 ua.setInvited(true);您正在更改由 ua 引用的对象中的值,而不是 ua 的引用,因此通过设置 ua final 不会影响您的 setInvited(true)

否则你必须通过在你的活动类中实现它来使用点击监听器

public MyActivity extends Activity implements OnClickListener

并使用

myView.setOnClickListener(this);

实现方法

public void onClick(View v)
 {
    switch (v.getId()) 
       {
         case R.id.myView:
          //functionality for on click
         break;
        }
  }

【讨论】:

    【解决方案2】:

    在Java中,关键字final,当应用于引用类型的变量时,意味着它的引用不能改变,而不是底层对象不能修改(后者称为不变性)。

    例如,这意味着在你的方法中,如果 ua 被声明为 final,你可以这样做:

    ua.some_pub_non_final_field = "some_value";
    ua.somePublicMethod();
    

    但不是

    ua = new UA();
    

    【讨论】:

      猜你喜欢
      • 2017-05-23
      • 2022-06-12
      • 2011-08-15
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      • 2016-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多