вызов getViewById в классе за пределами фрагмента генерирует исключение нулевого указателя и содержимое - PullRequest
0 голосов
/ 06 мая 2018

Я пытаюсь изменить текст с TextView, который находится в Fragment, когда вызывается функция onLocationChanged.

Я знаю, что мог бы реализовать 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 голосов
/ 06 мая 2018

Вы создаете экземпляр HomeFragment, но он еще не прикреплен к макету, поэтому вы получаете null из getView.

Фрагмент необходимо присоединить к Activity с помощью транзакции из FragmentManager, затем вызывается fragment.onCreateView, тогда getView не вернет ноль.

Для меня причина, по которой вы не хотите использовать слушателя, не в том, что должно быть. Обратный вызов местоположения должен быть глобальным в приложении, учитывающем местоположение, и любой компонент, который должен прослушивать измененное местоположение, может зарегистрировать слушателя в любом месте.

Вот как я это реализую:

  • Имеет одноэлементный класс AppLocationManager, который содержит логику местоположения, он хранит список LocationListener и событие fire для всех слушателей, если местоположение изменилось. AppLocationManager не нужно знать о его зависимостях или о том, чем они являются, он выполняет только одну работу.
  • HomeFragment регистрирует слушателя на AppLocationManager в onCreateView, прослушивает изменение и обновляет его TextView.
  • Любой другой компонент может зарегистрировать слушателя на AppLocationManager, если он хочет, как HomeFragment.
0 голосов
/ 06 мая 2018

Прежде всего, вы, вероятно, не хотите каждый раз инициализировать свой класс фрагмента , вместо этого вам следует создать экземпляр этого класса только один раз и проверить доступность этого фрагмента, поэтому есть несколько вариантов:

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

По крайней мере, попытайтесь опубликовать весь класс, где у вас есть метод onLocationChanged

...