在 Fragment 外部的 class 中调用 getViewById 会生成空指针异常和

calling getViewById in a class outside a Fragment generates null pointer exception and the content of

我正在尝试更改调用 onLocationChanged 函数时 Fragment 中的 TextView 中的文本。

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

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");
                }
            }
        }
    }
}

首先,您可能不想每次都初始化您的 片段 class,相反,您应该实例化此 class仅一次并检查此片段的可访问性,因此有几个选项:

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

    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
        }
    }
    

至少,尝试 post 整个 class,你有 onLocationChanged 方法

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

片段需要通过来自FragmentManager的事务附加到Activity,然后调用fragment.onCreateView,然后getView不会return null .

对我来说,您不想使用侦听器的原因不应该。在位置感知应用程序中,位置回调应该是全局的,任何需要监听位置变化的组件都可以在任何地方注册一个监听器。

下面是我将如何实现它:

  • 有一个保存位置逻辑的单例 AppLocationManager class,它保留 LocationListener 列表并在位置更改时向所有侦听器触发事件​​。 AppLocationManager 不需要知道它的依赖关系或它们是什么,它只做 1 个工作。
  • HomeFragmentonCreateView中注册AppLocationManager的监听器,监听变化并更新其TextView。
  • 任何其他组件都可以将侦听器注册到 AppLocationManager,如果他们想要就像 HomeFragment