Organizar o código - App Calculadora

Boa noite pessoal, estou aprendendo Android e nada melhor do que desenvolver uma Calculadora =D
As funcionalidades estão praticamente todas desenvolvidas, agora preciso de dicas e ajuda para organizar meu código pois está um lixo, eu reconheço. Botei tudo dentro do método onCreate()…até comecei a fazer um método carregarComponentes ali mas não sei o que fazer pra organizar este código.

package br.com.calculadorak;

import java.text.DecimalFormat;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.text.DecimalFormat;
import java.util.Locale;

public class MainActivity extends Activity {
	public double numero1;
	public double numero2;
	public double total;
	public DecimalFormat formatarResultadoInteiro, formatarResultadoDecimal;

	public int operacao = 0;
	
	public void carregarComponentes(){
		Locale.setDefault(Locale.US); // configura o local para facilitar as operacoes com virgula =)
	}

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

		carregarComponentes();
		
		final TextView visor = (TextView) findViewById(R.id.visor);

		// Botões Numéricos
		final Button btnNum0 = (Button) findViewById(R.btn.btnNum0);
		final Button btnNum1 = (Button) findViewById(R.btn.btnNum1);
		final Button btnNum2 = (Button) findViewById(R.btn.btnNum2);
		final Button btnNum3 = (Button) findViewById(R.btn.btnNum3);
		final Button btnNum4 = (Button) findViewById(R.btn.btnNum4);
		final Button btnNum5 = (Button) findViewById(R.btn.btnNum5);
		final Button btnNum6 = (Button) findViewById(R.btn.btnNum6);
		final Button btnNum7 = (Button) findViewById(R.btn.btnNum7);
		final Button btnNum8 = (Button) findViewById(R.btn.btnNum8);
		final Button btnNum9 = (Button) findViewById(R.btn.btnNum9);

		// Botões operações
		final Button btnSomar = (Button) findViewById(R.btn.btnSomar);
		final Button btnSubtrair = (Button) findViewById(R.btn.btnSubtrair);
		final Button btnDividir = (Button) findViewById(R.btn.btnDividir);
		final Button btnMultiplicar = (Button) findViewById(R.btn.btnMultiplicar);

		// Outros botões
		final Button btnEfetuarOperacao = (Button) findViewById(R.btn.btnEfetuarOperacao);
		final Button btnLimpar = (Button) findViewById(R.btn.btnLimpar);
		final Button btnApagar = (Button) findViewById(R.btn.btnApagar);
		final Button btnPonto = (Button) findViewById(R.btn.btnPonto);
		final Button btnMaisMenos = (Button) findViewById(R.btn.btnMaisMenos);

