Android и делает " это " слушателем для одной из своих кнопок


У меня есть пользовательский вид MyView, раздутый из my_view.xml (с соответствующим классом Java MyView.java).

Я переопределяю MyView(Context context, AttributeSet attrs) для подключения вложенных представлений к членам класса.

Теперь один из этих подвидов является Button, и я хотел бы, чтобы мой вид прослушал щелчок по его кнопке, прежде чем передавать это событие делегату. Однако если я объявлю

this.myButton.setOnClickListener(this);

В конструкторе MyView(Context context, AttributeSet attrs) (где this - экземпляр MyView) я получаю NullPointerException.

Где находится подходящее место в MyClass.java для вызова this.myButton.setOnClickListener(this);?

%%

Правка. Код:

public MyView(Context ctx, AttributeSet attrs)
{
  super(context, attrs);
  this.myButton = (Button) this.findViewById(R.id.my_button);
  this.myButton.setOnClickListener(this); // Raises null pointer;'id' is correct.
}
2 3

2 ответа:

Вместо того, чтобы пытаться выполнить вызов setOnClickListener(this) в конструкторе, сделайте это после полной инициализации кнопки. Попробуйте переместить setOnClickListener(this) так, чтобы он вызывался (косвенно) из метода родительского действия onResume следующим образом:

public class MainMenuActivity extends Activity {
    @Override
    public void onResume() {
        super.onResume();
        new MyView(this, attrs).onResume();
    }
   ...
}

public class MyView {
    public void onResume() {
        myButton.setOnClickListener(this);
    }
  ...
}

Я использую Roboguice все время для такого рода вещей, и очень рекомендую его. Мой код обработчика кнопок выглядит следующим образом:

class ButtonHandler implements OnClickListener {
    @InjectView(R.id.MainMenuButton)
    private Button button;

    public void onResumeEvent( @Observes OnResumeEvent onResume ) {
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        doSomethingUseful();
    }
}

Проблема в том, что я пропустил накачку в конструкторе:

LayoutInflater i = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
i.inflate(R.layout.my_view, this);

Это сбивает меня с толку, поскольку я думал, что конструктор MyView(Context ctx, AttributeSet attrs) будет вызван для раздувания представления, а не наоборот.