I am using a ViewPager and have 3 Fragments in it.
I know that when the ViewPager loads for the first time it loads all the fragments by default ,
minimum is 3 fragments and viewpager executes all the lifecycle methods of fragments.
Problems I noticed :
Whenever I swipe the viewpager the selected fragment doesn't call any of its lifecycle methods again.
Hence I cannot access the global variables directly.
e.g: if I have a preference initialized in OnCreateView() I am getting NPE when I try to access it from activity by initializing the instance of that fragment and calling a method in that fragment.
Also not even onResume is getting called for any fragment after first loading.
What I want to Know :
How can I access the views and preferences after I have already initialized them in onCreateView() ?
But for the button which is initialized in onCreateView(), on click of it calls the web-services and works perfectly as I want .How ?
I have stuck with these issues from the past 3 days and googled a lot but not found my answers.
Any Help will be appreciated.
Fragment Code :
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_dth, container, false);
preferences=
PreferenceManager.getDefaultSharedPreferences(getActivity());
editor = preferences.edit();
editAmt = (EditText) v.findViewById(R.id.editAmt);
browsplan = (Button) v.findViewById(R.id.browsplan);
Log.e("DTH onCreateView ",""+page);
String fontpath = "fonts/OpenSans-Regular.ttf";
Typeface tf = Typeface.createFromAsset(getActivity().getAssets(),
fontpath);
editCustomerid.setTypeface(tf);
editAmt.setTypeface(tf);
token=preferences.getString("Token","-1");
mobileNo=preferences.getString("userMobileNo","0");
browsplan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//new DTHOperator(getActivity()).execute(); HERE IT WORKS PROPERLY
}
});
return v;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser && isResumed()){
new DTHOperator(getActivity()).execute();
Toast.makeText(getActivity(),"setUserVisibleHint DTH "
,Toast.LENGTH_SHORT).show();
}
}
public class DTHOperator extends AsyncTask<Context, Integer, String> {
Context ctx;
DTHOperator(Context ctx) {
this.ctx = ctx;
}
@Override
protected String doInBackground(Context... params) {
List<NameValuePair> telecomdata = new ArrayList<NameValuePair>();
String result;
Log.d("Register Activity Token", /*preferences.getString("Token", "")*/token);
telecomdata.add(new BasicNameValuePair("mobNo", /*preferences.getString("userMobileNo", "")*/mobileNo));
telecomdata.add(new BasicNameValuePair("requestDate", Utilities.getApiCallTimeFormat()));
telecomdata.add(new BasicNameValuePair("reqFrom", "APP"));
Log.v("PostParameters", "telecomdata" + telecomdata);
if (Connectivity.checkNetwork(ctx)) {
result = rechargeUrl.queryRESTurlONline(ctx, "/GetDTHOperatorsService", "post", telecomdata, GenericConstants.PiPay_root);
} else {
result = GenericConstants.NETWORKNOTFOUND;
displayToast("The Internet Connection appears to be offline");
}
return result;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
MyProgress.show(ctx, "", "");
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
if (result != null) {
if (result.equalsIgnoreCase(GenericConstants.NETWORKNOTFOUND)) {
MyProgress.CancelDialog();
Toast.makeText(ctx,"The Internet Connection appears to be offline",Toast.LENGTH_SHORT).show();
return;
}
String[] resArr = result.split("delimiter_");
if (!resArr[0].equals("500")) {
MyProgress.CancelDialog();
Log.d("DTHOperator Response ::", result);
JSONArray jsonArray = null;
JSONObject object = new JSONObject(result);
jsonArray = object.getJSONArray("data");
for (int i = 0; i < jsonArray.length(); i++) {
if (jsonArray.getJSONObject(i).has("opName")) {
operator.add(jsonArray.getJSONObject(i).getString("opName"));
Log.d("", " Question size " + operator.size());
}
}
if(MyProgress.isShowingProgress())
MyProgress.CancelDialog();
editAmt.setText("2000"); // NPE HERE Also setting the value
} else {
MyProgress.CancelDialog();
displayToast("Failure");
}
}
} catch (Exception e) {
e.printStackTrace();
MyProgress.CancelDialog();
}finally {
if(MyProgress.isShowingProgress())
MyProgress.CancelDialog();
}
}
You can keep instances of Fragments
which you use in your ViewPager
. Here's an example:
In your ViewPagerAdapter
define a SparseArray
and override the methods like below:
SparseArray<Fragment> registeredFragments = new SparseArray<>();
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
And add a PageChangeListener
to your ViewPager
:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
// Here's your fragment instance
// You can access it's methods, variables, views etc.
YourFragment fragment =(YourFragment)yourPagerAdapter.getRegisteredFragment(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
I hope this'll help you. Good luck!
Edit:
You can define your Fragment's Views public or define a getter method for your view and access from your fragment instance such as:
public TextView mTextView;
or
private TextView mTextVieW;
public TextView getTextView(){
return this.mTextView;
}
You can access it like below:
TextView textView = yourFragmentInstance.mTetxView;
or
TextView textview = yourFragmentInstance.getTextView();