Autore Topic: Update ListFragment in Tab Layout quando l'Activity finisce  (Letto 450 volte)

Offline Drugsmatt

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S3
  • Sistema operativo:
    Windows 7/8
Update ListFragment in Tab Layout quando l'Activity finisce
« il: 11 Novembre 2015, 11:50:00 CET »
0
Ciao a tutti, premetto che sono agli inizi con Android e questa è la mia prima applicazione, quindi vi chiedo pazienza in anticipo!
Per utilità vi riporto la struttura dell'app: MainActivity composta da Tab Layout, 4 Tabs, ognuna contenente un ListFrgament (simil whatsapp per intenderci).
Ora, nella MainActivity premendo un tasto della ActionBar avvio un'Activity specifica per la creazione di un utente (CreateUser), quando questa finisce vorrei che il ListFragment contenuto nella Tab 3 si aggiornasse mostrando l'ultimo utente creato.
Attualmente riesco a creare l'utente, ma terminata l'Activity il ListFragment rimane così com'è, per aggiornarlo devo necessariamente cambiare Tab finchè non si ricarica mostrandomi l'ultima entry del db.

Ho provato l'approccio StartActivityForResult() ma nulla da fare, non richiama onActivityResult nel ListFragment, penso perchè l'Activity non essendo avviata direttamente dal ListFragment (ma dalla Action Bar) non sia collegata ad esso. Ora invece sto cercando di capire come utilizzare Observer/Observable ma ho delle difficoltà. Vi posto il codice.

CreateUser.java
Codice (Java): [Seleziona]
public class CreateUser extends AppCompatActivity {

  //La creazione dell'utente viene effettuata nella Classe ProcessCreateUser
  //la quale estende AsyncTask

  private class ProcessCreateUser extends AsyncTask<String, String, JSONObject> {

    //...
    //onPreExecute, doInBackground
    //...

    @Override
    protected void onPostExecute() {
        super.onPostExecute();

        //operazioni database...

        //a questo punto l'utente è stato aggiunto al db e l'Activity termina

        finish();
    }
  }

  public void onDestroy(){
        Tab3.updateFragmentList();
  }
}

Tab3.java
Codice (Java): [Seleziona]
public class Tab3 extends ListFragment implements Observer
{
    //in onActivityCreated(Bundle savedInstanceState) recupero i dati dal db e setto l'adapter

    @Override
    public void update(Observable observable, Object data) {

    }

    public static void updateFragmentList() {
       //Problema: non posso recuperare l'adapter da un metodo statico
       //ma dev'essere necessariamente statico per essere richiamato da CreateUser
       ((BaseAdapter)adapter).notifyDataSetChanged();
    }
}

In sostanza, nel ListFragment ho implementato Observer (con il metodo update) ma non posso estendere Observable in CreateUser perchè estendo già AsyncTask (e AppCompatActivity nella Classe principale), quindi non sapendo come fare ho cercato di richiamare il metodo updateFragmentList del ListFragment da CreateUser, ma essendo statico non riesco a richiamare l'adapter per il notifyDataSetChanged().

Non voglio per forza utilizzare Observer, l'importante è che riesca in qualche modo ad aggiornare il ListFragment a fine Activity.
Grazie in anticipo!
« Ultima modifica: 11 Novembre 2015, 11:51:40 CET da Drugsmatt »

Offline LonelyWolf

  • Utente junior
  • **
  • Post: 148
  • Respect: +12
    • Mostra profilo
    • Traversate dei laghi
  • Dispositivo Android:
    GT-I9505, ALE-L21
  • Sistema operativo:
    Windows 7 32/64
Re:Update ListFragment in Tab Layout quando l'Activity finisce
« Risposta #1 il: 11 Novembre 2015, 13:04:24 CET »
0
Puoi avviare l'activity di creazione utente con il metodo startActivityForResult, così ritorni il valore di avvenuta creazione al fragment che provvederà ad aggiornarsi, oppure ritornerà un valore che indica l'annullamento/errore della procedura (e quindi nessun aggiornamento).
Se la mia risposta ti è utile, per favore un thanks!

Offline Drugsmatt

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S3
  • Sistema operativo:
    Windows 7/8
Re:Update ListFragment in Tab Layout quando l'Activity finisce
« Risposta #2 il: 11 Novembre 2015, 13:15:14 CET »
0
Puoi avviare l'activity di creazione utente con il metodo startActivityForResult, così ritorni il valore di avvenuta creazione al fragment che provvederà ad aggiornarsi, oppure ritornerà un valore che indica l'annullamento/errore della procedura (e quindi nessun aggiornamento).

