web-dev-qa-db-fra.com

IllegalStateException avec PagerAdapter

Je reçois une exception IllegalStateException dans cette activité, mais je ne suis pas trop sûr de ce qui se passe. Voici la classe ViewPagerAdapter dans QuickContactActivity.

private class ViewPagerAdapter extends FragmentPagerAdapter {
    public ViewPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @Override
    public Fragment getItem(int position) {
        QuickContactListFragment fragment = new QuickContactListFragment();
        final String mimeType = mSortedActionMimeTypes.get(position);
        final List<Action> actions = mActions.get(mimeType);
        fragment.setActions(actions);
        return fragment;
    }

    @Override
    public int getCount() {
        return mSortedActionMimeTypes.size();
    }
}

Voici le journal des accidents:

07-15 09:49:21.060: E/com.##.##.##.Application(12378): Thread uncaught exception:
07-15 09:49:21.060: E/com.##.##.##.Application(12378): Java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 0, found: 1 Pager id: com.##.##.Android:id/item_list_pager Pager class: class Android.support.v4.view.ViewPager Problematic adapter: class com.##.contacts.quickcontact.QuickContactActivity$ViewPagerAdapter
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.support.v4.view.ViewPager.populate(ViewPager.Java:959)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.support.v4.view.ViewPager.populate(ViewPager.Java:911)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.support.v4.view.ViewPager.onMeasure(ViewPager.Java:1432)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.View.measure(View.Java:15518)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.ViewGroup.measureChildWithMargins(ViewGroup.Java:4825)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.Java:1404)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.widget.LinearLayout.measureVertical(LinearLayout.Java:695)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.widget.LinearLayout.onMeasure(LinearLayout.Java:588)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.View.measure(View.Java:15518)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.ViewGroup.measureChildWithMargins(ViewGroup.Java:4825)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.widget.FrameLayout.onMeasure(FrameLayout.Java:310)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.View.measure(View.Java:15518)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.ViewGroup.measureChildWithMargins(ViewGroup.Java:4825)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.widget.FrameLayout.onMeasure(FrameLayout.Java:310)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.View.measure(View.Java:15518)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.ViewGroup.measureChildWithMargins(ViewGroup.Java:4825)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.Java:1404)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.widget.LinearLayout.measureVertical(LinearLayout.Java:695)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.widget.LinearLayout.onMeasure(LinearLayout.Java:588)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.View.measure(View.Java:15518)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.ViewGroup.measureChildWithMargins(ViewGroup.Java:4825)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.widget.FrameLayout.onMeasure(FrameLayout.Java:310)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at com.Android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.Java:2176)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.View.measure(View.Java:15518)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.ViewRootImpl.performMeasure(ViewRootImpl.Java:1874)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.Java:1089)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.ViewRootImpl.performTraversals(ViewRootImpl.Java:1265)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.ViewRootImpl.doTraversal(ViewRootImpl.Java:989)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.Java:4351)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.Choreographer$CallbackRecord.run(Choreographer.Java:749)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.Choreographer.doCallbacks(Choreographer.Java:562)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.Choreographer.doFrame(Choreographer.Java:532)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.Java:735)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.os.Handler.handleCallback(Handler.Java:725)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.os.Handler.dispatchMessage(Handler.Java:92)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.os.Looper.loop(Looper.Java:137)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Android.app.ActivityThread.main(ActivityThread.Java:5041)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Java.lang.reflect.Method.invokeNative(Native Method)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at Java.lang.reflect.Method.invoke(Method.Java:511)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:793)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:560)
07-15 09:49:21.060: E/com.##.##.##.Application(12378):  at dalvik.system.NativeStart.main(Native Method)
07-15 09:49:21.060: E/ACRA(12378): ACRA caught a IllegalStateException exception for com.##.##.Android. Building report.
11
thisiscrazy4

Le problème est que votre liste d'éléments/pages à afficher dans le PageAdapter change et que vous n'appelez paspageAdapter.notifyDataSetChanged().

Si vous continuez à lire le message, dites que vous attendez 0 élément et que vous obtenez 1. Cela semble que vous définissez l'adaptateur avant de définir tous les éléments/pages que l'adaptateur reçoit.

14
Aracem

J'ai des problèmes similaires à ceux que vous avez rencontrés: j'ai un viewpager sur l'activité A, puis lorsque l'utilisateur clique sur l'élément dans le viewpager, il passe à l'activité B qui possède également viewpager. Après que l'utilisateur soit revenu de l'activité B à l'activité A, il lancera une exception comme ceci:

Java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 4, found: 0 Pager id: com.gbu.app.templateforbussiness:id/header_view_pager_list Pager class: class Android.support.v4.view.ViewPager Problematic adapter: class com.gbu.app.templateforbussiness.adapter.DetailProductPagerAdapter

Je pense que le problème est que le contenu des données que l'adaptateur du viewpager a toujours égal à 0, car l'adaptateur n'a pas les données transmises depuis Activity. J'ai donc essayé de travailler comme dans cet exemple:

DetailProductActivity.class

