IllegalStateException with PagerAdapter

后端 未结 3 1664
说谎
说谎 2021-02-20 01:47

I am getting an IllegalStateException within this activity but not too sure what is going on. Here is the ViewPagerAdapter class in QuickContactActivity.

private         


        
相关标签:
3条回答
  • 2021-02-20 02:26

    I have similar problems like you did, i have viewpager on Activity A then when user clicked the item in the viewpager, it will go to Activity B that have viewpager too. After user back from Activity B to Activity A, it will throwing Exception like this:

    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
    

    I think the problem is, the data content that the adapter of the viewpager have always 0 because the adapter not have the data that passed through from Activity. So i tried it work like this example:

    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));
        }
    
    }
    

    And the adapter of 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;
        }   
    
    }
    

    And the fragment class: 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);
                }
            }
        }
    
    }
    

    Now, the Exception before it will not showing anymore, and the viewpager works normally. This method trying make the viewpager like listview did, because listview will have passing the data through the adapter so the adapter will not lose the data content even the data have changed. I hope this example will help your problems. Cheers.

    0 讨论(0)
  • 2021-02-20 02:26

    It happened to me when I tried to override getCount() of page adapter

    During authorization, I show only one page. After end of authorization I change page count to 3. It falls for me if I do not call InvalidatePageAdapter() once

    @Override
    public int getCount() {
    
        if (mAuthorization_Status == AUTH_STATUS.AUTH_SUCCESS) {
    
            if (!isRefreshed) {
                isRefreshed = true;
                this.notifyDataSetChanged();
            }
    
            return NUM_PAGES;
    
        } else {
    
            return 1;
            //return NUM_PAGES;
    
        }
    
    } // END: getCount
    
    0 讨论(0)
  • 2021-02-20 02:39

    The problem is that your list of items/pages to show in the PageAdapter change and you dont call pageAdapter.notifyDataSetChanged().

    If you continue read the message, says that wait for 0 items and get 1. With this, it's seems that you set the adapter before set all the items/pages that the adapter receive.

    0 讨论(0)
提交回复
热议问题