我有Fragment
TableLayout
。表中的数据来自SQLite数据库。 SQLite数据库是从AsyncTask
中的MainActivity
中的RESTful Web服务填充的。在填充表之前,Fragment
必须等待任务完成。 Fragment
侦听要调用的任务onPostExecute()
方法。如果是,则调用onLoadAndStoreComplete()
中的方法Fragment
。一切正常。
我需要在片段的TableLayout
方法之外查看OnCreateView()
。如果我能够在onLoadAndStoreComplete
中获得可以让我到那里的片段视图。
Same code as here.
我从MainActivity获得mContext
,但没有与之关联的getView()
方法。
我试过了:
- 在onCreateView()中创建类成员rootView并进行分配,但在onLoadAndStoreComplete()
中,它为null。
- 创建一个类成员tableLayout并在onCreateView()中进行分配,但在onLoadAndStoreComplete()
中,它为null。
- 在onLoadAndStoreComplete()
中再次调用this.getView(),但它返回null
- 在onLoadAndStoreComplete()
内调用充气机,这有效,但后来我不知道在.inflate()
电话中使用容器的内容
我不明白为什么rootView和tableLayout的类成员值在onLoadAndStoreComplete()
public class MyFragment extends Fragment implements OnLoadAndStoreCompleteListener {
private TableLayout tableLayout;
private View rootView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mContext = this.getActivity();
rootView = inflater.inflate(R.layout.fragment_permits, container, false); // this works
tableLayout = (TableLayout) rootView.findViewById(R.id.main_table); // and this
...
}
@Override
public void onLoadAndStoreComplete() {
// rootView is null, ie not remembered from OnCreateView
View view = getView(); // null
LayoutInflater inflater = LayoutInflater.from(getActivity());
rootView = inflater.inflate(R.layout.fragment_permits, container, false); // container? don't know what it should be
// tableLayout is null
tableLayout.addView(tableRow, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
...
}
答案 0 :(得分:6)
getView()
给出了从onCreatedView()
返回的片段的rootView。因此,如果在onLoadAndStoreComplete()
完成之前调用onCreatedView()
(它无法返回您的rootView),则会获得null
,因为尚未创建视图。
我尝试在getView()
内调用onViewCreated()
,这是非空的:
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
View viewer=getView();
if(viewer==null){
Itu.showToast("null",getActivity(), Toast.LENGTH_LONG);
}else{
Itu.showToast(viewer.toString(),getActivity(), Toast.LENGTH_LONG);//This is called
}
}
答案 1 :(得分:6)
如果我正确理解了您的代码,那么您的代码不尊重Fragment生命周期或不同的Fragment实例失败会出现问题。
:一种。生命周期问题
Android框架希望您的Fragment在Activity
方法中创建其视图。 框架调用此方法后,视图可用。
您的代码可能在onCreateView()
之前调用onLoadAndStoreComplete()
,这导致了问题。
您需要提取用数据填充实际视图的方法,因为它可以有2个入口点。请参阅以下代码:
onCreateView()
<强> B中。不同的实例失败
当您在前面提到的片段的2个不同实例上进行操作时,可能会发生这种情况。
首先,所有内容都会按顺序查看:public class MyFragment extends Fragment implements OnLoadAndStoreCompleteListener {
private TableLayout tableLayout;
private View rootView;
private SomeDataClass loadedData;
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
mContext = this.getActivity();
rootView = inflater.inflate(R.layout.fragment_permits, container, false);
tableLayout = (TableLayout) rootView.findViewById(R.id.main_table);
updateUi(); // If onLoadAndStoreComplete() was already called
// this will plug newly created view to returned data
}
@Override
public void onLoadAndStoreComplete() {
loadedData = ...; // Save loaded data here
updateUi(); // If onCreateView() was already called
// this will plug loaded data to the view
}
private void updateUi() {
if (rootView == null) { // Check if view is already inflated
return;
}
if (loadedData != null) {
// View is already inflated and data is ready - update the view!
...
}
}
}
在onCreateView()
之前调用。因此,请检查以下内容:
onLoadAndStoreComplete()
的对象是否与调用onCreateView()
完全相同的对象,您可以使用onLoadAndStoreComplete()
,在这两种方法中获取不同的值是一个不好的信号如果发生这种情况,原因可能隐藏得更深一些,没有代码,我无法就此提供准确的建议。你如何创建你的片段?通过XML或手动然后通过FragmentManager或ViewPager添加?
答案 2 :(得分:2)
在您的代码片段中,如果在调用rootView
后初始化字段tableLayout
和onCreateView(..)
,如果之后两个字段都未设置为null,则在调用时它们必须不为null onLoadAndStoreComplete(..)
。
说,我认为你在片段的不同实例中调用该方法。查看您的活动代码,并检查您是否始终使用片段中的相同实例。
答案 3 :(得分:1)
我需要在OnCreateView()之外获得一个TableLayout的视图 片段的方法。如果我能得到片段的视图 onLoadAndStoreComplete会让我在那里。
尝试更改onLoadAndStoreComplete的定义以获取视图,然后传入片段视图。
答案 4 :(得分:1)
您确定在onCreateView()之后调用onLoadAndStoreComplete()吗?实例变量为null的唯一原因是没有调用初始化它们的方法。
我建议您在onAttach,onDetach,onCreate,onCreateView,onStart,onStop,onLoadAndStoreComplete上调用Log.d,以查看调用的顺序。在那之后,用日志输出更新你的问题,看看哪个可能是问题,我可能会给你一个更简洁的答案。
答案 5 :(得分:1)
您可以进行多项修复:
如果在启动片段之前调用异步任务,则可以在onCreateView(以及所有视图未膨胀)之前调用回调onLoadAndStoreComplete
你可以从onCreateView执行asyncTask,但你必须显示一个加载器来告诉用户应用程序正在同步
您也可以使用listview而不是tableLayout:
public class MyFragment extends Fragment implements OnLoadAndStoreCompleteListener {
private ListView listView;
private View rootView;
private MyAdapter adapter;
private List<T> mDatas; /// This one is populated like you want, from onLoadAndStoreComplete
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mContext = this.getActivity();
rootView = inflater.inflate(R.layout.fragment_permits, container, false); // this works
listView = (ListView) rootView.findViewById(R.id.main_table); // and this
mDatas = new List<>();
adapter = new MyAdapter();
tableLayout.setAdapter(adapter);
}
@Override
public void onLoadAndStoreComplete() {
adapter.notifyDataSetChanged();
}
private class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
// TODO Auto-generated method stub
return mDatas.size() == 0 ? 1 : mDatas.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (mDatas.size()==0){
// inflate new view with only a progressbar indefinite
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_loading, parent, false);
return convertView;
}
else{
// list is populated
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_datas, parent, false);
// do inflating view stuff
return convertView;
}
}
}
您需要将tableLayout修改为ListView(在RelativeLayout内部吗?)