Reputation: 73
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
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
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
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