我有一个ListFragment,它为其元素提供了ContextMenu。当我将这个片段放在xml-layout中时,一切正常,但是当我通过FragmentManager以编程方式添加这个ListFragment时,这只能在第一次屏幕旋转时工作。旋转屏幕后,我可以在调试器中看到Android恢复旧的ListFragment并由于
而创建一个新的ListFragmentCustomListFragment fragment = new CustomListFragment();
fragmentTransaction.add(R.id.customFragmentContainer, fragment);
创建新的ListFragment。当我长按项目以打开ContextMenu时,将调用新ListFragment的onCreateContextMenu
方法,并将结果传递给旧ListFragment的onContextItemSelected
方法。
我认为当我发布一些代码时会更清楚:
这是我的ListFragment:
public class CustomListFragment extends ListFragment {
private LayoutInflater layoutInflater;
private OnSelectedListener<String> selectionListener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
layoutInflater = inflater;
return inflater.inflate(R.layout.list_fragment_layout, null);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new CustomListAdapter());
registerForContextMenu(getListView());
}
public void setOnSelectedListener(OnSelectedListener<String> listener) {
selectionListener = listener;
}
private static final String item0 = "item0";
private static final String item1 = "item1";
@Override
public void onCreateContextMenu (ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.add(0, 0, 0, item0);
menu.add(0, 1, 0, item1);
}
@Override
public boolean onContextItemSelected(MenuItem menuItem) {
String selection;
if (menuItem.getItemId()==0)
selection = item0;
else
selection = item1;
if (selectionListener!=null)
selectionListener.onSelected(selection);
return true;
}
private class CustomListAdapter extends BaseAdapter {
private List<String> elemente = new ArrayList<String>();
public CustomListAdapter() {
elemente.add("one");
elemente.add("two");
elemente.add("three");
}
@Override
public int getCount() {
return elemente.size();
}
@Override
public Object getItem(int position) {
return elemente.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView==null)
convertView = layoutInflater.inflate(R.layout.element, null);
TextView tv = (TextView)convertView;
tv.setText(elemente.get(position));
return tv;
}
}
}
使用此活动可以正常工作:
public class CustomFragmentActivity extends FragmentActivity implements OnSelectedListener<String> {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_layout);
FragmentManager fragmentManager = getSupportFragmentManager();
CustomListFragment fragment = (CustomListFragment)fragmentManager.findFragmentById(R.id.customFragment);
fragment.setOnSelectedListener(this);
}
@Override
public void onSelected(String selection) {
Toast.makeText(this, selection, Toast.LENGTH_LONG).show();
}
}
但是使用此活动它只能在第一次屏幕旋转时起作用:
public class CustomFragmentContainerActivity extends FragmentActivity implements OnSelectedListener<String> {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_container_layout);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
CustomListFragment fragment = new CustomListFragment();
fragmentTransaction.add(R.id.customFragmentContainer, fragment);
fragmentTransaction.commit();
fragment.setOnSelectedListener(this);
}
@Override
public void onSelected(String selection) {
Toast.makeText(this, selection, Toast.LENGTH_LONG).show();
}
}
OnSelectedListener只是一个提供单个公共方法的接口。屏幕旋转后,结果(所选项目)将传递给旧的ListFragment。但是这个旧的ListFragment是由Android系统重新创建的,而selectionListener是null,所以没有任何反应。界面如下所示:
public interface OnSelectedListener<V> {
public void onSelected(V selection);
}
最后,也许我应该提一下,我正在使用v4支持库。
答案 0 :(得分:0)
好的,问题是,支持库中存在内存泄漏,onContextItemSelected() - 旧片段的方法被调用。当我返回true时,较新的片段不会调用此方法。