Ho già scritto di aver provato questa soluzione (rivedi il post) ma non funziona perchè onActivityResult nel ListFragment non viene richiamata (per i motivi già menzionati).

Offline LonelyWolf

  • Utente junior
  • **
  • Post: 148
  • Respect: +12
    • Mostra profilo
    • Traversate dei laghi
  • Dispositivo Android:
    GT-I9505, ALE-L21
  • Sistema operativo:
    Windows 7 32/64
Re:Update ListFragment in Tab Layout quando l'Activity finisce
« Risposta #3 il: 11 Novembre 2015, 13:35:32 CET »
0
Scusa ma ero un po' di corsa, sono stato un po' troppo stringato!

startActivityForResult deve essere lanciato dall'activity principale (quella che contiene i fragment per intenderci) perchè può accedere ad ogni proprio fragment, quindi può ricevere il risultato e far aggiornare il fragment; anche la actionbar dipende dall'activity principale.

Io invece, avendo esclusivamente fragment (anche per creazione degli oggetti nelle listview) ho creato delle semplici interfacce per far dialogare tra loro i vari fragment passando per la mainactivity.
« Ultima modifica: 11 Novembre 2015, 13:37:36 CET da LonelyWolf »
Se la mia risposta ti è utile, per favore un thanks!

Offline Drugsmatt

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S3
  • Sistema operativo:
    Windows 7/8
Re:Update ListFragment in Tab Layout quando l'Activity finisce
« Risposta #4 il: 11 Novembre 2015, 15:04:49 CET »
0
Tranquillo! Anzi, grazie per l'interessamento, purtroppo è un problema che mi perseguita da giorni ormai...
Ti faccio vedere come ho impostato l'approccio startActivityForResult (utilizzo un ViewPagerAdapter per la gestione dei Fragament).

MainActivity.java
Codice (Java): [Seleziona]
public class MainActivity extends AppCompatActivity {

    // Declaring Your View and Variables

    Toolbar toolbar;
    ViewPager pager;
    ViewPagerAdapter adapter;
    SlidingTabLayout tabs;
    CharSequence Titles[]={"1","2","3","4"};
    int Numboftabs =4;

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

        //
        // Creating The Toolbar and setting it as the Toolbar for the activity

        toolbar = (Toolbar) findViewById(R.id.tool_bar);
        //setSupportActionBar(toolbar);

        // Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
        adapter =  new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);

        // Assigning ViewPager View and setting the adapter
        pager = (ViewPager) findViewById(R.id.pager);
        pager.setAdapter(adapter);

        // Assiging the Sliding Tab Layout View
        tabs = (SlidingTabLayout) findViewById(R.id.tabs);
        tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width

        // Setting Custom Color for the Scroll bar indicator of the Tab View
        tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
            @Override
            public int getIndicatorColor(int position) {
                return ContextCompat.getColor(getApplicationContext(), R.color.darkgreen);
            }
        });

        // Setting the ViewPager For the SlidingTabsLayout
        tabs.setViewPager(pager);

    }

    @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();

        switch (id) {
            case R.id.action_settings:
                Intent intentMSett = new Intent(this, MainSettings.class);
                startActivity(intentMSett);
                break;
            case R.id.action_add_user:
                Intent intent = new Intent(this, CreateUser.class);
                startActivityForResult(intent, 101);
                break;
            case R.id.action_search:
                Toast.makeText(getApplicationContext(),
                        "search", Toast.LENGTH_SHORT).show();
                break;
        }

        return super.onOptionsItemSelected(item);
    }

}

Nota in onOptionsItemSelected il case.R.id.action_add_user, ho impostato l'intent e l'ho startato con un codice di risultato pari a 101.
In CreateUser invece imposto setResult(Activity.RESULT_OK) e finisco l'Activity. Di seguito:

CreateUser.java
 
Codice (Java): [Seleziona]
public class CreateUser extends AppCompatActivity {

  //La creazione dell'utente viene effettuata nella Classe ProcessCreateUser
  //la quale estende AsyncTask

  private class ProcessCreateUser extends AsyncTask<String, String, JSONObject> {

    //...
    //onPreExecute, doInBackground
    //...

