Autore Topic: Ruotando lo smartphone si innesca metodo in activity non voluto.  (Letto 303 volte)

Offline censore

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Wiko
  • Sistema operativo:
    Windows 10
0
Salve a tutti. Premetto sono un neofita.
Dunque ho un activity con 4 fragments: in ogni fragment raccolgo dati che passo all'activity.
I dati li raccolgo con edittext e textwatcher, oppure con radiobutton e checkbox. Il problema nasce dai fragment con gli edittext.
Inserito qualcosa nella edittext, richiamo un metodo nell'activity che, in un array boolean, varia una cella da false a true (per tenere conto se sono stati inseriti tutti i dati).
Se non ruoto il cellulare, funziona tutto. Ma se ruoto il cell, appena aperta l'app, con gli edittext vuoti (senza neanche aver aperto la tastiera), non son come o perché, il metodo viene richiamato e mi trovo l'array variato nelle celle riferite agli edittext del frammento n. 1 e n. 2, sia che mi sia posizionato sul primo sia sul secondo.
Ho provato ad eliminare il richiamo del metodo dal textwatcher, e non si verifica l'errore. Inserendo il richiamo del metodo nella interfaccia nell'activity (in modo che oltre a raccogliere i dati vari l'array) e non nei fragment, questo problema si ripresenta.
Non so cosa fare.
ecco il codice della mia activity:
Codice: [Seleziona]
public class MainActivity extends AppCompatActivity implements FragmentTab1.OnFragmentInteractionListener1,
        FragmentTab2.OnFragmentInteractionListener2, FragmentTab3.OnFragmentInteractionListener3, FragmentTab4.OnFragmentInteractionListener4 {

    private final Context context = this;
    // definisco un ArrayList
    private ControlloInput esame = new ControlloInput();

    //private FragmentTab1 tab1;
    private BottigliaDiVino botte = new BottigliaDiVino();
    boolean[] verifiche = new boolean[26];//array verifica inserimento campi
    private final String[] campi = new String[]{"manifestazione", "nome", "commissione", "data", "ora",
            "categoria", "campione", "designazione", "annata", "percorso",
            "VISTA limpidezza", "VISTA tonalità", "VISTA intensità",
            "OLFATTO franchezza", "OLFATTO intensità", "OLFATTO finezza", "OLFATTO armonia",
            "GUSTO franchezza", "GUSTO intensità", "GUSTO corpo", "GUSTO armonia", "GUSTO persistenza", "GUSTO Retrogusto", "Giudizio Complessivo",
            "V.Q.P.R.D.", "Osservazioni"};


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

        ViewPagerAdapter mSectionsPagerAdapter;
        ViewPager mViewPager;

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(mViewPager);
/*
        //carico arraylist
        for (int i = 0; i < campi.length; i++) {
            listp.add(campi[i]);
        }
*/
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int inserimenti = contaInput();
                Log.v("inserimenti", String.valueOf(inserimenti));
                for (boolean aVerifiche : verifiche) {
                    Log.v("inserimenti", String.valueOf(aVerifiche));
                }


                if (inserimenti == verifiche.length) {
                    riepilogo();
                    createPdf();
                } else {
                    //manifesto();
                    dialogo();
                    //riepilogo();


                }
            }
        });


    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onFragmentInteraction1(String manifestazione, String nome, String commissione, String data, String ora) {
        botte.set_manifestazione(manifestazione);
        botte.set_nome(nome);
        botte.set_commissione(commissione);
        botte.set_data(data);
        botte.set_ora(ora);

        for(int i=0; i<5; i++){
            verificaInput(i);
        }

    }

    @Override
    public void onFragmentInteraction2(String categoria, String campione, String designazione, String annata, String percorso) {
        botte.set_categoria(categoria);
        botte.set_campione(campione);
        botte.set_designazione(designazione);
        botte.set_annata(annata);
        botte.set_percorso(percorso);

    }

    @Override
    public void onFragmentInteraction3(int[] voto) {
        String[] appoggio = new String[14];
        for (int i = 0; i < 14; i++) {
            appoggio[i] = Integer.toString(voto[i]);
        }
        botte.setVoti(appoggio);
    }

    @Override
    public void onFragmentInteraction4(boolean[] difetti, int vqprd, String osservazioni) {
        botte.setDifetti(difetti);
        botte.setVqprd(vqprd);
        botte.setOsservazioni(osservazioni);

    }

    //aggiornamento stato inserimento campi
    public void verificaInput(int i) {
        verifiche[i] = true;
    }

    //conteggio input
    private int contaInput() {
        int totale = 0;
        for (boolean aVerifiche : verifiche) {
            if (aVerifiche) {
                totale++;
            }
        }
        return totale;
    }

    /*
        public void manifesto(){
            // get your custom_toast.xml ayout
            LayoutInflater inflater = getLayoutInflater();

            View layout = inflater.inflate(R.layout.custom_toast,
                    (ViewGroup) findViewById(R.id.custom_toast_layout_id));

            String messaggio ="";

            for(int i=0; i<24; i++){
                if(!verifiche[i]){
                    messaggio = messaggio + campi[i] + "\n";
                }

            }

            // set a message
            TextView text1 = (TextView) layout.findViewById(R.id.text1);
            text1.setText("Non sono stati avvalorati i seguenti campi:");
            TextView text2 = (TextView) layout.findViewById(R.id.text2);
            text2.setText(messaggio);

            Log.v("messaggio",messaggio);


            // Toast...
            Toast toast = new Toast(getApplicationContext());
            toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
            toast.setDuration(Toast.LENGTH_LONG);
            toast.setView(layout);
            toast.show();
        }
    */
    private void dialogo() {
        // custom dialog
        final Dialog dialog = new Dialog(context);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.custom);

        //dialog.setTitle("Alert");
        dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);


        // recupero la lista dal layout
        final ListView mylist = (ListView) dialog.findViewById(R.id.listView1);

        final ArrayList<String> listp = new ArrayList<>();
        //carico arraylist
        for (int i = 0; campi.length > i; i++) {
            if (!verifiche[i]) {
                listp.add(campi[i]);
            }
        }

        // creo e istruisco l'adattatore
        final ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listp);

        // inietto i dati
        mylist.setAdapter(adapter);

        Button dialogButton = (Button) dialog.findViewById(R.id.conferma);
        // if button is clicked, close the custom dialog
        dialogButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

        dialog.show();
    }

    private void riepilogo() {
        Log.v("manifestazione", botte.get_manifestazione());
        Log.v("nome", botte.get_nome());
        Log.v("commissione", botte.get_commissione());
        Log.v("data", botte.get_data());
        Log.v("ora", botte.get_ora());
        Log.v("categoria", botte.get_categoria());
        Log.v("designazione", botte.get_designazione());
        Log.v("campione", botte.get_campione());
        Log.v("annata", botte.get_annata());
        Log.v("percorso", botte.get_percorso());

        String[] voti;
        voti = botte.getVoti();
        for (String i : voti) {
            Log.v("voto", i);
        }

        boolean[] difetti;
        difetti = botte.getDifetti();
        for (boolean i : difetti) {
            Log.v("difetti", String.valueOf(i));
        }

        Log.v("vqprd", String.valueOf(botte.getVqprd()));
        Log.v("osservazioni", botte.getOsservazioni());

    }

    private void createPdf() {
        String[] campi = {"vista_limpidezza", "vista_tonalita", "vista_intensita",
                "olfatto_franchezza", "olfatto_intensita", "olfatto_finezza", "olfatto_armonia",
                "gusto_franchezza", "gusto_intensita", "gusto_corpo", "gusto_armonia", "gusto_persistenza",
                "gusto_retrogusto", "giudizio"
        };
        PdfReader reader;
        PdfStamper stamper;

        File pdfFolder = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES) + File.separator + "Pdfdemo");

        boolean success;
        if (!pdfFolder.exists()) {
            success = pdfFolder.mkdir();
            if (success) {
                // Do something on success
                Log.v("Crea /BottiglieDiVino", "Ho Creato nuova directory");
            } else {
                // Do something else on failure
                Log.v("Crea /BottiglieDiVino", "ERRORE nel creare nuova directory");
            }
        }

        //Create time stamp
        Date date = new Date();
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date);

        try {
            File myFile = File.createTempFile(
                    timeStamp,
                    ".pdf",
                    pdfFolder);

            reader = new PdfReader(getResources().openRawResource(R.raw.scheda));
            stamper = new PdfStamper(reader, new FileOutputStream(myFile));
            AcroFields acroFields = stamper.getAcroFields();

            acroFields.setField("manifestazione", botte.get_manifestazione());
            acroFields.setField("assaggiatore", botte.get_nome());
            acroFields.setField("commissione", botte.get_commissione());
            acroFields.setField("data", botte.get_data());
            acroFields.setField("ora", botte.get_ora());
            acroFields.setField("categoria", botte.get_categoria());
            acroFields.setField("designazione", botte.get_designazione());
            acroFields.setField("campione", botte.get_campione());
            acroFields.setField("annata", botte.get_annata());

            String[] voti;
            voti = botte.getVoti();
            for (int i = 0; i < 14; i++) {
                acroFields.setField(campi[i], voti[i]);
            }

            String[] difetti_campi = {"biologica", "chimico", "accidentale", "congenita"};
            boolean[] difetti;
            difetti = botte.getDifetti();
            for (int i = 0; i < 4; i++) {
                if (difetti[i]) {
                    acroFields.setField(difetti_campi[i], "Sì");
                }
            }

            acroFields.setField("vqprd", String.valueOf(botte.getVqprd()));
            acroFields.setField("osservazioni", botte.getOsservazioni());

            stamper.setFormFlattening(true);
            stamper.close();
            reader.close();

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(myFile), "application/pdf");
            intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
            startActivity(intent);

        } catch (DocumentException | IOException e) {
            e.printStackTrace();
        }


    }


}
ed ecco il primo fragment:
Codice: [Seleziona]
public class FragmentTab1 extends Fragment {
    //verifica campi inseriiti
    private boolean[] verifiche = new boolean[5];
    //valori inseriti
    private String manifestazione;
    private String nome;
    private String commissione;
    private String data;
    private String ora;
    //EditText
    EditText input_manifestazione;
    EditText input_nome;
    EditText input_commissione;
    EditText input_data;
    EditText input_ora;
    //interfaccia per passare dati all'Activity
    private OnFragmentInteractionListener1 mListener;
/*
    //interfaccia unica in ascolto dell'inserimento testo
    private TextWatcher generalTextWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            if (input_manifestazione.getText().hashCode() == s.hashCode()) {
                manifestazione = input_manifestazione.getText().toString();
                ((MainActivity) getActivity()).verificaInput(0);
                provaInput(0);
            } else if (input_nome.getText().hashCode() == s.hashCode()) {
                nome = input_nome.getText().toString();
                ((MainActivity) getActivity()).verificaInput(1);
                provaInput(1);
            } else if (input_commissione.getText().hashCode() == s.hashCode()) {
                commissione = input_commissione.getText().toString();
                ((MainActivity) getActivity()).verificaInput(2);
                provaInput(2);
            } else if (input_data.getText().hashCode() == s.hashCode()) {
                data = input_data.getText().toString();
                ((MainActivity) getActivity()).verificaInput(3);
                provaInput(3);
            } else if (input_ora.getText().hashCode() == s.hashCode()) {
                ora = input_ora.getText().toString();
                ((MainActivity) getActivity()).verificaInput(4);
                provaInput(4);
            }
            int inserimenti = contaInput();
            if (inserimenti == 5) {
                mListener.onFragmentInteraction1(manifestazione, nome, commissione, data, ora);

            }
        }

    };
*/
    public FragmentTab1() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        final View rootView = inflater.inflate(R.layout.fragmenttab1, container, false);

