在Fragment外的类中调用getViewById会生成空指针异常和内容

时间:2018-05-06 15:40:33

标签: android nullpointerexception location fragment getview

我试图在调用TextView函数时更改FragmentonLocationChanged的文字。

我知道我可以在创建LocationListener时实现HomeFragment,但我希望将其模块化。

public void onLocationChanged(Location location) {

    Log.i(TAG,"onLocationChanged method called");

    HomeFragment hf = new HomeFragment();

    if(hf == null)
    {
        Log.i(TAG,"hf is null");
    }
    else {
        if(hf.getView().findViewById(R.id.speed_box) == null)
        {
            Log.i(TAG,"findViewById failed");
        }
        else {
            TextView speedBox = (TextView) hf.getView().findViewById(R.id.speed_box);

            if (location == null) {
                if (speedBox != null) {
                    speedBox.setText("unknown m/s");
                } else {
                    Log.i(TAG, "speedBox object is null");
                }
            } else {
                Log.i(TAG, "onLocationChanged method called, the speed is: " + location.getSpeed());
                float speed = location.getSpeed();

                if (speedBox != null) {
                    speedBox.setText(location.getSpeed() + " m/s");
                }
                {
                    Log.i(TAG, "speedBox object is null");
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

首先,您可能不想在每次 Fragment类时进行初始化,而不是那样,您应该只对该类进行一次实例化,并检查此Fragment的可访问性,以便几个选项:

  1. 选项 - 在这种情况下,您只实例化一次Fragment类,并将此方法用作变量持有者

    private HomeFragment hf; 
    
    public Fragment getHomeFragment() {
        if (hf == null) {
            hf = new HomeFragment();
        }
        return hf; 
    }
    
  2. 查找已经可见的片段:

    Fragment currentFragment = getFragmentManager().findFragmentById(R.id.fragment_container);
    if (currentFragment != null) {
        if (currentFragment instanceof HomeFragment) {
            //do your action
        }
    }
    
  3. 至少,尝试发布整个班级,你有onLocationChanged方法

答案 1 :(得分:0)

您创建了HomeFragment的实例,但它尚未附加到布局,这就是您从null获得getView的原因。

片段需要通过FragmentManager的事务附加到Activity,然后调用fragment.onCreateView,然后getView将不会返回null。

对我来说,你不想使用监听器的原因并非如此。位置回调应该是位置感知应用程序中的全局回调,任何需要侦听位置更改的组件都可以在任何地方注册侦听器。

以下是我将如何实施它:

  • 拥有一个包含位置逻辑的单AppLocationManager类,如果位置发生变化,它会将LocationListener列表和fire事件保存到所有侦听器。 AppLocationManager不需要知道它的依赖关系或它们是什么,它只做1个工作。
  • HomeFragment将监听器注册到AppLocationManager中的onCreateView,收听更改并更新其TextView。
  • 任何其他组件都可以将监听器注册到AppLocationManager,如果他们想要HomeFragment