2012-09-01 10 views
23

Estoy usando Android Fragments con una configuración viewpager. Básicamente hay 5 pestañas que puedes deslizar."Vista de contenido aún no creada" en los Fragmentos de Android

4 de las 5 contienen ListFragments que están pobladas por tablas MySQL; esto se hace dentro de un AsyncTask. Cuando swipe muy rápido a veces me sale este error:

09-01 07:54:01.243: E/AndroidRuntime(19706): FATAL EXCEPTION: main 
09-01 07:54:01.243: E/AndroidRuntime(19706): java.lang.IllegalStateException: Content view not yet created 
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.support.v4.app.ListFragment.ensureList(ListFragment.java:328) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.support.v4.app.ListFragment.getListView(ListFragment.java:222) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at com.---.---.MasterCat$TopFrag$TopTask.onPostExecute(MasterCat.java:570) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at com.---.---.MasterCat$TopFrag$TopTask.onPostExecute(MasterCat.java:1) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.os.AsyncTask.finish(AsyncTask.java:631) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.os.AsyncTask.access$600(AsyncTask.java:177) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.os.Handler.dispatchMessage(Handler.java:99) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.os.Looper.loop(Looper.java:137) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.app.ActivityThread.main(ActivityThread.java:4928) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at java.lang.reflect.Method.invokeNative(Native Method) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at java.lang.reflect.Method.invoke(Method.java:511) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558) 
09-01 07:54:01.243: E/AndroidRuntime(19706): at dalvik.system.NativeStart.main(Native Method) 

He intentionly no se utiliza un ProgressDialog porque hace deslizar tartamudeo un poco.

Así que tienen dos opciones y necesito ayuda de cualquier manera:

  1. Cómo evitar este error y mantener la lista refrescante, incluso durante el escaneo.

  2. O una vez que los 5 fragmentos estén cargados, apague 'refresh while swiping'. En otras palabras, las listas seguirán siendo las mismas a menos que abandones la Actividad y vuelvas.

