【问题标题】:How to avoid fragment's list refreshing after Navigation Drawer opens?导航抽屉打开后如何避免片段列表刷新?
【发布时间】:2014-12-18 14:25:16
【问题描述】:

我的片段中有列表,MainActivity 中有 NavigationDrawer。从 NavigationDrawer 我正在调用该片段。当我滚动一点并再次打开 NavigationDrawer 时,列表会刷新并从顶部开始。我猜主要原因是setHasOptionsMenu(true);,因为当我评论这一行时一切正常,但我在 ActionBar 中的搜索不起作用。

当我滚动一点时:

应该是什么样子的:

它的实际外观:

我的片段:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.alllists, container, false);
    View header = inflater.inflate(R.layout.list_header, null);
    ImageView image = (ImageView) header.findViewById(R.id.small_icon);
    navMenuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons);
    Bundle bundle = getArguments();
    position = bundle.getInt("position");
    location = bundle.getString("location");
    image.setImageDrawable(navMenuIcons.getDrawable(position));
    context = getActivity().getApplicationContext();
    DatabaseHandler db = new DatabaseHandler(context);
    items = db.getAllItems(location);
    tmp_items = db.getAllItems(location);
    listView = (ListView) rootView.findViewById(R.id.list);
    adapter = new CustomListAdapter(context, items);
    listView.addHeaderView(header, "", false);
    listView.setAdapter(adapter);
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        }
    });
    setHasOptionsMenu(true);
    return rootView;
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    MenuItem searchItem = menu.findItem(R.id.action_search);
    mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
    mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String s) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String s) {
            if (TextUtils.isEmpty(s)) {
                adapter = new CustomListAdapter(context, tmp_items);
                listView.setAdapter(adapter);
            }
            if (tmp_s.length() > s.length()) {
                adapter.getFilter(tmp_items, true).filter(s);
            } else {
                adapter.getFilter(tmp_items, false).filter(s);
            }
            tmp_s = s;
            return false;
        }
    });
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    mSearchView.setQuery("", false);
}

我更新了我的 newInstance 方法:

public static final AllLists newInstance(int position, String location) {
    AllLists mainfrag = MainActivity.getMainFragment();
    if (mainfrag == null || !mainfrag.getArguments().getString("location").equals(location)) {
        AllLists all = new AllLists();
        Bundle bdl = new Bundle(2);
        bdl.putInt("position", position);
        bdl.putString("location", location);
        all.setArguments(bdl);
        MainActivity.setMainFragment(all);
        return all;
    }
    return mainfrag;
}

主活动:

public static AllLists mainFragment = null;

 ...

public static void setMainFragment(AllLists fragment) {
    mainFragment = fragment;
}

public static AllLists getMainFragment() {
    return mainFragment;
}

为了清楚起见,我这样改变我的片段:

getSupportFragmentManager()
       .beginTransaction()
       .replace(R.id.frame_container, AllLists.newInstance(position, location))
       .commit();

【问题讨论】:

  • 我真的很喜欢模糊和手提包图标(看起来像一张脸)

标签: android android-fragments android-listview navigation-drawer


【解决方案1】:

问题是您的片段视图会在您每次返回时重置。

为了不丢失主片段的状态,您应该在 newIntance 方法中只执行一次“new Fragment()”。您可以创建一个全局变量,例如“mainFragment”,存储创建后的新 Fragment(),然后应用检查您的全局变量,即“mainFragment”是否不为空,然后返回 mainFragment。

这应该可以解决您的问题。但在屏幕旋转时,仍会创建一个新实例,从而再次将您带回列表顶部。旋转问题见:

http://blog.sqisland.com/2014/06/navigationdrawer-creates-fragment-twice.html

【讨论】:

  • 抱歉耽搁了,我不确定我做的一切是否正确。我已经更新了我的 newInstance 方法,但问题并没有消失。
  • 首先你需要为实例化片段保留一个全局变量。如果我没记错的话,我认为您已经创建了一个局部变量。请纠正它,并请通过我答案中的链接,这将解决您所有的问题,不仅与旋转相关,而且还可以用于您提到的问题。
  • 我浏览了该链接,但我发现它与我的情况无关。我更新了我的问题并添加了我的 MainActivity 方法,我在其中设置和获取我的片段。
  • 我不知道为什么它不起作用,根据我的说法,您已正确完成所有操作。如果您可以分享,请将您的代码上传到 github,也许我可以复制它并提供更多帮助,谢谢。很乐意帮助...
  • 看看所有你需要知道的片段:thenewcircle.com/s/post/1250/android_fragments_tutorial请阅读链接中的Saving Fragment State主题。它说默认情况下,如果所有片段都有 id 并且可以覆盖它,则会保存它们。
【解决方案2】:

来自docs

您的片段可以将菜单项贡献给活动的选项 菜单(以及相应的操作栏)通过实现 onCreateOptionsMenu()。为了让这个方法能够接听电话, 但是,您必须在 onCreate() 期间调用 setHasOptionsMenu(),以 表示片段想要将项目添加到选项菜单 (否则,片段将不会收到调用 onCreateOptionsMenu())。

所以,让我们将 setHasOptionsMenu(true); 从您的 onCreateView(...) 调用移动到片段中的 onCreate(...) 覆盖:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多