在 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仅一次并检查此片段的可访问性,因此有几个选项:
选项 - 在这种情况下,您只实例化 Fragment class 一次,并将此方法用作变量 holder
private HomeFragment hf;
public Fragment getHomeFragment() {
if (hf == null) {
hf = new HomeFragment();
}
return hf;
}
找到已经可见的片段:
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 个工作。
HomeFragment
在onCreateView
中注册AppLocationManager
的监听器,监听变化并更新其TextView。
- 任何其他组件都可以将侦听器注册到
AppLocationManager
,如果他们想要就像 HomeFragment
。
我正在尝试更改调用 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仅一次并检查此片段的可访问性,因此有几个选项:
选项 - 在这种情况下,您只实例化 Fragment class 一次,并将此方法用作变量 holder
private HomeFragment hf; public Fragment getHomeFragment() { if (hf == null) { hf = new HomeFragment(); } return hf; }
找到已经可见的片段:
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 个工作。 HomeFragment
在onCreateView
中注册AppLocationManager
的监听器,监听变化并更新其TextView。- 任何其他组件都可以将侦听器注册到
AppLocationManager
,如果他们想要就像HomeFragment
。