		// Listeners - Números
		btnNum0.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				String valorAnterior = visor.getText().toString();
				visor.setText(valorAnterior + btnNum0.getText().toString());
			}
		});

		btnNum1.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				String valorAnterior = visor.getText().toString();
				visor.setText(valorAnterior + btnNum1.getText().toString());
			}
		});

		btnNum2.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				String valorAnterior = visor.getText().toString();
				visor.setText(valorAnterior + btnNum2.getText().toString());
			}
		});

		btnNum3.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				String valorAnterior = visor.getText().toString();
				visor.setText(valorAnterior + btnNum3.getText().toString());
			}
		});

		btnNum4.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				String valorAnterior = visor.getText().toString();
				visor.setText(valorAnterior + btnNum4.getText().toString());
			}
		});

		btnNum5.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				String valorAnterior = visor.getText().toString();
				visor.setText(valorAnterior + btnNum5.getText().toString());
			}
		});

		btnNum6.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				String valorAnterior = visor.getText().toString();
				visor.setText(valorAnterior + btnNum6.getText().toString());
			}
		});

		btnNum7.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				String valorAnterior = visor.getText().toString();
				visor.setText(valorAnterior + btnNum7.getText().toString());
			}
		});

		btnNum8.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				String valorAnterior = visor.getText().toString();
				visor.setText(valorAnterior + btnNum8.getText().toString());
			}
		});

		btnNum9.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				String valorAnterior = visor.getText().toString();
				visor.setText(valorAnterior + btnNum9.getText().toString());
			}
		});
		// Listeners - Operações
		btnSomar.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (visor.getText().toString() != "") {
					numero1 = Double.parseDouble(visor.getText().toString());
					operacao = 1;
				}
				visor.setText("");
			}
		});

		btnSubtrair.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (visor.getText().toString() != "") {
					numero1 = Double.parseDouble(visor.getText().toString());
					operacao = 2;
				}
				visor.setText("");
			}
		});

		btnDividir.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (visor.getText().toString() != "") {
					numero1 = Double.parseDouble(visor.getText().toString());
					operacao = 3;
				}
				visor.setText("");
			}
		});

		btnMultiplicar.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (visor.getText().toString() != "") {
					numero1 = Double.parseDouble(visor.getText().toString());
					operacao = 4;
				}
				visor.setText("");
			}
		});

		
		// formatando numeros
		formatarResultadoInteiro = new DecimalFormat("#");
		formatarResultadoDecimal = new DecimalFormat("#.##");
		
		btnEfetuarOperacao.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				switch (operacao) {
				case 1:
					numero2 = Double.parseDouble(visor.getText().toString());
					total = numero1 + numero2;
					if ((int)total == total) {
						visor.setText(String.valueOf(formatarResultadoInteiro.format(total)));
					} else {
						visor.setText(String.valueOf(formatarResultadoDecimal.format(total)));
					}
					
					break;
				case 2:
					numero2 = Double.parseDouble(visor.getText().toString());
					total = numero1 - numero2;
					if ((int)total == total) {
						visor.setText(String.valueOf(formatarResultadoInteiro.format(total)));
					} else {
						visor.setText(String.valueOf(formatarResultadoDecimal.format(total)));
					}
					break;
				case 3:
					numero2 = Double.parseDouble(visor.getText().toString());
					total = numero1 / numero2;
					if ((int)total == total) {
						visor.setText(String.valueOf(formatarResultadoInteiro.format(total)));
					} else {
						visor.setText(String.valueOf(formatarResultadoDecimal.format(total)));
					}
					break;
				case 4:
					numero2 = Double.parseDouble(visor.getText().toString());
					total = numero1 * numero2;
					if ((int)total == total) {
						visor.setText(String.valueOf(formatarResultadoInteiro.format(total)));
					} else {
						visor.setText(String.valueOf(formatarResultadoDecimal.format(total)));
					}
					break;
				default:
					break;
				}
			}
		});

		// Demais botoes
		btnLimpar.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				visor.setText("");
			}
		});
		
		btnApagar.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v){
				String visorApg = visor.getText().toString();
				try {
					visorApg = visorApg.substring(0, visorApg.length() - 1);	
				} catch (Exception e) {} // Se a string for vazia ocorre erro StringIndexOutOfBoundsException
				visor.setText(visorApg);
			}
		});
		
		btnPonto.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				String visorPonto = visor.getText().toString();
				visorPonto += new String(".");
				visor.setText(visorPonto);
			}
		});
		
		btnMaisMenos.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				double visorSinal = Double.parseDouble(visor.getText().toString());
				visorSinal *= -1;
				if ((int)visorSinal == visorSinal) {
					visor.setText(String.valueOf(formatarResultadoInteiro.format(visorSinal)));
				} else {
					visor.setText(String.valueOf(formatarResultadoDecimal.format(visorSinal)));
				}
			}
		});
	}
}

Voce pode comecar por isso que vc disse, retirar tudo dentro de um método só…

Pode fazer o seguinte:

deixar essa parte aqui:

[code]final TextView visor = (TextView) findViewById(R.id.visor);

    // Botões Numéricos  
    final Button btnNum0 = (Button) findViewById(R.btn.btnNum0);  
    // outros botoes       

[/code]
Para um metodo de criação dos botoes
Separar os métodos das operações, passando o que for preciso por parâmetro
Formatar números em outro método, por mais que seja 2 linhas
Efetuar operações, td em outro método
Limpar, apagar, ponto, maismenos um pra cada método tb

Depois disso ja vai da pra ter uma visão melhor, pra ir refatorando mais…
A idéia é essa, começa refatorando pelos mais básicos, aos poucos vai enxergando métodos que tem algo em comum, nisso vai juntando e separando conforme a necessidade

Eu deixaria mais clara a aplicaçãom de orientação a objetos.
Poderia ter uma classe para tratar dos botões e outra das operações.

  private void mostrarNumero(String numero) {
                String valorAnterior = visor.getText().toString();  
                visor.setText(valorAnterior + numero);  
  }

btnNum0.setOnClickListener(new View.OnClickListener() {  
            public void onClick(View v) {  
               mostrarNumero(btnNum0.getText().toString());
            }  
        });  

Obrigado pelas respostas pessoal, fiz uma refatoração e ficou legal.

Separei em métodos o carregamento dos botões, formatação dos números e recuperação/exibição/alteração dos números do visor e utilizei ENUM pra padronizar as operações.

Vejam o que acham e sugiram mais alterações. Valeu.

package br.com.calculadorak;

import java.text.DecimalFormat;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Locale;

