Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Content view not yet Created" on Android Fragments

I am using Android Fragments with a viewpager setup. Basically there are 5 tabs you can swipe through.

4 of the 5 contain ListFragments that are populated by MySQL tables; this is done inside of an AsyncTask. When I swipe very fast I sometimes get this 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)

I have intentionly not used a ProgressDialog because it makes swiping stutter quite a bit.

So I have two options and I need help either way:

  1. How to prevent this error and keep the list refreshing even while swiping.

  2. OR once the 5 fragments are loaded, turn off 'refresh while swiping'. In other words, the lists will stay the same unless you back out of the Activity and come back.

I'd prefer option #1. Please let me know what code you need to see:

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

        }

Also, line 570 referenced in the LogCat pertains to a getListView() inside of an AsyncTask which is inside of a ListFragment not shown above.

EDIT:

Adding one of the 5 Fragments - the one referenced in 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);

        }
    }

}
like image 363
TheLettuceMaster Avatar asked Sep 01 '12 15:09

TheLettuceMaster


1 Answers

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

your TopTask.onPostExecute() must not touch the UI while the fragment is not yet (before onCreateView) / no longer (after onDestroyView) shown. There is simply no ListView you can get.

What you could do here is to update the datastructure that is used by the ListView so the next time the list is drawn the new data is included.

like image 99
zapl Avatar answered Oct 21 '22 10:10

zapl