ListFragments错误的数据奇怪的寻呼机

时间:2012-12-06 08:34:46

标签: android android-viewpager android-listfragment

我希望有人可以帮忙。我有一个Fragment使用支持库托管多个列表片段。列表片段应该显示我在父片段中从异步任务检索的数据。我一直在试图弄清楚数据是如何被加载的,因为它没有正确加载。

每次启动列表显示片段时,它都会预先形成异步任务以获取并将Json解析为ArrayList <ArrayList <HashMap <String, String> > >

每个List片段在父片段中查询ArrayList中其位置的数据。 例如。对于第3页,它应该检索包含`ArrayList&gt;的arrList [2]。显示为列表。

寻呼机表现得很奇怪。也许我不了解片段的生命周期或者寻呼机如何使用它们。我有7个碎片。如果我从frag3开始,寻呼机将显示片段3而没有数据。它还加载片段2和4,没有数据。如果我左转到frag 1它将正确显示片段1并加载片段0.我可以正确切换到frag 0但是如果我切换到frag 2它从frag 0加载数据并将frag 0的数据加载到所有其余的观点。如果我来回走动它会用碎片0中的数据替换每个片段中的所有数据。我相信它不会立即加载数据,因为它在viewpager启动时没有数据。我还没等它等待异步任务。

我认为每次从视图中获取足够远的每个片段都会重新绘制它的视图。所以我把更新放在片段的onCreateView()中。我觉得这是一件小事,我错了,或者我忽略了它。我试图实现FragmentStatePagerAdapter,但我不认为我做得对。

任何帮助都得到了很多赞赏如果我只是做了可怕的错误,我会非常乐于讨论。我经常这样做。它永远不会失败。创建一些东西,找出我需要重写一切。

public class ListFragmentDisplay extends SherlockFragment {
public static final String TAG = "listFragmentDisplay";

Calendar calendar = Calendar.getInstance();
private int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
// listbyday is a list of hash maps each list of hash maps represents a day
// of the week with items for that Object
private ArrayList<ArrayList<HashMap<String, String>>> listByDay = null;
private String objectName = null;
private ViewPager pager;
private FragAdapter adapter;

public ArrayList<HashMap<String, String>> getList(int day) {
    return listByDay.get(day);

}
private void getObjectName() {
    barName = ((MainFragActivity) getActivity()).getobjectSelected();
}
public static ListFragmentDisplay newInstance() {
    return new ListFragmentDisplay();
}
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // Inflate the ListView layout file.
    initArrList();
    getObjectName();
    fillList();
    return inflater.inflate(R.layout.list_view, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    pager = (ViewPager) view.findViewById(R.id.viewPager);
    adapter =new FragAdapter(getChildFragmentManager());
    if (pager.getAdapter() == null)
        pager.setAdapter(adapter);
    reload();
    pager.setOnPageChangeListener(new OnPageChangeListener() {
        @Override
        public void onPageScrollStateChanged(int arg0) {}

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {reload();}

        @Override
        public void onPageSelected(int arg0) {  
        }
    });
    pager.setCurrentItem(dayOfWeek-1);
}
private void initArrList() {
    if (listByDay == null) {
        listByDay = new ArrayList<ArrayList<HashMap<String, String>>>();
    } else {
        listByDay.clear();
    }
    for (int i = 0; i < 7; i++) {
        ArrayList<HashMap<String, String>> hm = new ArrayList<HashMap<String, String>>();
        listByDay.add(hm);
    }
}
synchronized private void fillList() {
    LoadWebTask lWT = new LoadWebTask();
    executeAsyncTask(lWT, getSherlockActivity().getApplicationContext());
}

FragmentPager

public class FragAdapter extends FragmentPagerAdapter {
private static final String[] CONTENT = new String[] { "frag0", "frag1",
        "frag2", "frag3", "frag4", "frag5", "frag6" };
public FragAdapter(FragmentManager fm) {
    super(fm);

}
@Override
public Fragment getItem(int arg0) {
    return MyListFragment.newInstance(arg0);
}
@Override
public int getCount() {
    return CONTENT.length;
}
@Override
public CharSequence getPageTitle(int position) {
    return CONTENT[position % CONTENT.length];
}
}

ListFragment

public class MyListFragment extends SherlockListFragment {
public static final String NAME_TAG = "name";
public static final String DESCRIPTION_TAG = "description";
private static int dow;
public static final String TAG = "listFragment";
// Keys used in Hashmap that will be mapped to the rows
String[] dFrom = { NAME_TAG, DESCRIPTION_TAG };
private ArrayList<HashMap<String, String>> list;
int[] dTo = { R.id.name, R.id.description };
    public void upDateList() {
    //**************************Not really sure if this is how things are supposed 
            //** to be done. For my small data- set i feel like it will work but i would 
            //** be interested in knowing how else this might be done. 
              ListFragmentDisplay lFD = (ListFragmentDisplay) this
            .getParentFragment();
        dList = lFD.getList(dow);
}
public static MyListFragment newInstance(int pos) {
    MyListFragment frag = new MyListFragment();
    dow = pos;
    return (frag);
}
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    upDateList();
    View results = inflater.inflate(R.layout.list_fragment, container,
            false);
    SimpleAdapter adapter = new SimpleAdapter(getParentFragment()
            .getActivity(), list, R.layout.listrow, dFrom, dTo);
    setListAdapter(adapter);
    return results;
}
}

编辑。解决的代码:在列表片段中 初步问题已经解决。我只是在实现对ListFragmentDisplay的onPostExecute回调的过程中。非常感谢Luksprog解决我非常无聊的错误。我在不知道其影响的情况下做了静电。我认为这实际上是Eclipse为解决冲突而提供的东西。我应该仔细阅读它。

 public class MyListFragment extends SherlockListFragment {
public static final String NAME_TAG = "name";
public static final String DESCRIPTION_TAG = "description";

public static final String TAG = "listFragment";
// Keys used in Hashmap that will be mapped to the rows
String[] dFrom = { NAME_TAG, DESCRIPTION_TAG };
private ArrayList<HashMap<String, String>> list;
int[] dTo = { R.id.name, R.id.description };

    SimpleAdapter adapter = null; **NEW**

    public void upDateList() {
                      ListFragmentDisplay lFD = (ListFragmentDisplay) this
            .getParentFragment();
        dList = lFD.getList(getArguments().getInt(TAG)); **NEW**
            if(adapter != null)  **NEW**
            adapter.notifyDataSetChanged(); **NEW**
}
public static MyListFragment newInstance(int pos) {
    MyListFragment frag = new MyListFragment();

    Bundle args = new Bundle(); **NEW**
    args.putInt(TAG, pos); **NEW**
    frag.setArguments(args); **NEW**

    return (frag);
}
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    upDateList();
    View results = inflater.inflate(R.layout.list_fragment, container,
            false);
    adapter = new SimpleAdapter(getParentFragment()
            .getActivity(), list, R.layout.listrow, dFrom, dTo);
    setListAdapter(adapter);
    return results;
}
}

1 个答案:

答案 0 :(得分:1)

是否有任何理由将dow变量从MyListFragment变为static?使用static关键字,ViewPager中的片段将共享其位置,因此大多数情况下您将使用错误的位置调用lFD.getList(dow);方法。将dow设为私有实例字段:private int dow;

关于代码的其余部分,它看起来没问题,看看上面的更改是否解决了问题。要更新内部片段中的数据,您可以遵循以下方案:

  • ListFragmentDisplay中的空数据列表开始,然后启动任务
  • 最初,您的内部ListFragmnents会看到数据列表为空,因此您将使用空列表初始化它们(如果没有数据,getList(int day)方法应该返回一个空列表listByDay字段)
  • 你的任务现在完成了。假设您使用onPostExecute的{​​{1}}方法进行回调。在AsyncTask将实施的回调中,您将更新ListFragmentDisplay中的每个Fragment,该ViewPager当前对用户可见,或者位于FragmentPagerAdapter (因此Fragment的每个null及其getView()方法都不会从null返回ViewPager。其他Fragments会自行更新,因为需要为他们调用onCreateView方法,并且您在其中进行updateList调用。
  • 上述要点请注意,调用updateList方法不会更新可见的Fragment,因为在该方法中,您只需更新未调用的片段列表{{1}在适配器上让它知道数据已经改变。