我在附加到CursorAdapter的Fragment中有一个ListView。片段有setRetainInstance(true)
。在Fragment的onCreate()
方法下,我实例化了CursorAdapter(将其存储在变量adapter
中)。然后我在Fragment的listView.setAdapter(adapter)
方法下调用onCreateView
。 CursorAdapter中的Cursor由CursorLoader加载。在我的LoaderCallbacks'onLoadFinished()
中,我致电adapter.swapCursor(cursor)
。
总之:似乎所有内容都已到位,以便在标签和背面之间切换时,ListView不应滚动到顶部。但它仍然存在!我可以错过什么吗?
这是一些代码。
片段
public class Home extends Fragment{
...
private HomeFeedAdapter adapter; // HomeFeedAdapter extends CursorAdapter
private AutoQuery autoQuery; // AutoQuery extends LoaderCallbacks<Cursor>
... // (See inner class, at the end)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
if(adapter == null)
adapter = new HomeFeedAdapter(getActivity(), null);
if(autoQuery == null)
autoQuery = new AutoQuery();
getLoaderManager().initLoader(LOADER_INITIAL, null, autoQuery);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Layout
View v = inflater.inflate(R.layout.home, container, false);
l = (ListView) v.findViewById(R.id.listview);
l.setAdapter(adapter);
return v;
}
private class AutoQuery implements LoaderCallbacks<Cursor>{
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
...
return new CursorLoader(getActivity(), uri,
null, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.swapCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
}
}
活动
public class MainActivity extends SherlockFragmentActivity {
...
private class TabsListener implements ActionBar.TabListener {
private Fragment fragment;
private String tag;
public TabsListener(Fragment fragment, String tag) {
this.fragment = fragment;
this.tag = tag;
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// Do nothing
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(R.id.fragment_container, fragment, tag);
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Layout
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setHomeButtonEnabled(false);
getSupportActionBar().setDisplayShowTitleEnabled(false);
setContentView(R.layout.activity_main);
// Loads fragment
Fragment fHome, fActivity, fProfile;
if((fHome = getSupportFragmentManager().findFragmentByTag(HOME)) == null) fHome = new Home();
if((fActivity = getSupportFragmentManager().findFragmentByTag(ACTIVITY)) == null) fActivity = new FriendsList();
if((fProfile = getSupportFragmentManager().findFragmentByTag(PROFILE)) == null) fProfile = new Profile();
ActionBar.Tab tab;
tab = getSupportActionBar().newTab();
tab.setTabListener(new TabsListener(
fHome,
HOME
));
getSupportActionBar().addTab(tab, false);
tab = getSupportActionBar().newTab();
tab.setTabListener(new TabsListener(
fActivity,
ACTIVITY
));
getSupportActionBar().addTab(tab, false);
tab = getSupportActionBar().newTab();
tab.setTabListener(new TabsListener(
fProfile,
PROFILE
));
getSupportActionBar().addTab(tab, false);
...
}
}
答案 0 :(得分:0)
Greg Giacovelli的帮助引导我朝着正确的方向前进,我找到了解决问题的方法。
我将从一个免责声明开始,我不太清楚如何保存ListView的位置。每次调用Fragment的onCreateView()
时,都会重新创建我的ListView实例。例如,当屏幕旋转时会发生这种情况。然而,在屏幕旋转的特定情况下,即使调用onCreateView()
并因此重新实例化ListView,仍然会恢复ListView的状态。因此,如果正在重新创建ListView,那么其他东西必须告诉它之前的位置是什么......我不知道那是什么。我认为这可归因于setRetainInstance(true)
的机制。
但是让我们看看我的主要问题:为什么ListView会在标签更改之间滚动到顶部?正如格雷格所说,这是因为我正在重新添加片段replace()
,因此每次用户翻转到另一个标签并返回时,都会销毁我的片段并重新创建。
我的解决方案是检查选项卡是否已添加;若然,则不加;否则,添加它。然后,当用户单击选项卡时,我只是分离片段(不删除它),并附加一个新片段。这样,未选中的选项卡的片段仍然存在,但是已经分离。
// Tabs listener
private class TabsListener implements ActionBar.TabListener {
private Fragment fragment;
private String tag;
public TabsListener(Fragment fragment, String tag) {
this.fragment = fragment;
this.tag = tag;
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
if(fragment instanceof ScrollableToTop) ((ScrollableToTop) fragment).scrollToTop();
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if(!fragment.isAdded()){
ft.add(R.id.fragment_container, fragment, tag);
}
ft.attach(fragment);
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.detach(fragment);
}
}