Android: FragmentPagerAdapter: getItem method called twice on First time

前端 未结 5 1453
一整个雨季
一整个雨季 2020-12-15 04:44

In My application, I have used the ViewPager. Like,

(say main.xml)



        
相关标签:
5条回答
  • 2020-12-15 04:53

    you can use this method to update your views

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
    
        if (isVisibleToUser) {
            // Fetch data or something...
        }
    }
    
    0 讨论(0)
  • 2020-12-15 05:01

    I faced the same issue - getItem() method was called twice. I don't know about your purposes of using that method by mine was to trigger changes in a hosting activity when new slide appears.

    Well, first of all getItem() is not a right method to get event of appearing new slide.

    I used ViewPager.OnPageChangeListener listener on ViewPager itself for this purpose. Here is what I did:

    In Activity that holds slide fragments:

     @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.signature_wizard_activity);
    
        // Instantiate a ViewPager and a PagerAdapter.
        mPager = (ViewPager) findViewById(R.id.pager);
        mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
        mPager.setAdapter(mPagerAdapter);
        mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                onSlideChanged(position); // change color of the dots
            }
            @Override
            public void onPageSelected(int position) {}
            @Override
            public void onPageScrollStateChanged(int state) {}
        });
    }
    

    onPageScrolled() is called every time your slide appears, as a parameter it gets current position of the slide that is shown. Nice thing is that it is called including the first time it appears, not just when slide was changed.

    When it can be used? For example if you have some wizard activity with ViewPager where you slide fragments with some hints, you probable would like to have a bar with grey dots below the slider that would represent the number of slides in total, and one of the dots will be different color representing the current slide. In this case ViewPager.OnPageChangeListener and method onPageScrolled() will be the best option.

    Or if you have buttons PREV. and NEXT which change slides and you want to disable PREV. button on the first slide and disable NEXT button on the last slide. Here is how you do it inside onPageScrolled() method:

     @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                if(position == 0){
                    prevBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_grey_500));
                    prevBtn.setEnabled(false);
                }else{
                    prevBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_blue));
                    prevBtn.setEnabled(true);
                }
    
                if(position == NUM_PAGES -1){
                    nextBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_grey_500));
                    nextBtn.setEnabled(false);
                }else{
                    nextBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_blue));
                    nextBtn.setEnabled(true);
                }
            }
    

    where NUM_PAGES is a constant with total number of slides

    0 讨论(0)
  • 2020-12-15 05:07

    The FragmentPagerAdapter instantiates 2 Fragments on start, for index 0 and for index 1. If you want to get data from the Fragment which is on the screen, you can use setOnPageChangeListener for the Pager to get current position. Then have SparseArray with WeakReference to your fragments. Update that array in the getItem call. When onPageSelected gets called use that position to get reference to right Fragment and update User data.

    Initialization of array:

    private SparseArray<WeakReference<MyFragment>> mFragments = new SparseArray<WeakReference<MyFragment>>(3);
    
    0 讨论(0)
  • 2020-12-15 05:10

    My Problem is getItem() method is called twice on First time

    This is not the problem, this is default feature of FragmentPagerAdapter. Its good for you to swipe from this page to the next one and previous one.

    the view displayed in the emulator is 0th index, but got 1st Index value in the FragmentActivity

    I got the same issue, and I know why. This because you used same Fragment in View Pager.

    How to fix this is separate Fragments by using different Fragment.

    0 讨论(0)
  • 2020-12-15 05:12

    in getItem method i wrote this..

    @Override
    public Fragment getItem(int index) {
        EditFragment frag = new EditFragment();
        Bundle args = new Bundle();
        args.putSerializable("currentItem", itemsList.get(index));
        frag.setArguments(args);
        return (frag);
    }
    

    here itemsList.get(index) is the model class object which i will use in EditFragment class. here is that.

     @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        View result = inflater.inflate(R.layout.pager_fragment_layout, container, false);
        image = (ImageView)result.findViewById(R.id.pager_image);
        text = (TextView)result.findViewById(R.id.pager_item_desc);
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getActivity()).build();
        ImageLoader.getInstance().init(config);
        imLoader = ImageLoader.getInstance();
    
                ****NOTE
        final SwapItems itemList = (SwapItems) getArguments().getSerializable("currentItem");
    
        imagePath = itemList.getPaths().get(0);
        imLoader.displayImage(imagePath,image);
        text.setText(itemList.getItemDescription());
    
        image.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Fragment fragment = new ItemImagesFragment();
                FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                Bundle bundle = new Bundle();
                bundle.putSerializable("val", itemList);
                fragment.setArguments(bundle);
                fragmentTransaction.replace(R.id.content_frame, fragment);
                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();
            }
        });
        return result;
    }
    

    NOTE: here i am getting swapitems model object from previous getItem method is 'final'. this solves my issue. Earlier i was initialized the same object with static as modifier.

    hope yours will also clear

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