【问题标题】:Why use Anonymous Inner classes, and what are the alternatives?为什么要使用匿名内部类,有哪些替代方案?
【发布时间】:2014-03-14 22:51:36
【问题描述】:

我最近接触了 Android,一直在查看有关内部类的示例,但并不真正了解它们的用途。在制作听众和制作完整课程时经常使用它们,对吗?也许有人可以用外行的方式向我解释,在这种情况下使用内部匿名类的替代方法是什么? 这段代码:

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

谢谢

【问题讨论】:

  • 您可以创建一个带有名称的内部类,如果您需要该类的行为在多个位置而不是仅在一个位置内联,您通常会这样做.它基本上与局部变量与字段相同。
  • 你可以创建一个常规类,实例化它,然后将一个实例传递给 setOnClickListener。

标签: java android event-handling anonymous-inner-class


【解决方案1】:

另一种模式是让容器类本身成为监听器。

public class MyClass implements View.OnClickListener {
    @Override
    public void onClick(View v) {
        // Do something when button is clicked
    }

    public void initOrSomething() {
        button.setOnClickListener(this);
    }
}

但是,如果您有多个按钮需要采取不同的行为方式,您可能会遇到麻烦。

另一种方法是为每个按钮设置不同的侦听器类

public class Button1Listener implements View.OnClickListener {
    @Override
    public void onClick(View v) {
        // Do something when button1 is clicked
    }
}

public class Button2Listener implements View.OnClickListener {
    @Override
    public void onClick(View v) {
        // Do something when button2 is clicked
    }
}


button1.setOnClickListener(new Button1Listener());
button2.setOnClickListener(new Button2Listener());

匿名内部类只是第二种模式的更紧凑的表示。

编辑:两种模式的变化都是可能的,其中检查 View 对象的内容以确定单击了哪个按钮或将构造函数参数传递给侦听器类以更改侦听器行为等。

【讨论】:

  • 没问题 - 你只需打开视图的 id
  • 当然,与为每个按钮设置不同的侦听器接口实现相比,仅检查 View 对象的内容更容易出错。
  • 还请记住,您的构造函数可以接受一个或多个参数(即使匿名类不能这样做),并且实现侦听器的类可以具有字段(即使 interface 可以't)。如果您想要具有非常相似的行为但在某些细节上略有不同的东西,您可以使用构造函数参数使侦听器根据其构造方式改变行为。
  • @user254886 很高兴它有帮助。一个“接受答案”将被应用;)
【解决方案2】:

在制作听众和制作完整课程时经常使用它们,对吧?

Android 中的侦听器,或其他情况下的其他接口。但本质上,仅此而已。

在这种情况下使用内部匿名类的替代方法是什么?

这将是创建一个实现此接口的类并将其作为参数提交。例如:

public class MyListener
    implements View.OnClickListener
{
    // implement onClick(), etc etc
}

// In code:

button.setOnClickListener(new MyListener(...));

【讨论】:

    【解决方案3】:

    这很简单:您所做的只是创建一个类。对于 JVM(或本例中的 dalvik),类是它自己的编译单元(文件)、内部类还是匿名类(*)都没有关系。所以你有三个同样有效的选择:

    选项 1 您的示例:

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        }
    });
    

    选项2命名内部类:

    public MyActivity extends Activity {
    
     static class MyListener implements View.OnClickListener {
       @Override 
       public void onClick(View v) {
        // do something 
       }
    }
    ....
    
      button.setOnClickListener(new MyListener());
    }
    

    选项3不同的文件:

    文件 MyListener.java

    public class MyListener implements View.OnClickListener {
     @Override 
     public void onClick(View v) {
      // do something 
     }
    }
    

    文件 MyActivity.java

    import MyListener.java
    public MyActivity extends Activity {
    ....
    
      button.setOnClickListener(new MyListener());
    }
    

    您使用的这些选项中的哪一个完全是主观的 - 根据您的需求和使用情况,一个或另一个更有意义。 但是,通常在 UI 侦听器中,您不希望有任何与您正在编程的 Activity 的逻辑脱节的逻辑。因此,您使用匿名类,因为所有代码都保留在一个位置并使其具有良好的可读性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-21
      • 2010-09-28
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多