无法刷新在不同选项卡下使用的相同片段内的列表视图数据 [英] Unable to refresh listview data within same fragments used under different tabs

查看:48
本文介绍了无法刷新在不同选项卡下使用的相同片段内的列表视图数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经通过android应用程序中的SmartTabLayout库实现了选项卡功能.目前,我的两个tabs都使用相同的fragment作为viewpager.因为,唯一的区别是视图是对列表项的排序.以下是我的HomeActivity代码:

I have implemented tabs functionality via SmartTabLayout library in my android application. At present I have used same fragment as viewpager for both of my tabs. Since, the only difference is the view is that sorting of listitems. Below is my HomeActivity code:

HomeActivity.java

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

    final ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
    final SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);
    viewPagerTab.setCustomTabView(this);

    FragmentPagerItems pages = new FragmentPagerItems(this);
    pages.add(FragmentPagerItem.of("Test1", SampleFragment.class));
    pages.add(FragmentPagerItem.of("Test2", SampleFragment.class));

    FragmentStatePagerItemAdapter adapter = new FragmentStatePagerItemAdapter(
            getSupportFragmentManager(), pages);

    viewPager.setAdapter(adapter);
    viewPager.setCurrentItem(0);
    viewPagerTab.setViewPager(viewPager);
}

@Override
public View createTabView(ViewGroup container, int position, PagerAdapter adapter) {
    LayoutInflater inflater = LayoutInflater.from(container.getContext());
    View tab = inflater.inflate(R.layout.custom_tab_icon_and_notification_mark, container, false);
    TextView txtTab=(TextView)tab.findViewById(R.id.txtTitle);
    switch (position){
        case 0:txtTab.setText("Test1");break;
        case 1:txtTab.setText("Test2");break;
        default:throw new IllegalStateException("Invalid pos - "+ position);
    }
    return tab;
}

我的SampleFragment.java如下,其中我对服务器执行一些数据请求并更新listview适配器.

My SampleFragment.java is as below wherein I do some server request for data and update the listview adapter.

SampleFragment.java

List<Items> lstItems=new ArrayList<>();
static ItemListAdapter mAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view= inflater.inflate(R.layout.fragment_sample, container, false);
    ListView lstviewItems = (ListView) view.findViewById(R.id.lstItems);
    int position = FragmentPagerItem.getPosition(getArguments());
    View emptyView=view.findViewById(R.id.emptyList);
    lstviewItems.setEmptyView(emptyView);
    mAdapter = new ItemsListAdapter(getActivity(),lstItems);
    lstviewItems.setAdapter(mAdapter);
    switch (position){
        case 0:
            //JsonObjectRequest
            loadItems();
            break;
        case 1:
            //sort the loaded items
            break;
    }
    return view;
}

private void loadItems(){
    try {
        JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET,url, null,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        lstItems.clear();
                        for (int i = 0; i < response.length(); i++) {
                            //Add item to lstItems
                        }
                        mAdapter.notifyDataSetChanged();
                    }
                }
        });
        testApp.getInstance().addToRequestQueue(request);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

但是即使在mAdapter.notifyDataSetChanged()之后,当前viewPager tab中的listview也没有刷新.导航到Test2选项卡时,我可以在列表视图中看到更改,其中数据已正确加载.下面是2个不同标签的屏幕截图.

But even after mAdapter.notifyDataSetChanged() the listview in the current viewPager tab i.e. Test1 tab is not getting refreshed. Whereas when I navigate to Test2 tab, I can see the changes in the listview, where is data has been loaded properly. Below is the screenshot for 2 different tabs.

我也搜索了这个问题,并找到了其他对我不起作用的解决方案.解决方法之一是在ItemsAdapter中添加刷新方法,如下所示:

I've also searched for this problem and found other solution which did not work for me. One of the solution being, adding a refresh method in ItemsAdapter as below:

public void refresh(List<Items> items)
{
    this.items = items;
    notifyDataSetChanged();
}

,而我使用的是mAdapter.refresh(lstItems);而不是mAdapter.notifyDataSetChanged().但不幸的是,它也不起作用.我怎么可能克服这个问题.请让我知道是否需要在此添加更多详细信息.

and instead of mAdapter.notifyDataSetChanged() I used mAdapter.refresh(lstItems);. But unfortunately it did not work either. How can I possibly overcome this. Please let me know if I have to add furthermore details on this.

推荐答案

我认为您的问题在这里:

I think your problem is here:

mAdapter = new ItemsListAdapter(getActivity(),lstItems);

您创建ItemsItemAdapter的新实例,并将其绑定到列表视图,

You create a new instance of ItemsListAdapter and bind it to the listview with

lstviewItems.setAdapter(mAdapter);

问题是此适配器为static.因此,如果您创建一个新实例,则会破坏旧的适配器,而另一个选项卡的listview不再具有用于更新数据的适配器.

The problem is that this adapter is static. So if you create a new instance you destroy the old adapter and the listview of the other tab has not the adapter anymore that updates your data.

我建议将数据加载到中央位置.将响应(您的数据对象)添加到管理器类.然后在每个使用该数据的视图上实现回调(让我们说JsonDataChangedCallback).使用Manager.getInstance().registerCallback()将实现回调的类注册到管理器.然后,每次更改数据时,请致电经理中的updateCallbacks(),所有视图都将更新.这就是在我的应用程序中实现该过程的方式,并且可以正常工作.

I'd recommend to load the data on a central place. Add the response (your data objects) to a manager class. Then implement on every view which using this data a callback (lets say JsonDataChangedCallback). Register the classes which implementing the callback to the manager with Manager.getInstance().registerCallback(). Then every time your data is changed call updateCallbacks() in your manager and all views will be updated. That's the way implemented that process in my app and it works.

示例代码:

public class CDMMovieManager {
  private CDMMovieManager() {
    m_Movies = new ArrayList<>();
    m_MovieChangedCallbacks = new ArrayList<>();
  }

  public static synchronized CDMMovieManager getInstance() {
    if(ms_Instance == null)
      ms_Instance = new CDMMovieManager();

    return ms_Instance;
  }

  public void addMovie(CDMMovie p_Movie) {
    m_Movies.add(p_Movie);
    notifyCallbacks();
  }

  /**
   * Registers a movie changed callback
   *
   * @param p_MovieChangedCallback the callback to register
   */
  public void registerMovieChangedCallback(IDMMovieChangedCallback p_MovieChangedCallback) {
    m_MovieChangedCallbacks.add(p_MovieChangedCallback);
  }

  /**
   * Removes a movie changed callback
   *
   * @param p_MovieChangedCallback the callback to remove
   */
  public void removeMovieChangedCallback(IDMMovieChangedCallback p_MovieChangedCallback) {
    m_MovieChangedCallbacks.remove(p_MovieChangedCallback);
  }

  private void notifyCallbacks() {
    for(IDMMovieChangedCallback l_MovieChangedCallback : m_MovieChangedCallbacks) {
      l_MovieChangedCallback.onMoviesChanged();
    }
  }
}

实施类:

public class CDMBasicMovieFragment extends Fragment implements IDMMovieChangedCallback {

//...
  @Override
  public void onMoviesChanged() {
    m_Adapter.notifyDataSetChanged();
  }
}

这篇关于无法刷新在不同选项卡下使用的相同片段内的列表视图数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