        input_manifestazione = (EditText) rootView.findViewById(R.id.input_manifestazione);
        input_manifestazione.addTextChangedListener(new CustomWatcher(input_manifestazione));

        input_nome = (EditText) rootView.findViewById(R.id.input_nome);
        input_nome.addTextChangedListener(new CustomWatcher(input_nome));

        input_commissione = (EditText) rootView.findViewById(R.id.input_commissione);
        input_commissione.addTextChangedListener(new CustomWatcher(input_commissione));

        input_data = (EditText) rootView.findViewById(R.id.input_data);
        input_data.addTextChangedListener(new CustomWatcher(input_data));

        input_ora = (EditText) rootView.findViewById(R.id.input_ora);
        input_ora.addTextChangedListener(new CustomWatcher(input_ora));

        return rootView;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener1) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    //aggiornamento stato inserimento campi
    private void provaInput(int i) {
        verifiche[i] = true;
    }

    //conteggio input
    private int contaInput() {
        int totale = 0;
        for (boolean aVerifiche : verifiche) {
            if (aVerifiche) {
                totale++;
            }
        }
        return totale;
    }

    public interface OnFragmentInteractionListener1 {
        void onFragmentInteraction1(String manifestazione, String nome, String commissione, String data, String ora);
    }

    public class CustomWatcher implements TextWatcher {
        private View view;
        public CustomWatcher(View view) {
            this.view = view;
        }

        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        public void onTextChanged(CharSequence s, int start, int before, int count) {
        }

        public void afterTextChanged(Editable editable) {
            String text = editable.toString();
            switch (view.getId()) {
                case R.id.input_manifestazione:
                    manifestazione = text;
                    //manifestazione = input_manifestazione.getText().toString();

                        //((MainActivity) getActivity()).verificaInput(0);
                        provaInput(0);


                    break;
                case R.id.input_nome:
                    nome = text;
                    //((MainActivity) getActivity()).verificaInput(1);
                    provaInput(1);
                    break;
                case R.id.input_commissione:
                    commissione = text;
                    //commissione = input_manifestazione.getText().toString();
                    //((MainActivity) getActivity()).verificaInput(2);
                    provaInput(2);
                    break;
                case R.id.input_data:
                    data = text;
                    //((MainActivity) getActivity()).verificaInput(3);
                    provaInput(3);
                    break;
                case R.id.input_ora:
                    ora = text;
                    Log.v("input ora", "strada");
                    //((MainActivity) getActivity()).verificaInput(4);
                    provaInput(4);
                    break;
            }
            int inserimenti = contaInput();
            Log.v("manifestazione", manifestazione);

            if (inserimenti == 5) {

                mListener.onFragmentInteraction1(manifestazione, nome, commissione, data, ora);
                Log.v("manifestazione", manifestazione);
                Log.v("nome", nome);
                Log.v("commissione", commissione);
                Log.v("data", data);
                Log.v("ora", ora);
            }


        }
    }
}
Infine, spostandomi su altro fragment, il quarto, ruotando il cell, l'array viene riportato allo stato originario con le celle prima variate a true (con la sola rotazione) che ritornano true, e la sola cella della edittext del fragment in questione variata  a true.
L'array in questione è boolean[] verifiche in activity, il metodo verificainput() in activity.
Se al posto dell'array boolean uso variabili boolean, non accade alcun problema.
Vi prego non so più cosa fare.
Aiuto
Grazie
« Ultima modifica: 22 Luglio 2016, 12:23:32 CEST da censore »

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Ruotando lo smartphone si innesca metodo in activity non voluto.
« Risposta #1 il: 26 Luglio 2016, 18:31:02 CEST »
0
So che sono passati alcuni giorni, hai forse già risolto il problema?

