2012-03-01 15 views
6

Sto provando a creare un'attività che servirà da visualizzazione del giorno del calendario. Quando l'utente fa scorrere verso sinistra o verso destra, andrà a domani o ieri e così via attraverso il calendario.Le attività che utilizzano ViewPager, PagerAdapter e AsyncTask causano una vista vuota

Ho deciso di utilizzare ViewPager/PagerAdapter per gestire le visualizzazioni e controllare i giorni del paging.

Come parte dell'impostazione della vista giornaliera, l'app passerà alla mia API e richiederà gli appuntamenti per quel giorno. Gli appuntamenti verranno restituiti e visualizzati per quel giorno. Per recuperare i dati dall'API, sto usando un AsyncTask. Quindi, in pratica, instantiateItem() chiama l'API e imposta la lista vuota. Quindi BroadcastReceiver rileva la risposta, analizza i dati e li visualizza.

Il problema che sto avendo è che la prima vista visualizzata è sempre vuota. Le viste a sinistra oa destra, sono popolate e se passo due posizioni in entrambe le direzioni, abbastanza per distruggere la vista originale, quindi tornare alla vista originale, ha dati. Perché? Come ottenere la prima visualizzazione per essere popolata senza dover spostare oltre 2 passaggi?

Ecco la mia attività. Al momento non sto ancora analizzando i dati provenienti dall'API, semplicemente simulando un elenco di stringhe nel frattempo.

public class MyPagerActivity extends Activity { 

    private ViewPager myPager; 
    private static int viewCount = 1000; 
    private Context ctx; 
    private MyPagerAdapter myAdapter; 

    private static final String tag = "MyPagerActivity"; 

    private static final String apiAction = "getAppointmentsForDate"; 
    private static final String apiUri = "https://myAPI.com/api.php"; 
    private static final String resource = "appointments"; 
    private static final String action = "getappointmentsfordate"; 
    private static final String date = "20120124"; 
    private ProgressDialog progress; 
    private SharedPreferences loginPreferences; 
    private SharedPreferences.Editor loginPreferencesEditor; 
    private ListView v; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     ctx = this; 

     myAdapter = new MyPagerAdapter(); 
     myPager = (ViewPager) findViewById(R.id.myPager); 
     myPager.setAdapter(myAdapter); 
     myPager.setCurrentItem(500); 
    } 

    private class MyPagerAdapter extends PagerAdapter { 


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

     @Override 
     public Object instantiateItem(View collection, int position) { 

      try { 
       Log.d(tag, "trying http connection"); 
       loginPreferences = getSharedPreferences("loginPrefs", MODE_PRIVATE); 
       loginPreferencesEditor = loginPreferences.edit(); 
       String authToken = loginPreferences.getString("authToken", ""); 
       String staffOrRoomsId = loginPreferences.getString("staffOrRoomsId", ""); 
       String staffOrRoomsIdName = loginPreferences.getString("staffOrRoomsIdName", ""); 

       HttpPost apiRequest = new HttpPost(new URI(apiUri)); 
       List<NameValuePair> parameters = new ArrayList<NameValuePair>(); 
       parameters.add(new BasicNameValuePair("authToken", authToken)); 
       parameters.add(new BasicNameValuePair("resource", resource)); 
       parameters.add(new BasicNameValuePair("action", action)); 
       parameters.add(new BasicNameValuePair("date", date)); 
       parameters.add(new BasicNameValuePair(staffOrRoomsIdName, staffOrRoomsId)); 
       apiRequest.setEntity(new UrlEncodedFormEntity(parameters)); 

       RestTask task = new RestTask(ctx, apiAction); 
       task.execute(apiRequest); 
       //Display progress to the user 
    //   progress = ProgressDialog.show(ctx, "Searching", "Waiting For Results...", true); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

      Log.d(tag, "Creating another view! Position: " + position); 

      myPager.setTag(collection); 

      v = new ListView(ctx); 
      ((ViewPager) collection).addView(v, 0); 
      return v; 
     } 

     @Override 
     public void destroyItem(View collection, int position, Object view) { 
      Log.d(tag, "Destroying position: " + position + "!"); 
      ((ViewPager) collection).removeView((ListView) view); 
     } 

     @Override 
     public boolean isViewFromObject(View view, Object object) { 
      return view==((ListView)object); 
     } 

     @Override 
     public void finishUpdate(View arg0) {} 

     @Override 
     public void restoreState(Parcelable arg0, ClassLoader arg1) {} 

     @Override 
     public Parcelable saveState() { 
      return null; 
     } 

     @Override 
     public void startUpdate(View arg0) {} 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     registerReceiver(receiver, new IntentFilter(apiAction)); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     unregisterReceiver(receiver); 
    } 

    private BroadcastReceiver receiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      //Clear progress indicator 
      if (progress != null) { 
       progress.dismiss(); 
      } 

      Log.d(tag, "Broadcast received"); 

      String[] from = new String[] { "str" }; 
      int[] to = new int[] { android.R.id.text1 }; 
      List<Map<String, String>> items = new ArrayList<Map<String, String>>(); 
      for (int i = 0; i < 20; i++) 
      { 
       Map<String, String> map = new HashMap<String, String>(); 
       map.put("str", String.format("Item %d", i + 1)); 
       items.add(map); 
      } 
      SimpleAdapter adapter = new SimpleAdapter(ctx, items, android.R.layout.simple_list_item_1, from, to); 
      v.setAdapter(adapter); 
     } 
    }; 
} 

Grazie per aver il tempo di rivedere questa domanda!

+0

stiamo riscontrando un problema analogo in cui i vecchi risultati sono ancora visualizzati fino a quando si fa scorrere avanti o indietro da 1 a 3 posizioni. stiamo usando la combinazione pageradapter/viewpager. era la soluzione per usare un frammento per ogni pagina? –

risposta

4

Per impostazione predefinita, a ViewPager non solo viene caricata solo la pagina attualmente visibile, ma anche la pagina su entrambi i lati. Questo è il offscreenPageLimit. Il valore minimo è 1.

instantiateItem verrà chiamato per ogni pagina che desidera creare. Nell'implementazione di instantiateItem, si avvia un AsyncTask e si assegna un valore a v. Solo l'ultima chiamata a instantiateItem (vale a dire l'ultima pagina fino al offscreenPageLimit) avrà l'assegnazione corretta di v e quindi la prima pagina non verrà popolata inizialmente.

Non è possibile fare affidamento sull'ultima chiamata a instantiateItem per indirizzare alla pagina correntemente attiva. Passerei a utilizzare un frammento per ogni pagina, che mantiene la propria richiesta HTTP e ListView.

+0

Si può verificare se il problema è simile a questo problema simile- http://stackoverflow.com/questions/30555067/viewpager-not-displaying-content-of-first-view-that-is-being-opened –

Problemi correlati