简体   繁体   English

无法从父类触发OnClickListener

[英]OnClickListener not firing from Parent class

A Follow up to this question: Group of Views (controls) on multiple screens 答:这个问题的跟进: 在多个屏幕上的视图组(控件)

I have created a parent class and a child class that inherits from it. 我创建了一个父类和一个从其继承的子类。 When I set the OnClickListener in the child class, the event fires when the button is clicked. 当我在子类中设置OnClickListener时,单击按钮会触发该事件。 When I move the set OnClickListener to the parent class, the event doesn't fire. 当我将设置的OnClickListener移到父类时,该事件不会触发。 I've got to be missing something obvious but I just don't see it. 我必须丢失一些明显的东西,但是我看不到。

Thanks, Cameron. 谢谢,卡梅隆。

Parent Class: 家长班:

public class NavigationMenu extends Activity 
{
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.nav_bar);

        Button loginButton = (Button) findViewById(R.id.navbtnHome);
        loginButton.setOnClickListener(new View.OnClickListener() 
        {
            public void onClick(View view) 
            {
                Toast.makeText(getApplicationContext(), "Cameron, Im here", Toast.LENGTH_SHORT).show();
                Intent i = new Intent(NavigationMenu.this, Login.class);
                startActivity(i);
            }
        });
    }
}

Child Class: 儿童班:

public class Settings extends NavigationMenu 
{
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings);
    }
}

The problem is that the setContentView of your Settings class will reset the layout that was created by your parent class' onCreate(). 问题在于,您的Settings类的setContentView将重置由父类的onCreate()创建的布局。 And therefore, the callbacks as well. 因此,回调也是如此。

To work around that, I would suggest that you add a LinearLayout with id "container" in your nav_bar layout. 要解决此问题,我建议您在nav_bar布局中添加ID为“ container”的LinearLayout。

You then leave the NavigationMenu class untouched and in your child class, you just insert your view in the container. 然后,您不更改NavigationMenu类,而在子类中,只需将视图插入容器即可。 This should work : 这应该工作:

  public class Settings extends NavigationMenu 
    {
        @Override
        protected void onCreate(Bundle savedInstanceState) 
        {
            super.onCreate(savedInstanceState);
            LinearLayout container = (LinearLayout)findViewById(R.id.container);
            View settingsView = getLayoutInflater().inflate(R.layout.settings, null);
            container.addView(settingsView);
        }
    }

Now, a cleaner way to do that would be to force your NavigationMenu's child class to provide something to be put in the container. 现在,一种更清洁的方法是强制NavigationMenu的子类提供要放入容器的内容。

You could achieve that by adding an abstract method to NavigationMenu that would require the children to create the view. 您可以通过向NavigationMenu添加一个抽象方法来实现这一点,该方法将要求子级创建视图。

public abstract class NavigationMenu extends Activity 
{
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.nav_bar);

        Button loginButton = (Button) findViewById(R.id.navbtnHome);
        loginButton.setOnClickListener(new View.OnClickListener() 
        {
            public void onClick(View view) 
            {
                Toast.makeText(getApplicationContext(), "Cameron, Im here", Toast.LENGTH_SHORT).show();
                Intent i = new Intent(NavigationMenu.this, Login.class);
                startActivity(i);
            }
        });

        LinearLayout container = (LinearLayout)findViewById(R.id.container);
        container.addView(createView());
    }

    protected abstract View createView();
}

And in your child class, you just have to implement createView () : 在子类中,您只需实现createView()即可:

  public class Settings extends NavigationMenu 
    {
        @Override
        protected View createView()
        {
            LinearLayout container = (LinearLayout)findViewById(R.id.container);
            return getLayoutInflater().inflate(R.layout.settings, null);
        }
    }

This has the advantage that if you change your layout (rename your container for example), you would have to modify only the parent class. 这样做的好处是,如果您更改布局(例如重命名容器),则只需修改父类。

您应该在孩子的setContentView之后调用super.onCreate,但是您必须变通,因为您的父级使用另一个视图调用setcontentview

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM