2015-09-03 2 views
6

У меня есть фрагмент, который показывает линейную диаграмму, созданную с помощью MPAndroidChart. Загрузка фрагмента занимает около 200 миллисекунд.Выполнить код сразу после того, как фрагмент станет видимым в первый раз

Я хочу улучшить воспринимаемую производительность приложения, загрузив данные данных диаграммы сразу после того, как фрагмент станет видимым.

Поэтому мне нужно выполнить код сразу после того, как фрагмент станет видимым, но только в ПЕРВЫЙ момент он станет видимым.

Я не могу использовать onResume(), так как он вызывается непосредственно перед тем, как фрагмент будет виден.

Примечание: Я не могу использовать asynchrounous задачу, это нужно сделать на UI-потоке. В любом случае это не имеет смысла, поскольку это однократная инициализация, которая занимает около 200 миллисекунд.

+0

Вы говорите, что не можете поместить код в «onResume» фрагмента или в «onResume» активности? – ChrisStillwell

+0

В настоящее время код находится во фрагменте onCreateView(). Я не могу использовать onResume() в любом случае, ни в активности, ни в onResume(). – Mike76

+0

Я не уверен, что понимаю, почему вы не можете использовать «onResume» фрагмента. Этот метод вызывается после того, как фрагмент становится видимым. – ChrisStillwell

ответ

0

Поместите его в метод onViewCreated().

+2

Кажется, что это не так. Он вызывается еще до onResume(). -> ...... "Вызывается сразу после того, как onCreateView (LayoutInflater, ViewGroup, Bundle) вернулась, но до того, как какое-либо сохраненное состояние было восстановлено в представлении. В этот момент иерархия представлений фрагмента не привязана к ее родительскому объекту «. – Mike76

1

Выполнение чего-либо длинного в потоке пользовательского интерфейса - это плохая практика - вы заблокируете весь пользовательский интерфейс для длины вашей обработки (поскольку существует только один поток пользовательского интерфейса). И 200 мс на самом деле очень длинный, это 1/5-й секунды, легко обнаруживаемый человеческим глазом, представьте, что вы играете в игру со скоростью 5 кадров в секунду.

Воспринимаемое представление - все о том, что у него не хватает UI-лагов.

Используйте AsyncTask или AsyncTaskLoader для обработки ваших данных, обратные вызовы будут вызываться в потоке пользовательского интерфейса, поэтому не стоит беспокоиться об этом. Вы можете контролировать, является ли он разовым или нет, сохраняя данные, например, в переменной-члене. Если это null - загрузите, если нет - используйте сразу.

Если ваши данные довольно статичны и не очень большие - предварительно загрузите их перед открытием фрагмента (скажем, при запуске Activity или даже при запуске приложения) и просто передайте данные фрагменту при isntantiating (через аргумент Bundle).

+0

Я не могу использовать AsyncTask, так как мне нужно инициализировать мою диаграмму в потоке пользовательского интерфейса. 200 миллисекунд длиннее, но пользователь не может ничего сделать без этой диаграммы. Поэтому я могу показать только индикатор выполнения для 200 миллисекунд. – Mike76

+0

ваш индикатор выполнения будет заморожен, если вы берете 200 мс времени потока пользовательского интерфейса. Зачем вам это нужно обрабатывать в потоке пользовательского интерфейса? –

+0

Это правда, но обработка связана с обновлением пользовательского интерфейса диаграммы. – Mike76

6
public class MyFragment extends Fragment{ 
    Boolean _areLecturesLoaded =false; 
    @Override 
    onCreateView(){ 
    //Inflate the required views. Code gets executed once View is made but not shown 
    return v; 
} 
@Override 
    public void setUserVisibleHint(boolean isVisibleToUser) { 
     super.setUserVisibleHint(isVisibleToUser); 
     //Code executes EVERY TIME user views the fragment 

     if (isVisibleToUser && !_areLecturesLoaded) { 
      _areLecturesLoaded = true; 
      // Code executes ONLY THE FIRST TIME fragment is viewed. 
     } 
    } 
} 

isVisisbleToUser встроен, и это правда, когда пользователь просматривает текущий фрагмент. Пока пользователь не увидит фрагмент в первый раз, он останется ложным. Если вы хотите, чтобы какой-то код выполнялся каждый раз, когда пользователь просматривал фрагмент, размещайте код в этой области, но вне оператора if.

_areLecturesLoaded инициализируется как ложные и после фрагмента в первый раз, он установлен в истинное обеспечении заявления, если не будет называться в будущем, и код внутри выполняется только один раз

Всей инициализации просмотров кнопки виджетов и т. д., должны быть выполнены в onCreate(), чтобы не было возможности нулевого указателя и других подобных отвратительных исключений.

+0

Спасибо, я попробую. – Mike76

+0

дайте мне знать, если у вас возникнут проблемы. Else действительно принимают ответ. Спасибо –

+0

К сожалению, setUserVisibleHint никогда не получает вызов. Я тестировал его с помощью журналов на Android 4.4. Возможно, это работает только в том случае, если я буду использовать просмотрщик или что-то еще. – Mike76

0

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

public class SettingsFragment extends Fragment { 

    static boolean _areLecturesLoaded = true; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 

     View rootView = inflater.inflate(R.layout.fragment_settings, container, false); 

     return rootView; 
    } 

    private class Getlimits extends AsyncTask<Void, Void, Void> { 
     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      pd = ProgressDialog.show(getActivity(), "", "Loading...", true); 
      pd.setCancelable(false); 
     } 

     @Override 
     protected Void doInBackground(Void... arg0) { 
      //your background code 
      if(_areLecturesLoaded) { 
       try { 
        Thread.sleep(3500); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 

      return null; 
     } 
     @Override 
     protected void onPostExecute(Void result) { 
      super.onPostExecute(result); 
      // Dismiss the progress dialog 
      if (pd.isShowing()) 
       pd.dismiss(); 
      _areLecturesLoaded = false; 
     } 
    } 
} 
Смежные вопросы