切换到替代布局时,LoaderManager restartLoader 无法按预期工作
LoaderManager restartLoader does not work as expected when switching to alternative layout
我的应用有一个选择器和一个 ListFragment。在纵向布局中,微调器用作选择器;在景观中使用列表视图。选择项目时,侦听器将根据所选项目刷新 ListFragment 的内容。下面是代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card_logs);
...
spinner = (Spinner)findViewById(R.id.card_name);
listView = (ListView)findViewById(R.id.card_list);
if (spinner != null)
spinner.setOnItemSelectedListener(this);
if (listView != null) {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CardLogFragment.Entity selected = (CardLogFragment.Entity)listView.getAdapter().getItem(position);
if (selected != null) {
Bundle bundle = new Bundle();
bundle.putLong(CardLogFragment.CARD_ID, id);
CardLogFragment fragment = (CardLogFragment)getFragmentManager().findFragmentById(R.id.cardlog);
// this does not work after portrait->landscape
getLoaderManager().restartLoader(0, bundle, fragment);
// this always works
CardLogsActivity.this.getSupportActionBar().setTitle(
selected.getName()
);
}
}
});
}
@Override
public void onResume() {
super.onResume();
ArrayAdapter<CardLogFragment.Entity> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// populate the adapter
adapter.add(...);
adapter.add(...);
adapter.add(...);
if (spinner != null) {
spinner.setAdapter(adapter);
spinner.setSelection(1);
}
else if (listView != null) {
listView.setAdapter(adapter);
}
}
当我以纵向模式启动应用程序时,它可以正常工作。我更改为横向模式,小部件再次布置得很好。但是当我点击列表视图的一个项目时,列表内容没有更新,只有应用栏的标题发生了变化。所以很明显,getLoaderManager( ).restartLoader(0, bundle,f ragment) 已被调用但没有任何效果。
如果我以横向模式启动应用程序,一切正常 - 列表内容已更新。但是当改成肖像时,肖像的listfragment中的内容并没有更新。
顺便说一句,2个布局文件中的片段具有相同的id,res/layout/下的@+id/cardlog和res/layout-land/下的@id/cardlog。这是正确的吗?
我认为您的主要问题是您使用了封闭 Activity
的 LoaderManager
,同时传入了子 Fragment
作为回调。
Fragment
和 Activity
有不同的 LoaderManager
是有原因的 - 它们有不同的(并且可能不相关的)生命周期。
如果你需要Fragment
作为回调,你需要将所有与Loaders
相关的代码放入那个Fragment
并使用它自己的LoaderManager
。
我的应用有一个选择器和一个 ListFragment。在纵向布局中,微调器用作选择器;在景观中使用列表视图。选择项目时,侦听器将根据所选项目刷新 ListFragment 的内容。下面是代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card_logs);
...
spinner = (Spinner)findViewById(R.id.card_name);
listView = (ListView)findViewById(R.id.card_list);
if (spinner != null)
spinner.setOnItemSelectedListener(this);
if (listView != null) {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CardLogFragment.Entity selected = (CardLogFragment.Entity)listView.getAdapter().getItem(position);
if (selected != null) {
Bundle bundle = new Bundle();
bundle.putLong(CardLogFragment.CARD_ID, id);
CardLogFragment fragment = (CardLogFragment)getFragmentManager().findFragmentById(R.id.cardlog);
// this does not work after portrait->landscape
getLoaderManager().restartLoader(0, bundle, fragment);
// this always works
CardLogsActivity.this.getSupportActionBar().setTitle(
selected.getName()
);
}
}
});
}
@Override
public void onResume() {
super.onResume();
ArrayAdapter<CardLogFragment.Entity> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// populate the adapter
adapter.add(...);
adapter.add(...);
adapter.add(...);
if (spinner != null) {
spinner.setAdapter(adapter);
spinner.setSelection(1);
}
else if (listView != null) {
listView.setAdapter(adapter);
}
}
当我以纵向模式启动应用程序时,它可以正常工作。我更改为横向模式,小部件再次布置得很好。但是当我点击列表视图的一个项目时,列表内容没有更新,只有应用栏的标题发生了变化。所以很明显,getLoaderManager( ).restartLoader(0, bundle,f ragment) 已被调用但没有任何效果。
如果我以横向模式启动应用程序,一切正常 - 列表内容已更新。但是当改成肖像时,肖像的listfragment中的内容并没有更新。
顺便说一句,2个布局文件中的片段具有相同的id,res/layout/下的@+id/cardlog和res/layout-land/下的@id/cardlog。这是正确的吗?
我认为您的主要问题是您使用了封闭 Activity
的 LoaderManager
,同时传入了子 Fragment
作为回调。
Fragment
和 Activity
有不同的 LoaderManager
是有原因的 - 它们有不同的(并且可能不相关的)生命周期。
如果你需要Fragment
作为回调,你需要将所有与Loaders
相关的代码放入那个Fragment
并使用它自己的LoaderManager
。