无法在不同选项卡

时间:2017-01-03 17:25:07

标签: android listview android-fragments

我已经在我的Android应用程序中通过SmartTabLayout库实现了标签功能。目前,我对fragment的{​​{1}}使用了相同的tabs作为viewpager。因为,唯一的区别是视图是listitems的排序。以下是我的HomeActivity代码:

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适配器。

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 listview中的tab,即Test1标签也未获得刷新。而当我导航到Test2选项卡时,我可以看到列表视图中的更改,数据已正确加载到哪里。以下是2个不同标签的屏幕截图。

Tabs

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

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

而不是mAdapter.notifyDataSetChanged()我使用了mAdapter.refresh(lstItems);。但不幸的是,它也没有用。我怎么可能克服这一点。如果我需要进一步详细说明,请告诉我。

1 个答案:

答案 0 :(得分:1)

我认为你的问题在这里:

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

您可以创建ItemsListAdapter的新实例,并使用

将其绑定到列表视图

lstviewItems.setAdapter(mAdapter);

问题是此适配器是static。因此,如果您创建一个新实例,则销毁旧适配器,而另一个选项卡的列表视图不再具有更新数据的适配器。

修改

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

示例代码:

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();
  }
}