【问题标题】:ListView in ListFragment keeps accumulating dataListFragment中的ListView不断积累数据
【发布时间】:2015-08-28 01:18:43
【问题描述】:

我无法使用新数据刷新 ListFragment 中的 ListView。而是将新数据添加到以前的数据中。

每个实体的时间段为早上 6 点到下午 5 点。然后将新数据附加到在早上 6 点重新开始的另一个实体的列表中。在将第二个实体添加到 ListView 之前,应清理第一个实体的数据。

代码如下:

public class FragmentStatePagerSupport extends FragmentActivity {

   static final int NUM_ITEMS = 4; //control number of fragments
   MyAdapter mAdapter;
   ViewPager mPager;


   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.fragment_main);

       mAdapter = new MyAdapter(getSupportFragmentManager());
       mPager = (ViewPager)findViewById(R.id.pager);
       mPager.setAdapter(null);
       mPager.setAdapter(mAdapter);
   }

   //===============================================================================================
   public static class MyAdapter extends FragmentStatePagerAdapter {

       public MyAdapter(FragmentManager fm) {
           super(fm);
       }

       @Override
       public int getCount() {
           return NUM_ITEMS;
       }

       @Override
       public Fragment getItem(int position) {
           fragNumber = position;
           return ArrayListFragment.newInstance(position);
       }
   }

   //===============================================================================================
   public static class ArrayListFragment extends ListFragment  {
       Integer mNum;
       String FORMAT_LINE = "%s%7s%7s%10s%16s";

       static ArrayListFragment newInstance(int num) {
           ArrayListFragment f = new ArrayListFragment();
           Bundle args = new Bundle();
           args.putInt("num", num);
           f.setArguments(args);
           return f;
       }

       @Override
       public void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           mNum = getArguments() != null ? getArguments().getInt("num") : 1;
       }

       @Override
       public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                Bundle savedInstanceState) {
           View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
           View tv = v.findViewById(R.id.text);
           View tvd = v.findViewById(R.id.tv_description);

           String title = "";
           switch (mNum){
               case 0:title = MyGlobals.getInstance().getToday();break;
               case 1:title = MyGlobals.getInstance().getTomorrow();break;
               case 2:title = MyGlobals.getInstance().getDayAfter();break;
               case 3:title = MyGlobals.getInstance().getDayDayAfter();break;
           }

           ((TextView) tv).setText(MyGlobals.getInstance().getName() + " on " + title);
           ((TextView) tvd).setText(String.format(FORMAT_LINE, "time", "temp", "rain", "wind", "weather"));
           return v;

       }


       @Override
       public void onActivityCreated(Bundle savedInstanceState) {
           super.onActivityCreated(savedInstanceState);
           ArrayList<Data> row = Data.getRows(mNum);
           ListViewAdapter adapter = new ListViewAdapter(getActivity(), row);
           getListView().setAdapter(null);
           getListView().setAdapter(adapter);
       }


       @Override
       public void onListItemClick(ListView l, View v, int position, long id) {
           v.setBackgroundColor(getResources().getColor(R.color.blue));

       }
   }

   //==============================================================================================
   public static class ListViewAdapter extends ArrayAdapter<Data> {

       public static class ViewHolder{
           TextView time;
           TextView temp;
           TextView rain;
           TextView wind_speed;
           TextView weather;
       }

       public ListViewAdapter(Context context, ArrayList<Data> list) {super(context, R.layout.text_listview, list); }

           @Override
           public View getView(int position, View convertView, ViewGroup parent) {
               Data data = getItem(position);
               ViewHolder holder;
               if(convertView == null){
                   holder=new ViewHolder();
                   LayoutInflater inflater = LayoutInflater.from(getContext());
                   convertView=inflater.inflate(R.layout.text_listview,parent,false);
                   holder.time=(TextView) convertView.findViewById(R.id.time);
                   holder.temp=(TextView) convertView.findViewById(R.id.temp);
                   holder.rain=(TextView) convertView.findViewById(R.id.rain);
                   holder.wind_speed=(TextView) convertView.findViewById(R.id.wind);
                   holder.weather=(TextView) convertView.findViewById(R.id.weather);
                   convertView.setTag(holder);
               }else{
                   holder=(ViewHolder) convertView.getTag();
               }
               holder.time.setText(data.time);
               holder.temp.setText(data.temp);
               holder.rain.setText(data.rain);
               holder.wind_speed.setText(data.wind_speed);
               holder.weather.setText(data.weather);
               return convertView;
           }
   }
}

最后一块填充 ListView。调用 adapter.clear() 和 adapter.notifyDataSetChanged() 不能解决问题。