public class MainActivity extends Activity {
	/*************************************************** ATRIBUTOS ****************************************************/
	public MainActivity calculadora;
	public double numero1;
	public double numero2;
	public double total;
	public DecimalFormat formatarResultadoInteiro, formatarResultadoDecimal;
	public Operacoes operacoes;
	
	enum Operacoes {
		SOMAR, SUBTRAIR, DIVIDIR, MULTIPLICAR;
	}
	
	/*************************************************** MÉTODOS ****************************************************/
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		carregarComponentes();
		carregarBotoesNumericos();
		carregarBotoesOperacoes();
		carregarDemaisBotoes();
		carregarBotaoOperacao();

	}
	
	public void formatarNumeros(double valor){
		// Instancia para formatação no padrão desejado
		formatarResultadoInteiro = new DecimalFormat("#");
		formatarResultadoDecimal = new DecimalFormat("#.##");
		
		// Lógica para descobrir número inteiros e decimais
		if ((int) valor == valor) {
			alterarValorVisor(String.valueOf(formatarResultadoInteiro.format(valor)));
		} else {
			alterarValorVisor(String.valueOf(formatarResultadoDecimal.format(valor)));
		}
	}
	
	public void exibirValorVisor(String valorBotao){
		final TextView visor = (TextView) findViewById(R.id.visor);
		String valorAnterior = visor.getText().toString();
		visor.setText(valorAnterior + valorBotao);
	}
	
	public String recuperarValorVisor(){
		final TextView visor = (TextView) findViewById(R.id.visor);
		return (visor.getText().toString());
	}
	
	public void alterarValorVisor(String valorBotao){
		final TextView visor = (TextView) findViewById(R.id.visor);		
		visor.setText(valorBotao);
	}

	public void carregarComponentes() {
		Locale.setDefault(Locale.US); // configura o local para facilitar as peracoes com virgula
		calculadora = new MainActivity();
	}

	public void carregarBotoesNumericos() {
		// Botões numéricos
		final Button btnNum0 = (Button) findViewById(R.btn.btnNum0);
		final Button btnNum1 = (Button) findViewById(R.btn.btnNum1);
		final Button btnNum2 = (Button) findViewById(R.btn.btnNum2);
		final Button btnNum3 = (Button) findViewById(R.btn.btnNum3);
		final Button btnNum4 = (Button) findViewById(R.btn.btnNum4);
		final Button btnNum5 = (Button) findViewById(R.btn.btnNum5);
		final Button btnNum6 = (Button) findViewById(R.btn.btnNum6);
		final Button btnNum7 = (Button) findViewById(R.btn.btnNum7);
		final Button btnNum8 = (Button) findViewById(R.btn.btnNum8);
		final Button btnNum9 = (Button) findViewById(R.btn.btnNum9);
		
		// Capturar Ações
		btnNum0.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				exibirValorVisor(btnNum0.getText().toString());
			}
		});

		btnNum1.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				exibirValorVisor(btnNum1.getText().toString());
			}
		});

		btnNum2.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				exibirValorVisor(btnNum2.getText().toString());
			}
		});

		btnNum3.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				exibirValorVisor(btnNum3.getText().toString());
			}
		});

		btnNum4.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				exibirValorVisor(btnNum4.getText().toString());
			}
		});

		btnNum5.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				exibirValorVisor(btnNum5.getText().toString());
			}
		});

		btnNum6.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				exibirValorVisor(btnNum6.getText().toString());
			}
		});

		btnNum7.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				exibirValorVisor(btnNum7.getText().toString());
			}
		});

		btnNum8.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				exibirValorVisor(btnNum8.getText().toString());
			}
		});

		btnNum9.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				exibirValorVisor(btnNum9.getText().toString());
			}
		});
	}

	public void carregarBotoesOperacoes() {
		// Botões operações
		final Button btnSomar = (Button) findViewById(R.btn.btnSomar);
		final Button btnSubtrair = (Button) findViewById(R.btn.btnSubtrair);
		final Button btnDividir = (Button) findViewById(R.btn.btnDividir);
		final Button btnMultiplicar = (Button) findViewById(R.btn.btnMultiplicar);
		
		// Capturar Ações
		btnSomar.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (recuperarValorVisor() != "") {
					numero1 = Double.parseDouble(recuperarValorVisor());
					operacoes = Operacoes.SOMAR;
				}
				alterarValorVisor("");
			}
		});

		btnSubtrair.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (recuperarValorVisor() != "") {
					numero1 = Double.parseDouble(recuperarValorVisor());
					operacoes = Operacoes.SUBTRAIR;
				}
				alterarValorVisor("");
			}
		});

		btnDividir.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (recuperarValorVisor() != "") {
					numero1 = Double.parseDouble(recuperarValorVisor());
					operacoes = Operacoes.DIVIDIR;
				}
				alterarValorVisor("");
			}
		});

		btnMultiplicar.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (recuperarValorVisor() != "") {
					numero1 = Double.parseDouble(recuperarValorVisor());
					operacoes = Operacoes.MULTIPLICAR;
				}
				alterarValorVisor("");
			}
		});
	}

	public void carregarDemaisBotoes() {
		// Demais botões
		final Button btnLimpar = (Button) findViewById(R.btn.btnLimpar);
		final Button btnApagar = (Button) findViewById(R.btn.btnApagar);
		final Button btnPonto = (Button) findViewById(R.btn.btnPonto);
		final Button btnMaisMenos = (Button) findViewById(R.btn.btnMaisMenos);
		
		// Capturar Ações
		btnLimpar.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				alterarValorVisor("");
			}
		});

		btnApagar.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				String valorVisor = recuperarValorVisor();
				try {
					valorVisor = valorVisor.substring(0, valorVisor.length() - 1);
				} catch (Exception e) {
				} // Se a string for vazia ocorre erro StringIndexOutOfBoundsException
				alterarValorVisor(valorVisor);
			}
		});

		btnPonto.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				String visorPonto = recuperarValorVisor();
				visorPonto += new String(".");
				alterarValorVisor(visorPonto);
			}
		});

		btnMaisMenos.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				double visorSinal = Double.parseDouble(recuperarValorVisor());
				visorSinal *= -1;
				formatarNumeros(visorSinal);
			}
		});
	}

	public void carregarBotaoOperacao() {
		// Botão igual 
		final Button btnEfetuarOperacao = (Button) findViewById(R.btn.btnEfetuarOperacao);
		
		// Capturar Ações
		btnEfetuarOperacao.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				switch (operacoes) {
				case SOMAR:
					numero2 = Double.parseDouble(recuperarValorVisor());
					total = numero1 + numero2;
					formatarNumeros(total);
					break;
				case SUBTRAIR:
					numero2 = Double.parseDouble(recuperarValorVisor());
					total = numero1 - numero2;
					formatarNumeros(total);
					break;
				case DIVIDIR:
					numero2 = Double.parseDouble(recuperarValorVisor());
					total = numero1 / numero2;
					formatarNumeros(total);
					break;
				case MULTIPLICAR:
					numero2 = Double.parseDouble(recuperarValorVisor());
					total = numero1 * numero2;
					formatarNumeros(total);
					break;
				default:
					break;
				}	
			}
		});
	}
}

