gpt4 book ai didi

Android:在选项卡和返回之间切换时,ListView 烦人地滚动到顶部

转载 作者:太空狗 更新时间:2023-10-29 15:07:16 25 4
gpt4 key购买 nike

我在附加到 CursorAdapter 的 Fragment 中有一个 ListView。 fragment 有 setRetainInstance(true)。在 Fragment 的 onCreate() 方法下,我实例化了 CursorAdapter(将其存储在变量 adapter 中)。然后,我在 Fragment 的 onCreateView 方法下调用 listView.setAdapter(adapter)。 CursorAdapter 中的 Cursor 由 CursorLoader 加载。在我的 LoaderCallbacks 的 onLoadFinished() 中,我调用了 adapter.swapCursor(cursor)

总而言之:一切似乎都已就绪,因此当在选项卡和返回之间切换时,ListView 不应滚动到顶部。但它仍然如此!我会遗漏什么吗?

这是一些代码。

fragment

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

}

}

Activity

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

...

}

}

最佳答案

在 Greg Giacovelli 的帮助下,我找到了解决问题的方法。

我首先声明我不太了解 ListView 位置是如何保存的。每次调用 Fragment 的 onCreateView() 时都会重新创建我的 ListView 实例。例如,当屏幕旋转时会发生这种情况。然而,在屏幕旋转的特定情况下,即使 onCreateView() 被调用并因此重新实例化了 ListView,ListView 的状态仍然被恢复。因此,如果重新创建 ListView,则必须有其他信息告诉它它以前的位置……我不知道那是什么。我认为这归因于 setRetainInstance(true) 的机制。

但让我们看看我的主要问题:为什么 ListView 在选项卡更改之间滚动到顶部?正如 Greg 所建议的那样,这是因为我使用 replace() 重新添加了 Fragment,因此每次用户翻到另一个选项卡并返回时都会破坏我的 Fragment 并重新创建。

我的解决方案是检查选项卡是否已添加;如果是,则不添加;否则,添加它。然后,当用户点击一个选项卡时,我只是简单地分离 fragment (而不是删除它),并附加一个新 fragment 。这样,未选中的选项卡的 fragment 仍然存在,尽管已分离。

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

}

关于Android:在选项卡和返回之间切换时,ListView 烦人地滚动到顶部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20693825/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com