从OnOptionsItemSelected更新片段中的ListView

时间:2014-01-12 21:52:08

标签: android listview android-fragments

我有一个HomeActivity,它扩展了包含Actionbar项目的Activity。 HomeActivity有1个片段(StatusFragment扩展了Fragment)。在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;
    }

我无法从OnOptionsItemSelected回调中更新ListView。

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

1)这是从Actionbar项目(HomeActivity)访问Fragment的合适方式吗

2)有没有更好的方法来设计这段代码?

非常感谢!

2 个答案:

答案 0 :(得分:2)

Re 1)我可能不会每次都做findFragmentByTag(),而只是在活动onCreate()期间将片段粘贴到活动的成员变量中。

代码的主要问题是:

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

这里违反了loose coupling的面向对象设计原则。 HomeActivityStatusFragment的实现细节密切相关。您应该做的是将该代码移动到片段中并将其作为单个公共方法公开,该方法以操作的 intent (目标,目的)命名,而不是其实现< / em>的

   // In HomeActivity
   pFrag.reloadData();

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

这样,在其他地方重用状态片段就更容易了。更重要的是,进化该片段更容易,您现在可以完全更改内部,而无需更改主机活动。从设计的角度来看,这是更清洁的。

Re 2)除了我已经提到的问题之外,你应该考虑在发生异常时返回一个空数组而不是null。从finder方法返回空数组/集合通常是一个更好的主意,因为人们倾向于立即将结果用于迭代器或addAll()或类似的东西,而不首先对其进行空值检查。

答案 1 :(得分:2)

首先,你不进行nullpointer检查,因为你无法确定FragmentManager是否会实际返回validFragment。

然而,你可以在片段本身捕获onOptionsMenuSelected事件,这将导致更多的封装代码。

除此之外,你什么时候刷新ListView?一旦新数据到达,自动更新列表视图是否有意义?