How to handle network calls inside a Fragment

前端 未结 7 1042
攒了一身酷
攒了一身酷 2021-01-31 23:21

I have the following situation:

I have an Activity that hosts a ViewPager, and I have 4 Fragments;

the ViewPager

7条回答
  •  难免孤独
    2021-01-31 23:42

    @Andrew Carl provide good idea. I also use the similar approach in my projects. I think it's more generalized.

    Create an interface:

    public interface ViewPagerFragment {
        void onSelected();
    
        void onDeselected();
    }
    

    And this common helper:

    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.view.ViewPager;
    
    public class ViewPagerHelper implements ViewPager.OnPageChangeListener {
        private final FragmentManager mFragmentManager;
        private final ViewPager mViewPager;
        private int mSelectedPage;
    
        public ViewPagerHelper(FragmentManager fragmentManager, ViewPager viewPager) {
            mFragmentManager = fragmentManager;
            mViewPager = viewPager;
            mSelectedPage = -1;
        }
    
        @Override
        public void onPageSelected(int position) {
            Fragment previous = findViewPagerChildFragment(mFragmentManager, mViewPager, mSelectedPage);
            if (previous instanceof ViewPagerFragment) {
                ((ViewPagerFragment) previous).onDeselected();
            }
    
            Fragment current = findViewPagerChildFragment(mFragmentManager, mViewPager, position);
            if (current instanceof ViewPagerFragment) {
                ((ViewPagerFragment) current).onSelected();
            }
    
            mSelectedPage = position;
        }
    
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            // empty
        }
    
        @Override
        public void onPageScrollStateChanged(int state) {
            // empty
        }
    
        public static Fragment findViewPagerChildFragment(FragmentManager manager, ViewPager pager, int position) {
            if (pager == null) {
                return null;
            }
    
            String tag = "android:switcher:" + pager.getId() + ":" + position;
            return manager.findFragmentByTag(tag);
        }
    }
    

    Now you may use them for any purpose:

    Fragment:

    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class MyFragment extends Fragment implements ViewPagerFragment {
        private boolean mSelected;
    
        public static MyFragment newInstance(int position) {
            Bundle args = new Bundle();
            args.putInt("position", position);
    
            MyFragment result = new MyFragment();
            result.setArguments(args);
            return result;
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            TextView result = new TextView(inflater.getContext());
            result.setText("Position: " + getPosition());
            return result;
        }
    
        private int getPosition() {
            return getArguments().getInt("position");
        }
    
        @Override
        public void onSelected() {
            mSelected = true;
            start();
        }
    
        @Override
        public void onDeselected() {
            mSelected = false;
        }
    
        private void start() {
            final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    Activity activity = getActivity();
                    if (activity == null) {
                        return;
                    }
    
                    if (!mSelected) {
                        Toast.makeText(activity, "Fragment #" + getPosition() + " stopped", Toast.LENGTH_SHORT).show();
                        return;
                    }
    
                    TextView textView = (TextView) activity.findViewById(R.id.text);
                    if (textView != null) {
                        textView.setText("Fragment #" + getPosition() + " works: " + System.nanoTime() % 10000);
                    }
    
                    handler.postDelayed(this, 150);
                }
            }, 150);
        }
    }
    

    Activity:

    import android.os.Bundle;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.ActionBarActivity;
    
    public class MainActivity extends ActionBarActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
            viewPager.setOnPageChangeListener(new ViewPagerHelper(getSupportFragmentManager(), viewPager));
            viewPager.setAdapter(new MyAdapter(getSupportFragmentManager()));
        }
    }
    

    Adapter:

    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentPagerAdapter;
    
    public class MyAdapter extends FragmentPagerAdapter {
        public MyAdapter(FragmentManager fm) {
            super(fm);
        }
    
        @Override
        public Fragment getItem(int position) {
            return MyFragment.newInstance(position);
        }
    
        @Override
        public int getCount() {
            return 42;
        }
    }
    

    Check complete demo on github.

提交回复
热议问题