Stavo dando un occhiata al tuo codice e non trovo dove vengono allocati i Fragment del ViewPager.
Sono forse contenuti nel layout? O allocati in un custom ViewPagerAdapter che non hai postato?

Mi son perso nel seguire il codice che hai postato (è troppo), ma ti dò due consigli/informazioni.
 - Quando "giri il device", l'Activity viene ricreata da capo ed è "nuova", i Fragment invece solitamente no (dipende da alcune condizioni, leggi questo mio vecchio messaggio http://www.anddev.it/index.php/topic,6717.msg82437.html#msg82437). Questo può creare problemi in alcuni casi, tienine conto.
 - Il ViewPager di default tiene vivi solo alcuni dei fragment delle pagine (mi pare uno a dx ed uno a sx, rispetto la posizione corrente). Prova a fare setOffscreenPageLimit al tuo numero di pagine per essere sicuro che non crei o distrugga alcun Fragment.

Guarda, ti aggiungo pure un ulteriore consiglio:
 - Prima di postare un problema, cerca di localizzarlo e ridurlo a poche righe di codice. Sarà più facile che qualcuno si prenda la briga di leggerlo tutto.

Ciao

Offline censore

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Wiko
  • Sistema operativo:
    Windows 10
Re:Ruotando lo smartphone si innesca metodo in activity non voluto.
« Risposta #2 il: 01 Agosto 2016, 13:05:19 CEST »
0
Dunque, io uso un ViewPagerAdapter ecco il codice:
Codice: [Seleziona]
class ViewPagerAdapter extends FragmentPagerAdapter {