    @Override
    protected void onPostExecute() {
        super.onPostExecute();

        //operazioni database...

        //a questo punto l'utente è stato aggiunto al db e l'Activity termina

        // imposto il result dell'Activity come positivo a indicare una creazione utente avvenuta con successo
        setResult(Activity.RESULT_OK)
        finish();
    }
  }

In Tab3.java invece (ListFragment) imposto onActivityResult (ti risparmio la parte dell'impostazione delle due varibili nella condizione IF)

Codice (Java): [Seleziona]
public class Tab3 extends ListFragment
{
    //in onActivityCreated(Bundle savedInstanceState) recupero i dati dal db e setto l'adapter...

    // metodo di ascolto risultato onActivityResult
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
        if ((requestCode == MYACTIVITY_REQUEST_CODE) && (resultCode == Activity.RESULT_OK))
            adapter.notifyDataSetChanged()
        }
}

Purtroppo però, alla fine dell'Activity CreateUser, onActivityResult non viene mai chiamato, ho verificato con un Log.v subito all'inizio del metodo.
C'è qualcosa di sbagliato secondo te?
Per completezza ti riporto anche la classe del ViewPager.

ViewPagerAdapter.java

Codice (Java): [Seleziona]
public class ViewPagerAdapter extends FragmentStatePagerAdapter {

    CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
    int NumbOfTabs; // Store the number of tabs, this will also be passed when the ViewPagerAdapter is created
    private Context context;

    // Build a Constructor and assign the passed Values to appropriate values in the class
    public ViewPagerAdapter(FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb) {
        super(fm);

        this.Titles = mTitles;
        this.NumbOfTabs = mNumbOfTabsumb;

    }

    //This method return the fragment for the every position in the View Pager
    @Override
    public Fragment getItem(int position) {

        if(position == 0) // if the position is 0 we are returning the First tab
        {
            Tab1 tab1 = new Tab1();
            return tab1;
        } else if(position == 1){
            Tab2 tab2 = new Tab2();
            return tab2;
        } else if(position == 2) {
            Tab3 tab3 = new Tab3();
            return tab3;
        } else if(position == 3) {
            Tab4 tab4 = new Tab4();
            return tab4;
        } else {
            Tab1 tab1 = new Tab1();
            return tab1;
        }
    }

    // This method return the titles for the Tabs in the Tab Strip

    @Override
    public CharSequence getPageTitle(int position) {

        return Titles[position];
    }

    // This method return the Number of tabs for the tabs Strip

    @Override
    public int getCount() {
        return NumbOfTabs;
    }
}

« Ultima modifica: 11 Novembre 2015, 15:07:51 CET da Drugsmatt »

Offline pietroconti89

  • Utente normale
  • ***
  • Post: 164
  • Respect: +19
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note 3 N9005
  • Sistema operativo:
    Windows / Mac OSX
Re:Update ListFragment in Tab Layout quando l\'Activity finisce
« Risposta #5 il: 11 Novembre 2015, 15:21:22 CET »
0
Ciao se esegui startActivityForResult(intent, 101); dal Activity Main, onActivityResult deve essere posizionato sulla stessa activity , cosi riesci a recuperare il tutto , se lo posizioni in un altro punto come in questo caso Tab3 , non funzionerà mai

Post unito: 11 Novembre 2015, 15:49:36 CET
comunque solo questo non ti basterà , neanche notificando l'adapter come giustamente fai ... ma un problema alla volta , intanto fatti tornare l'activity for result mettendo l' onActivityResult nel main , verifica l'effettivo risultato e poi vediamo come farti aggiornare i dati nelle diverse tab della pagerview , proprio in questi giorni mi è toccata sta rottura e alla fine ne sono uscito  ;-)
« Ultima modifica: 11 Novembre 2015, 15:49:36 CET da pietroconti89, Reason: Merged DoublePost »

Offline Drugsmatt

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S3
  • Sistema operativo:
    Windows 7/8
Re:Update ListFragment in Tab Layout quando l\'Activity finisce
« Risposta #6 il: 11 Novembre 2015, 16:30:52 CET »
0
Ciao se esegui startActivityForResult(intent, 101); dal Activity Main, onActivityResult deve essere posizionato sulla stessa activity , cosi riesci a recuperare il tutto , se lo posizioni in un altro punto come in questo caso Tab3 , non funzionerà mai

Post unito: 11 Novembre 2015, 15:49:36 CET
comunque solo questo non ti basterà , neanche notificando l'adapter come giustamente fai ... ma un problema alla volta , intanto fatti tornare l'activity for result mettendo l' onActivityResult nel main , verifica l'effettivo risultato e poi vediamo come farti aggiornare i dati nelle diverse tab della pagerview , proprio in questi giorni mi è toccata sta rottura e alla fine ne sono uscito  ;-)

Grazie Pietro! Allora.. ho spostato onActivityResult in MainActivity e ti confermo che ora viene richiamato (ho fatto un test con Log.v)

Offline pietroconti89

  • Utente normale
  • ***
  • Post: 164
  • Respect: +19
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note 3 N9005
  • Sistema operativo:
    Windows / Mac OSX
