在android中实现View.OnClickListener的最佳方法

Sar*_*tal 41 java android

假设我们有一个活动,其中有很多OnClickListener要注册的视图.

实现这一点最常见的方法是让Activity-Subclass实现OnClickListener,如下所示:

public class ActivityMain extends Activity implements View.OnClickListener
{   
    @Override
    public void onClick(View view)
    {
        switch (view.getId())
        {
            //handle multiple view click events
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想实现它的方法是在Activity-Subclass中创建一个私有类,并让该内部类实现OnClickListener:

public class ActivityMain extends Activity implements View.OnClickListener
{
    private class ClickListener implements View.OnClickListener
    {   
        @Override
        public void onClick(View view)
        {
            switch (view.getId())
            {
                //handle multiple view click events
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这样代码看起来更有条理,易于维护.

此外,谈论"Is-a","Has-a"关系,后者似乎是一种很好的做法,因为现在Activity-Subclass与ClickListener有一个"Has-a"关系.虽然在前一种方法中我们会说我们的Activity-Subclass"Is-a"ClickListener,但这并不完全正确.

请注意,我不关心后者会导致的内存开销.

此外,在xml中添加onClick标记完全不可能.

那么,实现ClickListener的最佳方法是什么?

请不要建议像RoboGuice或ButterKnife等任何图书馆.

更新:

我想分享一下我最终采用的方法.

我直接在Activity/Fragment中实现了监听器.

就OOP设计而言.在"HAS-A"的做法并没有提供所有的实际利益,甚至占用更多的内存.考虑到我们将为我们实现的每个类似侦听器创建的嵌套类的数量(以及内存开销),应该明确避免这种方法.

小智 45

首先,Android没有关于注册点击监听器的最佳实践.这完全取决于您的使用案例.

实现View.OnClickListenerActivity 的接口是可行的方法.因为Android强烈推荐一遍又一遍地实现接口实现,无论它是Activity还是Fragment.

正如你所描述的那样:

public class ActivityMain extends Activity implements View.OnClickListener
{
    private class ClickListener implements View.OnClickListener
    {   
        @Override
        public void onClick(View view)
        {
            switch (view.getId())
            {
                //handle multiple view click events
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是你的方法.现在这是你的实现方式,如果你不关心内存开销,这没有什么不妥.但是创建内部类并实现它的好处是,View.OnClickListener如果您可以在主类中简单地实现它,这也可以导致您需要的代码清晰度和简单性.

所以它只是一个讨论而不是获得实现View.OnClickListener的最佳解决方案,因为如果你按照每个人的实际观点,你将寻求一个简单且内存有效的解决方案.

所以我更喜欢传统的方式.它使事情变得简单而有效.检查以下代码:

@Override
public void onClick(View view)
{
    switch (view.getId())
    {
        //handle multiple view click events
    }
}
Run Code Online (Sandbox Code Playgroud)

PS:你的方法肯定会增加代码行:P;)


Sha*_*dge 9

首先,让我们在这里清楚地了解基础知识.

通过实现一个接口,你的课程不会变成那样......就像你说的那样:

"我们的Activity-Subclass"是一个"ClickListener,这不是完全正确的."

如果扩展,你的类只能有"Is-a"关系,在这种情况下是一个Activity.实现接口意味着它可以像接口设置其合同那样运行.

一个例子:

彼得延伸人类...意味着彼得是人类......

班彼得也可以实现程序员,音乐家,丈夫等等,这意味着彼得可以表现得如上所述.

至于最佳实践,你可以创建一个完全独立的类,它实现OnClickListener如下:

class MyListener implements View.OnClickListener{

  @Override
public void onClick(View view) {
        // do whatever you want here based on the view being passed
    }

}
Run Code Online (Sandbox Code Playgroud)

在您的主要内容中,Activity您可以实例化MyListener并调用onClick()并传递您的视图:

MyListener listener = new MyListener();

Button b = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button = (Button)findViewById(R.id.button);
    listener.onClick(button);
   }
Run Code Online (Sandbox Code Playgroud)


Far*_*deh 8

我使用button.setOnClickListener(this);我的地方Activity implements View.OnClickListener,然后Button在一个单独的方法中获取ID .请参阅下面的示例:

public class MyActivity extends ActionBarActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.YOUR_LAYOUT);

        ...

        Button myFirstButton = (Button) findViewById(R.id.YOUR_FIRST_BUTTON);
        myFirstButton.setOnClickListener(this);

        Button mySecondButton = (Button) findViewById(R.id.YOUR_SECOND_BUTTON);
        mySecondButton.setOnClickListener(this);

        ...

    }

    ...

    @Override
    public void onClick(View v) {
        Button b = (Button) v;
        switch(b.getId()) {
            case R.id.YOUR_FIRST_BUTTON:
                // Do something
                break;
            case R.id.YOUR_SECOND_BUTTON:
                // Do something
                break;
            ...
        }
    }

    ...

}
Run Code Online (Sandbox Code Playgroud)


Kin*_*ses 5

在这里,您可以创建一个btnClickListner对象,然后在您想要为按钮执行onCLieck操作时调用该btnCLickLisner对象.

让我们假设,在我的活动中,我有一个5到10个按钮,每个按钮单独写一个onclick listner是个坏主意.所以来过这个,我们可以使用如下.

注册你的按钮

Button button1 = (Button)findViewById(R.id.button1);
Button button2 = (Button)findViewById(R.id.button2);
Button button3 = (Button)findViewById(R.id.button3);
Button button4 = (Button)findViewById(R.id.button4);
Button button5 = (Button)findViewById(R.id.button5);
Run Code Online (Sandbox Code Playgroud)

点击后,我将onclick listner设置为我的按钮

button1.setOnClickListener(btnClickListner);
button2.setOnClickListener(btnClickListner);
button3.setOnClickListener(btnClickListner);
button4.setOnClickListener(btnClickListner);
button5.setOnClickListener(btnClickListner);
Run Code Online (Sandbox Code Playgroud)

这是btnClick Listner实现

View.OnClickListener btnClickListner = new OnClickListener()
    {
  @Override
        public void onClick( View v )
        {
            // TODO Auto-generated method stub
            if( button1.getId() == v.getId() )
            {
                //Do Button1 click operations here

            }
            else if( button2.getId() == v.getId() )
            {

               // Do Button2 click operations here

            }
            else if( button3.getId() == v.getId() )
            {
                 // Do Button3 click operations here

            }
            else if( button4.getId() == v.getId() )
            {
                // Do Button4 click operations here

            }
            else if( button5.getId() == v.getId() )
            {
                // Do Button5 click operations here
            }

        }

     }
Run Code Online (Sandbox Code Playgroud)