    public ViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).

        switch (position) {

            // Open FragmentTab1.java
            case 0:
                return new FragmentTab1();

            // Open FragmentTab2.java
            case 1:
                return new FragmentTab2();

            // Open FragmentTab3.java
            case 2:
                return new FragmentTab3();
            case 3:
                return new FragmentTab4();
        }
        return null;
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return 4;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return "SECTION 1";
            case 1:
                return "SECTION 2";
            case 2:
                return "SECTION 3";
            case 3:
                return "SECTION 4";
        }
        return null;
    }
Ho compreso che girando il cell viene ricreato Fragment e/o Activity, ma io non afferro perché venga innescato il TextWatcher seppur il campo EditText sia nullo (niente sia stato inserito).
Infine, come mai questo controllo non ha alcun effetto ed il metodo viene richiamato nell'Activity?

Codice: [Seleziona]
        public void afterTextChanged(Editable editable) {
            String text = editable.toString();

            switch (view.getId()) {
                case R.id.input_manifestazione:
                    manifestazione = text;
                    if(manifestazione != ""){
                        mListener.onFragmentInteraction00(manifestazione);
                    }

Io Sto impazzendo!

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Ruotando lo smartphone si innesca metodo in activity non voluto.
« Risposta #3 il: 02 Agosto 2016, 10:45:55 CEST »
0
Quello che ti posso dire è che nella condizione in cui sei l'Activity viene ricreata da 0, mentre i Fragment sopravvivono e vengono riattaccati alla nuova Activity.
Verifica quello che ti succede alla luce di questa informazione.

Inoltre, hai provato a mettere setOffscreenPageLimit( 4 ) nel ViewPager?

Ciao, mi spiace non poterti essere più utile, ma sto partendo per le ferie... :)

Offline censore

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Wiko
  • Sistema operativo:
    Windows 10
Re:Ruotando lo smartphone si innesca metodo in activity non voluto.
« Risposta #4 il: 02 Agosto 2016, 15:20:24 CEST »
0
Ho risolto il problema inserendo questo controllo:
Codice: [Seleziona]
        public void afterTextChanged(Editable editable) {
            String text = editable.toString();

            switch (view.getId()) {
                case R.id.input_manifestazione:
                    if(text.length() > 0 ){
                        mListener.onFragmentInteraction00(text);
                    }
                    break;
In questo modo, sebbene si inneschi il TextWatcher ruotando il cell, se il campo EditText è vuoto, nulla è stato inserito, il flusso non ritorna all'Activity.