IllegalStateException with PagerAdapter

后端 未结 3 1666
说谎
说谎 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 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 detail_product;
    
        // the data from Activity passed to this adapter        
        public DetailProductPagerAdapter(FragmentManager fm, List 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 detail_product;
        private int index_item;
    
        // the data from adapter pass it to this fragment
        public ProductDetailFragment(List 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 = ""+
                                         ""+
                                         ""+
                                         "

    Harga : "+detail_product.get(index_item).getPrice()+"


    "+ detail_product.get(index_item).getDetail()+"

    "+ detail_product.get(index_item).getDetail2()+ ""+ ""; 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 { 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.

提交回复
热议问题