2012-09-01 4 views
23

Ich verwende Android-Fragmente mit einem viewpager Setup. Grundsätzlich gibt es 5 Tabs, die Sie durchwischen können."Inhaltsansicht noch nicht erstellt" auf Android-Fragmenten

4 der 5 enthalten ListFragments, die von MySQL-Tabellen aufgefüllt werden; Dies geschieht innerhalb einer AsyncTask. Wenn ich sehr schnell Swipe manchmal ich diesen Fehler:

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) 

Ich habe intentionly verwendet kein ProgressDialog, weil es recht Stottern ein bisschen macht klauen.

So habe ich zwei Möglichkeiten, und ich brauche jede Weise helfen:

  1. Wie dieser Fehler zu vermeiden und die Liste hält erfrischende sogar während klauen.

  2. ODER, sobald die 5 Fragmente geladen sind, deaktivieren Sie 'beim Wischen aktualisieren'. Mit anderen Worten, die Listen bleiben gleich, es sei denn, Sie verlassen die Aktivität und kehren zurück.

Ich würde Option # 1 bevorzugen. Bitte lassen Sie mich wissen, welchen Code Sie sehen müssen:

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

     } 

Auch Zeile in der LogCat verwiesen 570 ein getListView betrifft() innerhalb eines AsyncTask, die im Inneren eines ListFragment ist nicht oben gezeigt.

EDIT:

einer der 5 Fragmente Hinzufügen - die man in LogCat verwiesen - "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); 

     } 
    } 

} 

Antwort

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

Ihre TopTask.onPostExecute() die Benutzeroberfläche nicht berühren müssen, während das Fragment nicht ist noch (vor onCreateView)/nicht mehr (nach onDestroyView) gezeigt. Es gibt einfach keine ListView die du bekommen kannst.

Sie könnten hier die Datenstruktur aktualisieren, die von der ListView verwendet wird, so dass beim nächsten Zeichnen der Liste die neuen Daten enthalten sind.

+0

Ich bekomme die 'ListView' durch die normale' getListView() 'innerhalb der PostExecute - wäre es besser, sie in die' OnActivityCreated' zu platzieren? – KickingLettuce

+2

'OnActivityCreated' sollte funktionieren, aber ich würde es nach Aufruf von' super' in 'onCreateView' schreiben, da dies definitiv ein Ort ist, an dem Sie sicher sein können, dass es aufgerufen wird, wenn' ListView' erstellt wird. – zapl

+0

Markierung korrekt; Ich kann schon sehen, dass die Dinge viel stabiler sind. – KickingLettuce

0

Um zu vermeiden Absturz überprüfen können, ob ListFragment isAdded())

im Moment der Ausnahme ListFragment abgelöst wird.