2012-03-01 7 views
6

Estoy intentando crear una actividad que servirá como una vista de día del calendario. Cuando el usuario pase por la izquierda o la derecha, irá a mañana o ayer, y así sucesivamente a través del calendario.La actividad que utiliza ViewPager, PagerAdapter y AsyncTask causa una vista en blanco

Decidí usar ViewPager/PagerAdapter para manejar las vistas y controlar la búsqueda durante días.

Como parte de la configuración de la Vista de día, la aplicación irá a mi API y solicitará cualquier cita para ese día. Las citas se devolverán y se mostrarán para ese día. Para recuperar datos de la API, estoy usando una AsyncTask. Básicamente, instantiateItem() llama a la API y configura el ListView vacío. Luego, BroadcastReceiver capta la respuesta, analiza los datos y los muestra.

El problema que tengo es que la primera vista que se muestra siempre está en blanco. Las vistas a la izquierda oa la derecha, se rellenan y si voy dos posiciones en cualquier dirección, lo suficiente para que la vista original se destruya, vuelva a la vista original, tiene datos. ¿Por qué? ¿Cómo hacer para que la primera vista se rellene sin tener que mover dos veces?

Aquí está mi actividad. Actualmente no estoy analizando los datos que regresan de la API, solo estoy simulando con una lista de cadenas de caracteres mientras tanto.

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); 
     } 
    }; 
} 

Gracias por tomarse el tiempo para revisar esta pregunta!

+0

Estamos teniendo un problema similar en el que los resultados anteriores aún se muestran hasta deslizar hacia adelante o hacia atrás de 1 a 3 lugares. estamos usando la combinación pageradapter/viewpager. fue la solución para usar un fragmento para cada página? –

Respuesta

4

De manera predeterminada, un ViewPager no solo carga solo la página visible actualmente, sino también la página a cada lado. Este es el offscreenPageLimit. El valor mínimo es 1.

Se llamará a instantiateItem para cada página que desee crear. En su implementación de instantiateItem, está iniciando un AsyncTask y asignando un valor a v. Solo la última llamada al instantiateItem (es decir, la última página hasta el offscreenPageLimit) tendrá la asignación correcta de v, por lo que la primera página no se completará inicialmente.

No puede confiar en la última llamada al instantiateItem para dirigirlo a la página actualmente activa. Cambiaría a usar un Fragmento para cada página, que mantiene su propia solicitud HTTP y ListView.

+0

¿Puedes comprobar cuál es el problema con este problema similar? Http://stackoverflow.com/questions/30555067/viewpager-not-displaying-content-of-first-view-that-is-being-opened –

Cuestiones relacionadas