user3530080
user3530080

Reputation: 73

Load data of a Fragment only if selected

In my Androidapp I use Swipe View as my navigation now. If I start my App, this one loads all of my different fragments and not only this one whioch is selected. If I switch between the Fragments the view doesn't get reloaded. How can I do this that only getting load the view which is selected and if I switch to a fragment this is getting reloaded again. Thanks MainActivity:

public class MainActivity extends FragmentActivity implements ActionBar.TabListener {


AppSectionsPagerAdapter mAppSectionsPagerAdapter;
ViewPager mViewPager;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());


    final ActionBar actionBar = getActionBar();


    assert actionBar != null;
    actionBar.setHomeButtonEnabled(false);

    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(mAppSectionsPagerAdapter);
    mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            actionBar.setSelectedNavigationItem(position);
        }
    });


    for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {
        actionBar.addTab(
                actionBar.newTab()
                        .setText(mAppSectionsPagerAdapter.getPageTitle(i))
                        .setTabListener(this));
    }
}

@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}

@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    mViewPager.setCurrentItem(tab.getPosition());
}

@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}




public class AppSectionsPagerAdapter extends FragmentPagerAdapter {

    public AppSectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        switch (i) {
            case 0:
                return new EventCalendarFragment();

            default:

                return new VideoListFragment();
        }
    }

    @Override
    public int getCount() {
        return 2;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        if (position == 0) {
            return "Event";
        } else  {
            return "Videos";
        }
    }
}

VideoListFragment:

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_videos_table, container, false);
    //load customBanner
    imageView = (ImageView) rootView.findViewById(R.id.video_imageView);
    imageView.setVisibility(View.GONE);
    new AsyncTaskParseJson().execute();
    inputSearch = (EditText) rootView.findViewById(R.id.video_inputSearch);
    new UpdateData().execute();


    return rootView;
}
 @Override
    public void setUserVisibleHint(boolean isVisibleToUser){
        if (isVisibleToUser == true){
            new AsyncTaskParseJson().execute();
            new UpdateData().execute();
        }
    }

UpdateData:

class UpdateData extends AsyncTask<Void, Void, JSONArray> {
    int error = 0;
    InputStream is = null;
    String result = "";
    JSONArray jArray = null;

    ProgressDialog pd;

    @Override
    protected void onPostExecute(JSONArray result) {
        super.onPostExecute(result);
        pd.dismiss();       
    }

    @Override
    protected void onPreExecute() {

        super.onPreExecute();
        pd = ProgressDialog.show(getActivity(), "",
                "Loading...", true);
    }


    @Override
    protected JSONArray doInBackground(Void... arg0) {

        error = 0;
            url = "************";

        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(url);
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();

        } catch (Exception e) {
            Log.e("log_tag", "Error in http connection " + e.toString());
            error = 1;
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
            is.close();
            result = sb.toString();


        } catch (Exception e) {
            Log.e("log_tag", "Error converting result " + e.toString());
            error = 1;

        }

        deptList.clear();
        try {
            JSONArray array = new JSONArray(result);
            for (int i = 0; i < array.length(); i++) {
                JSONObject j = array.getJSONObject(i);
                EventCalendarStrings d = new EventCalendarStrings();
                d.name = j.optString("name", "");
                    deptList.add(d);

            }

        } catch (JSONException e) {
            Log.e("log_tag", "No connection " + e.toString());
            error = 1;
        }
        return jArray;
    }
}

Logcat:

E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException

Upvotes: 3

Views: 3932

Answers (3)

Desolator
Desolator

Reputation: 22759

I might be late for the party but here's my solution and it works as expected. This solution also prevents your users from re-sending requests again and again (if you're doing network operations).

In all of your child fragments create a boolean variable:

private boolean loadFragmentExecuted = false;

in the child fragments create a generic method called loadFragment and move all of the logic you added in onCreateView to that method:

public void loadFragment()
{
    if(!loadFragmentExecuted)
    {
        //Add your logic to manipulate the UI or load data etc...
        loadFragmentExecuted = true;
    }
}

in your pageview logic create the fragments dynamically like:

//add the fragment
String fragmentName = "com.something." + fragmentId;

//check if the class exists
try
{
    Class myFragmentClass = Class.forName(fragmentName);
    Fragment myFragment = (Fragment) myFragmentClass.newInstance();
    mFragments.add(myFragment);
}
catch (ClassNotFoundException e)
{
    e.printStackTrace();
}
catch (IllegalAccessException e)
{
    e.printStackTrace();
}
catch (InstantiationException e)
{
    e.printStackTrace();
}

then set your pager adapter and attach a tablayout with it:

//set our pager adapter that contains different fragments
mPagerAdapter = new BasePagerAdapter(mFragmentManager, mFragments);

//link the adapter to the viewpager
mViewPager.setAdapter(mPagerAdapter);

//cache fragments
int limit = (mPagerAdapter.getCount() > 0 ? mPagerAdapter.getCount() : 1);
mViewPager.setOffscreenPageLimit(limit);

//add the page listner to the viewPager and link it to the tabLayout
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));

//on tab selected select current viewpager item
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener()
{
    @Override
    public void onTabSelected(TabLayout.Tab tab)
    {
        mViewPager.setCurrentItem(tab.getPosition());

        //get fragment for the selected tab
        Fragment f = mPagerAdapter.getItem(tab.getPosition());

        //load the content of the fragment
        try
        {
            Class c = f.getClass();
            Method loadFragment = c.getMethod("loadFragment");
            loadFragment.invoke(f);
        }
        catch (IllegalAccessException e){}
        catch (InvocationTargetException e){}
        catch (NoSuchMethodException e){}
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab)
    {
    }

    @Override
    public void onTabReselected(TabLayout.Tab tab)
    {
    }
});

Upvotes: 0

Ayzen
Ayzen

Reputation: 983

If I understand your question correctly, you should override setUserVisibleHint(boolean isVisibleToUser) method in your fragments and use it as indicator that your fragment is currently visible (if isVisibleToUser is true). Then you should move there your logic (I suppose it's in onCreateView now) that should be invoked only if a fragment is currently on the screen.

Upvotes: 2

Harsha Vardhan
Harsha Vardhan

Reputation: 3344

Viewpager reads the loaded one...its clever

override this method.

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

POSITION_NONE: data changed, remove the fragment. POSITION_UNCHANGED: data unchanged.

Upvotes: 0

Related Questions