[quote=alangaro.si@gmail.com]Eu deixaria mais clara a aplicaçãom de orientação a objetos.
Poderia ter uma classe para tratar dos botões e outra das operações.[/quote]

Como ficaria esta abordagem, classe de botões com os botões como atributos e seus respectivos listerners como métodos, e o mesmo para as operações?

[quote=gRoOve][quote=alangaro.si@gmail.com]Eu deixaria mais clara a aplicaçãom de orientação a objetos.
Poderia ter uma classe para tratar dos botões e outra das operações.[/quote]

Como ficaria esta abordagem, classe de botões com os botões como atributos e seus respectivos listerners como métodos, e o mesmo para as operações?[/quote]

provavelmente ele esta falando sobre usar o AsyncTask que permite fazer ações bloqueantes sem causar problemas na thread de UI.

protected class Task extends AsyncTask<String, Void, String>{
//AsyncTask<Entrada, Progresso, Saida>    

   @Override
    protected String doInBackground(String... params) {
        //Executa alto em uma thread em background
        try {
           int i0 = Interger.parseInt(params[0]);
           int i1 = Interger.parseInt(params[1]);
           String type = params[2]
           if("SUM".equals(type)){
           return String.valueOf(i0+i1);
           } else return String.valueOf(i0-i1);
        }catch(Exception e){ //veja exatamente quais problemas podem ocorrer e coloque a exception exata.
         return "ERROR";    
        }

    }

   @Override
   protected void onPostExecute(String result) {
        super.onPostExecute(result);
       //esse metodo roda na Thread de UI
       final TextView txtView1 = (TextView) findViewById(R.id.txtView1);       
       txtView1 .setText(valorBotao);      
    }

}
//thread da UI (activity)
protected Task  task = new Task();
task.execute(value1, valoue2);

fazer métodos de validação - geralmente esses métodos são estáticos para evitar replicação de código, mas como seu programa só possui uma class não creio que não seja necessário

public boolean isInteger(double arg0){
        if((int) arg0 == arg0){
        return true;
        }else return false;
}

Desculpe, Cliquei em Citar em vez de Editar.
moderador pode deletar esse post.