public class DetailProductActivity extends FragmentActivity {
    private ViewPager product_detail_viewpager;
    private DetailProductPagerAdapter detail_product_adapter;
    private Intent product_detail_intent;
    public static List<Product> detail_product;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail_product);
        product_detail_viewpager = (ViewPager) findViewById(R.id.detail_product_viewpager);
        detail_product = HomeActivity.home_product;
    }

    @Override
    protected void onStart() {
        super.onStart();
        product_detail_intent = getIntent();
        startApp(product_detail_intent);
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

    private void startApp(Intent data) {
        // TODO Auto-generated method stub
            // pass the Array, List of data to viewpager adapter like this
        detail_product_adapter = new DetailProductPagerAdapter(getSupportFragmentManager(), detail_product); 
        product_detail_viewpager.setAdapter(detail_product_adapter);
        product_detail_viewpager.setCurrentItem(data.getIntExtra("current_item", 0));
    }

}

Et l'adaptateur de viewpager: DetailProductPagerAdapter.class

public class DetailProductPagerAdapter extends FragmentPagerAdapter {
    private ProductDetailFragment detail_product_fragment;
    private Bundle data;
    private List<Product> detail_product;

    // the data from Activity passed to this adapter        
    public DetailProductPagerAdapter(FragmentManager fm, List<Product> p) {
        super(fm);
        // TODO Auto-generated constructor stub
        detail_product = p;
    }

    // then passing the data again to your fragment class, like this example
    @Override
    public Fragment getItem(int arg0) {
        // TODO Auto-generated method stub
        detail_product_fragment = new ProductDetailFragment(detail_product);
        data = new Bundle();
        data.putInt("current_item", arg0);
        detail_product_fragment.setArguments(data);
        return detail_product_fragment;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return detail_product.size();
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }   

}

Et la classe de fragments: ProductDetailFragment.class

@SuppressLint("ValidFragment")
public class ProductDetailFragment extends Fragment {
    private RelativeLayout detail_item_header;
    private ImageView detail_item_imv;
    private TextView detail_item_tv_title;
    private WebView detail_item_web_content;
    private DisplayMetrics detail_metrics;
    private List<Product> detail_product;
    private int index_item;

    // the data from adapter pass it to this fragment
    public ProductDetailFragment(List<Product> p) {
        detail_product = p;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view_detail = inflater.inflate(R.layout.item_product_detail_viewpager, container, false);
        detail_metrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(detail_metrics);
        savedInstanceState = getArguments();
        index_item = savedInstanceState.getInt("current_item");
        detail_item_header = (RelativeLayout) view_detail.findViewById(R.id.item_header_product_viewpager);
        detail_item_imv = (ImageView) detail_item_header.findViewById(R.id.item_imv_product_viewpager);
        detail_item_tv_title = (TextView) detail_item_header.findViewById(R.id.item_tv_title_product_viewpager);
        detail_item_web_content = (WebView) view_detail.findViewById(R.id.item_web_product_viewpager);
        startApp();
        return view_detail;
    }

    private void startApp() {
        // TODO Auto-generated method stub
        detail_item_header.getLayoutParams().height = (int) (detail_metrics.heightPixels * 0.38);
        if (detail_product.get(index_item).getStatus() == 0) {
            new loadImageProduct(detail_item_imv).execute(detail_product.get(index_item).getImage());
        }else {
            detail_item_imv.setImageBitmap(detail_product.get(index_item).getBmp());
        }
        detail_item_tv_title.setText(detail_product.get(index_item).getTitle());
        String web_content_product = "<!DOCTYPE html>"+
                                     "<html>"+
                                     "<body>"+
                                     "<p>Harga : "+detail_product.get(index_item).getPrice()+"</p><br>"+
                                     detail_product.get(index_item).getDetail()+"<br><br>"+
                                     detail_product.get(index_item).getDetail2()+
                                     "</body>"+
                                     "</html>";
        detail_item_web_content.loadDataWithBaseURL("https://www.google.com", web_content_product, "text/html", "UTF-8", null);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    private class loadImageProduct extends AsyncTask<String, Integer, Bitmap> {
        private Bitmap b;
        private ImageView vimv;
        private GetImage get_image;

        public loadImageProduct(ImageView v) {
            vimv = v;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            b = null;
            get_image = new GetImage();
        }

        @Override
        protected Bitmap doInBackground(String...url) {
            try {
                b = get_image.loadImageFromServer(url[0]);
                if (b != null)
                    return b;
            } catch(OutOfMemoryError e) {

            }
            return b;
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            super.onPostExecute(result);
            if (result != null) {
                detail_product.get(index_item).setBmp(result);
                detail_product.get(index_item).setStatus(1);
                vimv.setImageBitmap(result);
            }
        }
    }

}

Maintenant, l'exception avant qu'elle ne s'affiche plus et le viewpager fonctionne normalement. Cette méthode essaye de faire en sorte que le viewpager ressemble à listview, car ce dernier transmettra les données à l'adaptateur afin que celui-ci ne perde pas le contenu des données, même si les données ont été modifiées. J'espère que cet exemple aidera vos problèmes. À votre santé.

1
Aprido Sandyasa