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

Posted

技术标签:

【中文标题】ListFragments 错误的数据奇怪的寻呼机【英文标题】:ListFragments Wrong Data Weird Pager 【发布时间】:2012-11-24 06:02:39 【问题描述】:

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

每次启动列表显示片段时,它都会执行一个异步任务来获取 Json 并将其解析为 ArrayList <ArrayList <HashMap <String, String> > >

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

寻呼机的行为很奇怪。也许我不了解片段的生命周期或寻呼机如何使用它们。我有 7 个片段。如果我从 frag3 开始,寻呼机将显示没有数据的片段 3。它还加载没有数据的片段 2 和 4。如果我向左转到片段 1,它将正确显示片段 1 并加载片段 0。我可以正确切换到片段 0,但如果我切换到片段 2,它会从片段 0 加载数据并将片段 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());

片段页面

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];


列表片段

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;


【问题讨论】:

我是否需要像 this PagerAdapter 一样跟踪寻呼适配器中的每个片段? 我只能假设没有人想阅读或者我在问一个愚蠢的问题。 :) 【参考方案1】:

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

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

ListFragmentDisplay 中的一个空数据列表开始并开始任务 最初,您的内部ListFragmnents 将看到数据列表为空,因此您将使用空列表初始化它们(如果listByDay 中没有数据,getList(int day) 方法应该只返回一个空列表字段) 您的任务现在完成了。假设您有来自AsyncTaskonPostExecute 方法的回调。在ListFragmentDisplay 将实现的回调中,您将从ViewPager 更新每个Fragment,它要么当前对用户可见,要么位于FragmentPagerAdapter alive(所以每个@ 987654340@ 不是null 并且它的getView() 方法不会从ViewPager 返回null 将被更新)。另一个 Fragments 将自我更新,因为需要为它们调用 onCreateView 方法,并且您在其中有 updateList 调用。 对于上述要点,请记住调用updateList 方法不会更新可见的Fragment,因为在该方法中,您只需更新您不调用适配器上的notifyDataSetChanged 的片段列表以让它知道数据已更改。

【讨论】:

Thankyou 这看起来很棒但是我应该如何处理片段中的static newInstance() 我应该使用Bundle args = new Bundle(); args.putInt(POSITION, pos); frag.setArguments(args); 之类的东西并通过片段参数访问 int 吗? @doubleA 是的,我在你的代码中错过了这一点(我想这是你首先制作dow 静态的方式)。是的,Bundle 是要走的路,所以Fragment 将保持这个位置。然后在需要时(或在生命周期方法之一中)从参数(getArguments())中检索位置。 太棒了。我正在尝试这个。我会尽快回复您。 我已经使用 Bundle 实现了 Fragment 来访问原始数据。我也在我的 onPostExecute 中接受你对回调方法的建议。起初我只是等到异步任务完成,但回调听起来更加流畅。我只是无法从 ParentFragment 访问片段 upDate() 方法。我确信这是我可以解决的问题,如果不是,那么我会发布一些关于它的内容。非常感谢您对 Luksprog 的帮助。看起来你真的经历了那个代码。我真的很感动。 @doubleA 您很可能使用FragmentPagerAdapter(?!) 因此,要访问来自ViewPager 的片段,请在此处查看我的答案***.com/questions/13729451/… 中的代码。因为您在Fragment 中,所以您需要使用getChildFragmentManager()(末尾的数字是页码)。在该回调中查找当前项目,以及当前项目的左右一个项目(如果你没有弄乱setOffscreenPageLimit)并调用updateList

以上是关于ListFragments 错误的数据奇怪的寻呼机的主要内容,如果未能解决你的问题,请参考以下文章

Android ViewPager,ListFragments以及更新列表中的元素时更新

jQgrid错误的寻呼机结构

free-jqgrid寻呼机不正确

BUG recyclerview 中的某些行在平板电脑的视图寻呼机内不可点击

从imageview加载图像的奇怪问题

嵌套的scrollview + recyclerview,奇怪的自动滚动行为[重复]