我已经在我的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个不同标签的屏幕截图。
我也搜索过这个问题,并找到了其他对我不起作用的解决方案。其中一个解决方案是,在ItemsAdapter
中添加刷新方法,如下所示:
public void refresh(List<Items> items)
{
this.items = items;
notifyDataSetChanged();
}
而不是mAdapter.notifyDataSetChanged()
我使用了mAdapter.refresh(lstItems);
。但不幸的是,它也没有用。我怎么可能克服这一点。如果我需要进一步详细说明,请告诉我。
答案 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();
}
}