Devo sostituire la maiuscole / minuscole delle funzioni determinate dalle opzioni nell'attività precedente?

1

Ad esempio, supponiamo che la mia app abbia 3 passaggi con 3 pagine:

Passaggio 1: MainActivity: scegli il colore

Passaggio2:EditTextActivity:inputtext

Passaggio3:GreenActivity:mostracoloreetestodiinput

InEditTextActivity,qualeattivitàandaredopoaverpremutoNextdipendedallaprecedenteMainActivity,quindiscrivouncasoswitchperfarlo:

MainActivity:

publicclassMainActivityextendsAppCompatActivity{@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);this.setTitle("Step 1");
    }

    public void redTheme(View view){
        Intent i=new Intent(this,EditTextActivity.class);
        i.putExtra("callbackId",0);
        this.startActivity(i);
    }

    public void greenTheme(View view){
        Intent i=new Intent(this,EditTextActivity.class);
        i.putExtra("callbackId",1);
        this.startActivity(i);
    }

    //similar for BlueActivity
    .
    .
    .
}

EditTextActivity:

public class EditTextActivity extends AppCompatActivity {
    public int callbackId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_text);
        this.setTitle("Step 2");
        this.callbackId=this.getIntent().getIntExtra("callbackId",0);
    }

    public void next(View view){
        switch (this.callbackId){
            case 0: {
                Intent i2 = new Intent(this, RedActivity.class);
                EditText editText = (EditText) this.findViewById(R.id.editText);
                i2.putExtra("text", editText.getText().toString());
                this.startActivity(i2);
                break;
            }
            case 1: {
                Intent i2 = new Intent(this, GreenActivity.class);
                EditText editText = (EditText) this.findViewById(R.id.editText);
                i2.putExtra("text", editText.getText().toString());
                this.startActivity(i2);
                break;
            }
            //similar for BlueActivity
            .
            .
            .
        }
    }
}

Ma penso che sia un incubo di mantenimento: quando aggiungo una nuova attività di colore, ad es. YellowActivity, ho bisogno di modificare sia MainActivity che EditTextActivity e quindi aggiungere una nuova opzione switch. Vorrei che la logica del pulsante Avanti fosse posizionata in MainActivity e quindi utilizzo il mio meccanismo di callback:

MainActivity:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.setTitle("Step 1");
    }

    public void redTheme(View view){
        Intent i=new Intent(this,EditTextActivity.class);
        final EditTextActivity.Callback callback= new EditTextActivity.Callback() {
            @Override
            public void run(EditTextActivity editTextActivity) {
                Intent i2=new Intent(editTextActivity,RedActivity.class);
                EditText editText=(EditText)editTextActivity.findViewById(R.id.editText);
                i2.putExtra("text",editText.getText().toString());
                editTextActivity.startActivity(i2);
                EditTextActivity.callbackMap.remove(editTextActivity.callbackId);
            }
        };
        int hashCode=callback.hashCode();
        EditTextActivity.callbackMap.put(hashCode,callback);
        i.putExtra("callbackId",hashCode);
        this.startActivity(i);
    }

    public void greenTheme(View view){
        Intent i=new Intent(this,EditTextActivity.class);
        final EditTextActivity.Callback callback= new EditTextActivity.Callback() {
            @Override
            public void run(EditTextActivity editTextActivity) {
                Intent i2=new Intent(editTextActivity,GreenActivity.class);
                EditText editText=(EditText)editTextActivity.findViewById(R.id.editText);
                i2.putExtra("text",editText.getText().toString());
                editTextActivity.startActivity(i2);
                EditTextActivity.callbackMap.remove(editTextActivity.callbackId);
            }
        };
        int hashCode=callback.hashCode();
        EditTextActivity.callbackMap.put(hashCode,callback);
        i.putExtra("callbackId",hashCode);
        this.startActivity(i);
    }

    //similar for BlueActivity
    .
    .
    .
}

EditTextActivity:

public class EditTextActivity extends AppCompatActivity {
    public interface Callback{
        public void run(EditTextActivity editTextActivity);
    }
    public static Map<Integer,Callback> callbackMap=new HashMap<>();

    public int callbackId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_text);
        this.setTitle("Step 2");
        this.callbackId=this.getIntent().getIntExtra("callbackId",0);
    }

    public void buttonPressed(View view){
        callbackMap.get(this.callbackId).run(this);
    }
}

Che uso una mappa statica per contenere i callback anziché incorporati nel caso di switch, e ora posso aggiungere una nuova operazione del pulsante Next senza modificare EditTextActivity.

Tuttavia, ho trovato che questo meccanismo è molto più complicato di quello originale:

  1. Contiene più codici
  2. Il nuovo approccio è meno diretto di quello originale, che temo che i miei compagni di squadra non riescano a capire cosa sto cercando di fare.
  3. Il modo standard in molti documenti sembra solo utilizzare il caso switch

Quindi la mia domanda è: dovrei eliminare il caso switch in questo caso?

Nota: sto chiedendo l'approccio generale di passare funzioni o callback all'attività successiva, non specifico per questo caso. Quindi non dare suggerimenti come "passare la stringa di colore su EditTextActivity".

    
posta ggrr 17.08.2017 - 08:35
fonte

1 risposta

2

Prima di scomporre il codice duplicato, puoi arrivare a una soluzione completamente diversa.

Se prendo la prima versione (con switch) e refactoring il codice duplicato, si finisce con qualcosa di simile

public class EditTextActivity extends AppCompatActivity {
    public int callbackId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_text);
        this.setTitle("Step 2");
        this.callbackId=this.getIntent().getIntExtra("callbackId",0);
    }

    public void next(View view){
        Intent i2;
        switch (this.callbackId){
            case 0: {
                i2 = new Intent(this, RedActivity.class);
                break;
            }
            case 1: {
                i2 = new Intent(this, GreenActivity.class);
                break;
            }
            //similar for BlueActivity
            .
            .
            .
        }
        EditText editText = (EditText) this.findViewById(R.id.editText);
        i2.putExtra("text", editText.getText().toString());
        this.startActivity(i2);
    }
}

Ora puoi vedere che l'unica vera variazione è quale Intent creare per l'attività di follow-on.
Una modifica logica ora è quella di non passare in un int, ma piuttosto il Intent da attivare successivamente, o la classe Activity che dovrebbe essere usata per creare il Intent .
Poiché gli oggetti di passaggio in questo modo non sembrano fattibili in Android, la cosa migliore è simile alla mappa statica utilizzata:

MainActivity:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.setTitle("Step 1");
    }

    public void redTheme(View view){
        Intent i=new Intent(this,EditTextActivity.class);
        int hashCode=callback.hashCode();
        EditTextActivity.callbackMap.put(hashCode,RedActivity.class);
        i.putExtra("callbackId",hashCode);
        this.startActivity(i);
    }

    public void greenTheme(View view){
        Intent i=new Intent(this,EditTextActivity.class);
        int hashCode=callback.hashCode();
        EditTextActivity.callbackMap.put(hashCode,GreenActivity.class);
        i.putExtra("callbackId",hashCode);
        this.startActivity(i);
    }

    //similar for BlueActivity
    .
    .
    .
}

EditTextActivity:

public class EditTextActivity extends AppCompatActivity {
    public static Map<Integer,Class<? extends Activity>> callbackMap=new HashMap<>();

    public int callbackId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_text);
        this.setTitle("Step 2");
        this.callbackId=this.getIntent().getIntExtra("callbackId",0);
    }

    public void next(View view){
        Intent i2 = new Intent(this, callbackMap.get(this.callbackId));
        EditText editText = (EditText) this.findViewById(R.id.editText);
        i2.putExtra("text", editText.getText().toString());
        this.startActivity(i2);
    }
}
    
risposta data 17.08.2017 - 12:43
fonte

Leggi altre domande sui tag