我正在使用ViewPager并且其中包含3个片段。
我知道,当ViewPager第一次加载时,默认加载所有片段,
最少是3个片段,viewpager执行片段的所有生命周期方法。
我注意到的问题:
每当我滑动viewpager时,所选片段都不会再次调用其任何生命周期方法。
因此我无法直接访问全局变量。
例如:如果我在OnCreateView()中初始化了一个首选项,当我尝试通过初始化该片段的实例并调用该片段中的方法来从活动中访问它时,我得到了NPE。
第一次加载后,甚至没有onResume被调用任何片段。
我想知道的事情:
如何在onCreateView()中初始化视图和首选项后才能访问它们?
但是对于在onCreateView()中初始化的按钮,点击它会调用网络服务并按照我的要求完美运行。如何?
过去3天我一直坚持使用这些问题并搜索了很多但未找到我的答案。
任何帮助将不胜感激。
片段代码:
@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();
}
}
答案 0 :(得分:2)
使用以下覆盖方法
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && isResumed()) {
}
}
这将为您提供在用户当前正在查看片段时调用任何内容的选项。
应用可能会将此设置为false,以表明片段的用户界面
*
答案 1 :(得分:1)
您可以保留Fragments
中使用的ViewPager
个实例。这是一个例子:
在ViewPagerAdapter
中定义SparseArray
并覆盖以下方法:
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);
}
并向PageChangeListener
添加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) {
}
});
我希望这对你有帮助。祝你好运!
编辑:
您可以将Fragment的视图公开定义,或者为您的视图和访问片段实例定义一个getter方法,例如:
public TextView mTextView;
或
private TextView mTextVieW;
public TextView getTextView(){
return this.mTextView;
}
您可以像下面这样访问它:
TextView textView = yourFragmentInstance.mTetxView;
或
TextView textview = yourFragmentInstance.getTextView();
答案 2 :(得分:0)
这在我的上一个项目中对我有用。我也喜欢这种方法,因为我不必做任何奇怪的事情。
基本上,在我的viewpager适配器中,我添加了一个跟踪片段标签的方法。相关的职位。
public class TabAdapter extends FragmentPagerAdapter {
private Map<Integer, String> tagMap = new HashMap<>(2); // matches tab count
public TabAdapter(FragmentManager fMgr) {
super(fMgr);
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!
// Capturing the tag that is auto-generated
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment frag = (Fragment) super.instantiateItem(container, position);
tagMap.put(position, frag.getTag());
return frag;
}
/**
* Return the Fragment associated with a specified position.
*
* @param position
*/
@Override
public Fragment getItem(int position) {
Fragment frag = null;
...
return frag;
}
/**
* Return the number of views available.
*/
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
String title = null;
...
return title;
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!
public String getFragmentTag(int position) {
return tagMap.get(position);
}
} // end of class TabAdapter
然后在我的活动(事件方法)中访问:
String fragTag = tabAdapter.getFragmentTag(tabPosition);
Fragment frag = getSupportFragmentManager().findFragmentByTag(fragTag);
当然,这意味着您必须在包含活动中保留适配器的引用。
从这里开始,我的片段将有简单的回调和显式方法来更新我需要更新的任何视图。