Re:Update ListFragment in Tab Layout quando l'Activity finisce
« Risposta #7 il: 11 Novembre 2015, 17:23:22 CET »
0
perfetto ora vedilo come una sorta di flag in cui ti dice, hai restituito ok ? procedi con l'update , innanzitutto andiamo su Tab3 , devi fare in modo di avere un metodo che aggiorni la situazione o meglio che inizializzi il tutto .... ti faccio un esempio, sono in Tab 3
Codice (Java): [Seleziona]
public void onCreateView() {
        int ris = 2+1;
    }

invece che eseguire il tutto nell onCreateView
creo un metodo updateView() e sostituisco cosi
Codice (Java): [Seleziona]
public void onCreateView() {
        updateView();
    }
    public void updateView() {
        int ris = 2+1;
    }

ora ho fatto si che la mia tab3 venga inizializzata da un metodo che potrà essere richiamato nella circostanza in cui in onActivityResult abbia restituito true ! vediamo come ... per prima cosa spostiamoci nel adapter " FragmentStatePagerAdapter " e implemento quanto segue
Codice (Java): [Seleziona]
@Override
        public int getItemPosition(Object object) {
            if (object instanceof Tab3) {
                ((Tab3) object).updateView("EVENTUALI PARAMETRI SE VUOI PASSARLI ");
            }
            return super.getItemPosition(object);
        }

cosi facendo puoi richiamare l'update nel caso in cui l'oggetto sia in visualizzazione , " se non lo è non ci interessa tanto verrà inizializzato comunque nel momento in cui verrà creato ! " ora dobbiamo creare una circostanza in cui sto " FragmentStatePagerAdapter " venga aggiornato al cambiare di qualcosa ... potrei iniziare a parlarti dell callback ma rischi di complicarti la vita , allora inserisci una variabile sempre nell adapter del tipo
int flagaggiornamento=0;
poi ti crei un metodo nell adapter
public void updateflagaggiornamento() {
            this.flagaggiornamento=flagaggiornamento+1;
        }

ed ora non ci resta richiamarlo nell onActivityResult quando è in stato di true e poi notificare l'adapter .... in questa maniera
Codice (Java): [Seleziona]
@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
        if ((requestCode == MYACTIVITY_REQUEST_CODE) && (resultCode == Activity.RESULT_OK)) {
             adapter.updateflagaggiornamento();
            adapter.notifyDataSetChanged();
         }
        }
}

e tutto funziona per magia  :-P prova e facci sapere  ;-)

Offline Drugsmatt

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S3
  • Sistema operativo:
    Windows 7/8
Re:Update ListFragment in Tab Layout quando l'Activity finisce
« Risposta #8 il: 12 Novembre 2015, 10:06:08 CET »
0
Sei un mago Pietro.. funziona perfettamente! Ma spiegami due cosette (se hai tempo), updateflagaggiornamento() a cosa serve esattamente? L'ho escluso e tutto funziona ugualmente. E perchè richiami updateView() precisamente dentro getItemPosition? Giusto per assimilare al meglio le informazioni.

p.s: Oltre a segnale il thread come risolto, c'è un modo per darti un voto positivo?

Offline pietroconti89

  • Utente normale
  • ***
  • Post: 164
  • Respect: +19
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note 3 N9005
  • Sistema operativo:
    Windows / Mac OSX
Re:Update ListFragment in Tab Layout quando l'Activity finisce
« Risposta #9 il: 12 Novembre 2015, 10:14:30 CET »
+1
Sei un mago Pietro.. funziona perfettamente! Ma spiegami due cosette (se hai tempo), updateflagaggiornamento() a cosa serve esattamente? L'ho escluso e tutto funziona ugualmente. E perchè richiami updateView() precisamente dentro getItemPosition? Giusto per assimilare al meglio le informazioni.

p.s: Oltre a segnale il thread come risolto, c'è un modo per darti un voto positivo?
Ciao Drugsmatt al momento sono fuori ,  ma appena rientro ti spiego xke usare quel metodo e perché ... nel tuo di caso ti funziona ugualmente    e quando invece è fondamentale tenerlo ,  comunque contento che hai risolto

Inviato dal mio SM-N9005 utilizzando Tapatalk


Offline LonelyWolf

  • Utente junior
  • **
  • Post: 148
  • Respect: +12
    • Mostra profilo
    • Traversate dei laghi
  • Dispositivo Android:
    GT-I9505, ALE-L21
  • Sistema operativo:
    Windows 7 32/64
Re:Update ListFragment in Tab Layout quando l'Activity finisce
« Risposta #10 il: 12 Novembre 2015, 12:41:38 CET »
0
Io sono rientrato oggi, ma a quanto pare avete già risolto. ;)
Se la mia risposta ti è utile, per favore un thanks!