web-dev-qa-db-fra.com

"Affichage du contenu non encore créé" sur les fragments Android

J'utilise des fragments Android avec une configuration viewpager. En gros, il y a 5 onglets que vous pouvez parcourir.

4 sur 5 contiennent ListFragments qui sont remplis par des tables MySQL; cela se fait à l'intérieur d'une AsyncTask. Lorsque je glisse très vite, j'obtiens parfois l'erreur suivante:

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)

J'ai intentionnellement pas utilisé une ProgressDialog car cela fait beaucoup glisser le bégaiement.

Donc, j'ai deux options et j'ai besoin d'aide de toute façon:

  1. Comment éviter cette erreur et conserver la liste actualisée même lors du balayage.

  2. OU une fois que les 5 fragments sont chargés, désactivez l'option "Actualiser lors du balayage". En d'autres termes, les listes resteront les mêmes à moins que vous vous retiriez de l'activité et que vous reveniez.

Je préférerais l'option n ° 1. S'il vous plaît laissez-moi savoir quel code vous avez besoin de voir:

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

        }

De plus, la ligne 570 référencée dans le LogCat concerne un getListView () à l'intérieur d'une AsyncTask qui est à l'intérieur d'un ListFragment non présenté ci-dessus.

MODIFIER:

Ajout d’un des 5 fragments - celui référencé dans 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);

        }
    }

}
23
KickingLettuce
at Android.support.v4.app.ListFragment.getListView(ListFragment.Java:222)
at com.---.---.MasterCat$TopFrag$TopTask.onPostExecute(MasterCat.Java:570)

votre TopTask.onPostExecute() ne doit pas toucher l'interface utilisateur tant que le fragment n'est pas encore affiché (avant onCreateView)/n'est plus (après onDestroyView). Il n’ya tout simplement pas ListView possible.

Ce que vous pouvez faire ici est de mettre à jour la structure de données utilisée par la variable ListView afin que la nouvelle fois que la liste soit dessinée, les nouvelles données soient incluses.

23
zapl

Pour éviter un crash, vous pouvez vérifier si ListFragment isAdded ()) 

au moment de l'exception, ListFragment est détaché.

0
Alexey O.