Portanto, o título diz tudo. Estou recebendo um erro de compilação dentro do meu onClick
.
Aqui está o código.
public class fieldsActivity extends Activity {
Button addSiteButton;
Button cancelButton;
Button signInButton;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// to create a custom title bar for activity window
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.fields);
// use custom layout title bar
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.topbar);
Pager adapter = new Pager();
ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);
mPager.setAdapter(adapter);
mPager.setCurrentItem(1);
addSiteButton = (Button) findViewById(R.id.addSiteButton);
addSiteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPager.setCurrentItem(2, true); //Compilation error happens here.
}
});
cancelButton = (Button) findViewById(R.id.cancel_button);
signInButton = (Button) findViewById(R.id.sign_in_button);
}
Respostas:
Se você não quiser torná-lo final, você pode apenas torná-lo uma variável global.
fonte
Você pode declarar a variável final ou torná-la uma variável de instância (ou global). Se você declará-lo final, não será possível alterá-lo mais tarde.
Qualquer variável definida em um método e acessada por uma classe interna anônima deve ser final. Caso contrário, você poderia usar essa variável na classe interna, sem saber que, se a variável mudar na classe interna e, em seguida, for usada posteriormente no escopo interno, as mudanças feitas na classe interna não persistiram no escopo interno. Basicamente, o que acontece na classe interna permanece na classe interna.
Eu escrevi uma explicação mais detalhada aqui . Também explica por que as variáveis de instância e globais não precisam ser declaradas finais.
fonte
O erro diz tudo, mude:
para
fonte
final
, em linguagem Java. Junto com a ausência de parâmetros de referência, essa regra garante que os locais sejam atribuídos apenas no método a que pertencem. O código é, portanto, mais legível.addSiteButton.setOnClickListener(new View.OnClickListener() {
, você tem alguma ideia de por que isso ocorreria?null
. Provavelmente, findViewById está retornandonull
. Não posso dizer mais, não sendo um programador Android; Aconselho você a abrir uma pergunta separada. Certamente, não tem nada a ver com classes internas, final, et similia .Aqui está uma resposta engraçada.
Você pode declarar um array final de um elemento e alterar os elementos do array o quanto quiser, aparentemente. Tenho certeza de que isso quebra o motivo pelo qual essa regra do compilador foi implementada em primeiro lugar, mas é útil quando você está em uma situação difícil como eu estava hoje.
Na verdade, não posso reivindicar crédito por este. Foi recomendação do IntelliJ! Parece um pouco hacky. Mas não parece tão ruim quanto uma variável global, então achei que valeria a pena mencionar aqui. É apenas uma solução para o problema. Não necessariamente o melhor.
fonte
Como @Veger disse, você pode fazer
final
com que a variável possa ser usada na classe interna.Eu o chamei em
pager
vez demPager
porque você o está usando como uma variável local noonCreate
método. Om
prefixo é reservado cusomarily para variáveis de membros de classe (isto é, variáveis que são declaradas no início da classe e estão disponíveis para todos os métodos de classe).Se você realmente precisa de uma variável de membro de classe, não funciona para torná-la final porque você não pode usar
findViewById
para definir seu valor atéonCreate
. A solução é não usar uma classe interna anônima. Dessa forma, amPager
variável não precisa ser declarada final e pode ser usada em toda a classe.fonte
fonte