有一个类似的问题来自 3 年前How update ListView in ListFragment from FragmentActivity?,尽管有 6836 次浏览,但仍然没有被接受。

非常感谢。

请求的 GetRows(mNum) 片段:

public class Data {
  public String time;
  public String temp;
  public String rain;
  public String wind_speed;
  public String weather;

  public Data(String time, String temp, String rain, String wind_speed, String weather) {
    this.time = time;
    this.temp = temp;
    this.rain = rain;
    this.wind_speed = wind_speed;
    this.weather = weather;

  }

  public static ArrayList<Data> getRows(int fragNumber) {

    int mNum = fragNumber;
    int size;
    String myList[] = null;

    ArrayList<Data> list = new ArrayList<Data>();

    switch (mNum) {
        case 0://Today
            size = MyGlobals.getInstance().getToday("time").size();
            myList = new String[size];
            for (int i = 0; i < size; i++) {
                String time = (String) MyGlobals.getInstance().getToday("time").get(i);
                String temp = (String) MyGlobals.getInstance().getToday("temperature").get(i);
                String wind_speed = (String) MyGlobals.getInstance().getToday("wind_speed").get(i);
                String pop = (String) MyGlobals.getInstance().getToday("pop").get(i);
                //String wind_gust = (String) MyGlobals.getInstance().getToday("wind_gust").get(i); //when null breaks code
                String weather = (String) MyGlobals.getInstance().getToday("weather").get(i);

                if (time.length() == 4) time = "0" + time;
                if (wind_speed.length() == 1) wind_speed = "0" + wind_speed;
                if (pop.length() == 1) pop = "0" + pop;
                list.add(new Data(time,temp,pop,wind_speed,weather));

            }
            return list;
        case 1://Tomorrow
            ...snip... same as above with pertinent variables,...
        case 2://DayAfter
            ...snip...
        case 3://DayDayAfter
            ...snip....
        case 4:// is an error
            Log.d("***error***", "list got to case 5");
    }
     return list;
   }
}

【问题讨论】:

  • 您的 LogCat 是否有任何错误?
  • logcat 中没有错误。数据显示正常。

标签: android listview android-fragmentactivity


【解决方案1】:

试试这个;

  • 在将新的数据列表添加到现有列表之前,使用 list.clear();
  • 将新数据添加到列表中,列表中应该只有新添加的数据..
  • 将该列表传递给您的适配器类。
  • 通知适配器新数据,即 adapter.notifyDataSetChanged()

    您在 getRows() 中返回列表两次

  • 去掉case结构前的“返回列表”

    public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // 在添加新列表之前清除此处的旧列表。 如果(列表!= null) { list.clear(); } // 添加新列表

    list = Data.getRows(mNum); ListViewAdapter 适配器 = 新 ListViewAdapter(getActivity(), list); getListView().setAdapter(适配器); 适配器.notifyDataSetChange(); }

【讨论】:

  • 我想我之前尝试过,但由于列表是在 GetRows() 中新创建的,所以它不起作用。尽管如此,我还是会照你说的去做并报告。感谢您的评论。
  • 是的,它也不起作用。如果我在 getListView().setAdapter(adapter); 之后清除列表,则在 onActivityCreated() 中lListView 出来是空白的。在设置适配器之前我也无法清除列表,因为结果是一样的。
  • 在添加新列表之前该列表不存在......所以我不能使用 list.clear()。根据之前的评论,如果我在设置适配器后 list.clear() 则列表视图为空白...
  • 我的代码中似乎存在来自切换活动的内部一致性缺陷。根据提供的代码 sn-ps,这无济于事。我正在尝试找出问题,如果我能纠正它,我会报告。
  • 我发现问题出在:case 0:title = MyGlobals.getInstance().getToday();break;案例1:title = MyGlobals.getInstance().getTomorrow();break;从而另一个活动将更新数据但不清除以前的 ArrayList 因此数据正在累积而不是替换。添加新方法:MyGlobals.getInstance().clear();解决了这个问题。即使问题无法通过您的建议解决,但他们确实让我走上了正轨。因此我接受了你的贡献。谢谢。
【解决方案2】:

因为每次你设置一个Adapter,它确实会被添加。,在重新设置之前先删除它的所有数据,所以它会像

mPager.setAdapter(null);

做之前

mPager.setAdapter(mAdapter);

【讨论】:

  • 谢谢,但它不起作用。如果我在填充 listView 的部分使用相同的想法,即 getListView().setAdapter(null);它也不清洁适配器。
  • 嗯你怎么把setAdapter(null)
  • 我可以看看 Data.getRow 部分
  • 谢谢我在上面添加了Data.class。
猜你喜欢
  • 1970-01-01
  • 2018-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多