简体   繁体   English

从 OnOptionsItemSelected 更新片段中的 ListView

[英]Updating ListView in a Fragment from OnOptionsItemSelected

I have a HomeActivity which extends Activity that contains Actionbar items.我有一个 HomeActivity,它扩展了包含 Actionbar 项目的 Activity。 The HomeActivity has 1 fragment (StatusFragment which extends Fragment). HomeActivity 有 1 个片段(扩展片段的状态片段)。 In the Fragment there is a ListView which uses a custom ArrayAdapter and a method call to supply the data.在 Fragment 中有一个 ListView,它使用自定义 ArrayAdapter 和方法调用来提供数据。

private ParseUser[] GetUsers(){
    final ParseQuery<ParseUser> query = ParseUser.getQuery();
    ParseUser[] usersArray;

    try {
        List<ParseUser> users = query.find();
        usersArray = users.toArray(new ParseUser[users.size()]);
    } catch (ParseException e) {
        usersArray = null;
        e.printStackTrace();
    }
    return usersArray;
}

I'm having trouble getting the ListView to update from the OnOptionsItemSelected callback.我无法从 OnOptionsItemSelected 回调获取 ListView 更新。

case R.id.home_ab_refresh:
    StatusFragment pFrag = (StatusFragment) getFragmentManager().findFragmentByTag("mFragment");
    pFrag.users = pFrag.GetUsers();
    pFrag.mAdapter.notifyDataSetChanged();
    return true;

1) Is this an appropriate way to access the Fragment from the Actionbar items (HomeActivity)? 1)这是从操作栏项目(HomeActivity)访问片段的合适方法吗?

2) Is there a better way to design this code? 2)有没有更好的方法来设计这段代码?

Thanks much!非常感谢!

Re 1) I probably wouldn't do a findFragmentByTag() every time, and instead just stick the fragment into a member variable of the activity during the activity's onCreate() . Re 1)我可能不会每次都执行findFragmentByTag() ,而是在活动的onCreate()期间将片段粘贴到活动的成员变量中。

The main issue with the code is something else:代码的主要问题是别的:

   pFrag.users = pFrag.GetUsers();
   pFrag.mAdapter.notifyDataSetChanged();

Here you violate the object-oriented design principle of loose coupling .这里违反了松耦合的面向对象设计原则。 The HomeActivity is too intimately bound to the implementation details of the StatusFragment . HomeActivityStatusFragment的实现细节绑定得太紧密了。 What you should do instead is move that code into the fragment and expose it as a single, public method that is named for the intent (goal, purpose) of the action, not its implementation .相反,您应该做的是将该代码移动到片段中,并将其公开为单个公共方法,该方法以操作的意图(目标、目的)命名,而不是其实现

   // In HomeActivity
   pFrag.reloadData();

   // In the fragment
   public void reloadData() {
       this.users = pFrag.GetUsers();
       this.mAdapter.notifyDataSetChanged();
   }

This way, it's easier to reuse the status fragment elsewhere.这样,可以更轻松地在其他地方重用状态片段。 More importantly, it's easier to evolve that fragment, you can now completely change the internals without having to change the host activity.更重要的是,该片段更容易演化,您现在可以完全更改内部结构,而无需更改主机活动。 This is cleaner from a design perspective.从设计的角度来看,这更清晰。

Re 2) Aside from the issue I already mentioned, you should consider returning an empty array rather than null when an exception occurs. Re 2) 除了我已经提到的问题之外,您应该考虑在发生异常时返回一个空数组而不是null It's generally a better idea to return empty array/collection from finder methods, because people tend to immediately use the result for an iterator or an addAll() or something like that, without null-checking it first.从 finder 方法返回空数组/集合通常是一个更好的主意,因为人们倾向于立即将结果用于迭代器或addAll()或类似的东西,而不先对其进行空检查。

First of all, you dont make a nullpointer check, since you cant be certain that the FragmentManager will actually return a validFragment.首先,您不进行空指针检查,因为您无法确定 FragmentManager 实际上会返回一个有效的片段。

you can however just catch the onOptionsMenuSelected event in the fragment itself, which will result in a much more capsulated code.然而,您可以在片段本身中捕获 onOptionsMenuSelected 事件,这将导致更多的封装代码。

Besides that, when do you refresh the ListView?除此之外,你什么时候刷新ListView? Wouldnt it make sense to update the listview automatically once the new data has arrived?一旦新数据到达,自动更新列表视图是否有意义?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM