Atualizando o texto em um botão
-
21-12-2019 - |
Pergunta
Olá, queria saber por que a atualização do texto de um botão se comporta de maneira diferente no meu aplicativo.
Eu chamo um fragmento que obtém as informações com as quais o botão deve ser atualizado, faço um retorno de chamada de interface do fragmento para atualizar uma variável global que a atividade atualiza o texto do botão.
O problema é que a atividade onde está localizado o botão não atualiza o botão para mostrar o novo texto mas se eu fizer através do fragmento funciona, invalidar o botão não funciona ou forçar a atualização se eu fizer através da atividade .
Aqui está a atividade que chama quando você pressiona o botão que então chama um fragmento que mostra uma lista e quando você clica em uma opção o botão deve mudar seu texto para o que você escolheu:
public void onClick_testSite(View view)
{
// create the fragment
SelectChartTypeDialogFragment chartType = new SelectChartTypeDialogFragment();
// register you as a delegate for the callback
chartType.delegate = this;
// show the list
chartType.show(getFragmentManager(), "WEE");
// fetch the button and set the text ** DOESNT WORK **
Button p1_button = (Button)findViewById(R.id.btn_pickChart);
p1_button.setText(response);
p1_button.invalidate();
}
@Override
public void processFinish(String response)
{
this.response = response;
}
e aqui está parte do fragmento que trata do diálogo:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
// get the list from a enum
final List<ChartTypes> chartList = Arrays.asList(ChartTypes.values());
// The array containing the different choices
ArrayAdapter<ChartTypes> adapter = new ArrayAdapter<ChartTypes>(
getActivity(), android.R.layout.simple_list_item_1, chartList);
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// The dialog setting
builder.setTitle(R.string.pick_chart);
builder.setAdapter(adapter, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int position)
{
// get the name of the enum based on the position, what one
// clicked on the dialog
String strName = chartList.get(position).name();
// this sets the text in the activitys global variable
delegate.processFinish(strName);
// set the text in the fragment instead
//changeBtnText(strName);
//dialog.dismiss();
}
});
// Create the AlertDialog object and return it
return builder.create();
}
public void changeBtnText(String newBtnxt)
{
Button button = (Button)getActivity().findViewById(R.id.btn_pickChart);
button.setText(newBtnxt);
}
Minha pergunta é: por que ele atualiza o texto na GUI (ao executar o aplicativo) por meio do fragmento, mas não por meio da atividade, ou seja, o método p1_button.setText(response);?
EDITAR resposta conforme explicado por Raghunandan:O problema é que eu não entendi isso onClick_testSite(View view)
concluído mesmo que você não tenha clicado em nada na caixa de diálogo, pensei que esperava com a chamada de função de chartType.show()
para que ele retorne e prossiga para o final da função.
Solução
Você precisa inicializar public AsyncResponse delegate = null;
delegate =(AsyncResponse) getActivity();
Acredito que este seja o método implementado
@Override
public void processFinish(String response)
{
Log.i(".........",response); // check if the response is logged
// if you get the response your button text will be changed
// else you need to look at why the response is not logged.
p1_button.setText(response);
}
Declarar Button p1_button
como variável de instância (por exemplo, antes de onCreate).
Inicialize isto
p1_button = (Button)findViewById(R.id.btn_pickChart); // in onCreate
Provavelmente o botão é atualizado antes mesmo da resposta ser recebida em processFinish
.Então você inicializa a variável de resposta.Portanto, o texto do botão será definido na próxima vez que você clicar no botão.
Você pode declarar o botão antes de onCreate e atualizá-lo em processFinish
em vez disso, como hwon acima.
Outras dicas
O ProcessFinish salva o valor em resposta.Mas isso não se aplica ao TextView com btn_pickChart eu ia.
Então, você só precisa salvar a instância do TextView for Activity:
private Button mP1Button;
protected void onCreate(Bundle savedInstanceState) {
...
Button mP1Button = (Button) findViewById(R.id.btn_pickChart);
...
}
E aplique o valor alterado quando ProcessFinish é chamado:
public void processFinish(String response) {
this.response = response;
// The value will be setup to the view element.
mP1Button.setText(response);
}
Da melhor forma, não use o delegado como campo.Você pode usar getActivity() ou getTargetFragment() para verificar instanceOf AsyncResponse e chamar o método processFinish.
AsyncResponse asyncResponse = null;
if(getActivity() instanceof AsyncResponse) {
asyncResponse = (AsyncResponse) getActivity();
} else if (getTargetFragment() instanceof AsyncResponse){
asyncResponse = (AsyncResponse) getTargetFragment();
}
if(asyncResponse != null){
asyncResponse.processFinish(strName);
}
A propósito, não há necessidade de ligar para o invalidar método depois definirTexto porque já é chamado daqui.