Prefiero la opción n. ° 1. Por favor, hágamelo saber qué código necesita ver:

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.fragment_layout); 


     mSectionsPagerAdapter = new SectionsPagerAdapter(
       getSupportFragmentManager()); 

     final ActionBar actionBar = getActionBar(); 
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

     mViewPager = (ViewPager) findViewById(R.id.viewpager); 
     mViewPager.setAdapter(mSectionsPagerAdapter); 

     mViewPager 
       .setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { 
        @Override 
        public void onPageSelected(int position) { 
         actionBar.setSelectedNavigationItem(position); 

        } 
       }); 

     for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) { 
      actionBar.addTab(actionBar.newTab() 
        .setText(mSectionsPagerAdapter.getPageTitle(i)) 
        .setTabListener(this)); 
     } 




    } 

    public void onTabUnselected(ActionBar.Tab tab, 
      FragmentTransaction fragmentTransaction) { 

    } 

    @Override 
    public void onSaveInstanceState(Bundle savedInstanceState) { 
      super.onSaveInstanceState(savedInstanceState); 
     } 

    @Override 
    public void onRestoreInstanceState(Bundle savedInstanceState) { 
     super.onRestoreInstanceState(savedInstanceState); 

    } 

    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { 
     mViewPager.setCurrentItem(tab.getPosition()); 
    } 

    public void onTabReselected(ActionBar.Tab tab, 
      FragmentTransaction fragmentTransaction) { 
    } 

    public class SectionsPagerAdapter extends FragmentPagerAdapter { 

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

     @Override 
     public Fragment getItem(int position) { 
      Fragment f = null; 
      switch (position) { 
      case 0: { 
       f = new MasterFrag(); 
       Bundle args = new Bundle(); 

       f.setArguments(args); 
       break; 
      } 
      case 1: { 
       f = new FeaturedFrag(); 
       Bundle args = new Bundle(); 

       f.setArguments(args); 
       break; 
      } 
      case 4: { 
       f = new TopFrag(); 
       Bundle args = new Bundle(); 

       f.setArguments(args); 
       break; 
      } 
      case 3: { 
       f = new NewFrag(); 
       Bundle args = new Bundle(); 

       f.setArguments(args); 
       break; 
      } 
      case 2: { 
       f = new TrendFrag(); 
       Bundle args = new Bundle(); 

       f.setArguments(args); 
       break; 
      } 
      default: 
       throw new IllegalArgumentException("not this many fragments: " 
         + position); 
      } 

      return f; 

     } 

Además, la línea 570 se hace referencia en el LogCat se refiere a una getListView() dentro de un AsyncTask que se encuentra dentro de un ListFragment no se muestra arriba.

EDITAR:

Adición de una de las 5 Fragmentos - el que se hace referencia en LogCat - "TopFrag"

class TopTask extends AsyncTask<String, String, Void> { 
     InputStream is = null; 
     String result = ""; 

     @Override 
     protected Void doInBackground(String... params) { 
      String url_select = "http://www.---.com/---/---.php"; 

      HttpClient httpClient = new DefaultHttpClient(); 
      HttpPost httpPost = new HttpPost(url_select); 
      ArrayList<NameValuePair> param = new ArrayList<NameValuePair>(); 
      param.add(new BasicNameValuePair("Top", "Top")); 

      try { 
       httpPost.setEntity(new UrlEncodedFormEntity(param)); 
       HttpResponse httpResponse = httpClient.execute(httpPost); 
       HttpEntity httpEntity = httpResponse.getEntity(); 

       // read content 
       is = httpEntity.getContent(); 

      } catch (Exception e) { 

       Log.e("log_tag", "Error in http connection " + e.toString()); 
      } 
      try { 
       BufferedReader br = new BufferedReader(
         new InputStreamReader(is)); 
       StringBuilder sb = new StringBuilder(); 
       String line = ""; 
       while ((line = br.readLine()) != null) { 
        sb.append(line + "\n"); 
       } 
       is.close(); 
       result = sb.toString(); 

      } catch (Exception e) { 
       // TODO: handle exception 
       Log.e("log_tag", "Error converting result " + e.toString()); 
      } 

      return null; 

     } 

     protected void onPostExecute(Void v) { 

      String item, cat; 
      try { 
       JSONArray jArray = new JSONArray(result); 
       JSONObject json_data = null; 
       for (int i = 0; i < jArray.length(); i++) { 
        json_data = jArray.getJSONObject(i); 
        item = json_data.getString("item"); 
        cat = json_data.getString("category"); 


        items.add(item); 
        cats.add(cat); 



       } 
      } catch (JSONException e1) { 
       Toast.makeText(getActivity(), "No Top Items Found", 
         Toast.LENGTH_LONG).show(); 
      } catch (ParseException e1) { 
       e1.printStackTrace(); 
      } 

      ListView listView; 
      listView = getListView(); 
      listView.setTextFilterEnabled(true); 

      listView.setOnItemClickListener(new OnItemClickListener() { 

       public void onItemClick(AdapterView<?> arg0, View arg1, 
         int arg2, long id) { 
      // edit 

       } 
      }); 

      MasterCatObject[] mco = new MasterCatObject[items.size()]; 
      int index = 0; 

      for (@SuppressWarnings("unused") 
      String i : items) { 
       mco[index] = new MasterCatObject(items.get(index), 
         cats.get(index)); 
       index++; 
      } 

      adapter = new AllTimeAdapter(getActivity(), mco); 
      setListAdapter(adapter); 

     } 
    } 

} 

Respuesta

23
at android.support.v4.app.ListFragment.getListView(ListFragment.java:222) 
at com.---.---.MasterCat$TopFrag$TopTask.onPostExecute(MasterCat.java:570) 

su TopTask.onPostExecute() no debe tocar la interfaz de usuario, mientras que el fragmento no es todavía (antes de onCreateView)/ya no (después de onDestroyView) se muestra. Simplemente no hay ListView que pueda obtener.

Lo que puede hacer aquí es actualizar la estructura de datos que utiliza el ListView, por lo que la próxima vez que se dibuje la lista, se incluirán los nuevos datos.

+0

Obtengo el 'ListView' por el' getListView() 'normal dentro del PostExecute - ¿sería mejor colocarlo en el' OnActivityCreated'? – KickingLettuce

+2

'OnActivityCreated' debería funcionar pero lo pondría en' onCreateView' después de llamar a 'super' ya que definitivamente es un lugar donde puede estar seguro de que se llama cuando se crea' ListView'. – zapl

+0

Marcado correcto; Ya puedo ver que las cosas son mucho más estables. – KickingLettuce

0

Para evitar choque puede comprobar si())

en el momento de ListFragment excepción se separa ListFragment isAdded.

Cuestiones relacionadas