Загрузка данных в ViewModel, которые были получены в SplashActvity - PullRequest
0 голосов
/ 06 октября 2018

Я новичок в ViewModel и понимаю, что это мощный и простой способ общения с фрагментами.

Моя проблема заключается в следующем: Как загрузить данные, полученные в SplashActivity, в ViewModel mainActivity?

Архитектура моего приложения следующая:

  1. SplashActivity: извлечение данных с модификацией и сохранение их в списке
  2. Основная операция: содержит два фрагмента, отображающих данные вразличные способы

Вот фрагмент кода, показывающий мою реализацию.

SplashActivity

public class SplashActivity extends AppCompatActivity {

    private final String TAG = "TAG.SplashActivity";
    public static List<Toilet> toiletList = new ArrayList<>(); // HERE IS THE DATA I WANT TO 
    RETRIEVE IN THE MAIN ACTIVITY

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /*Create handle for the RetrofitInstance interface*/
        GetDataService service = ...;
        // MY STUFF RETROFIT including
        Intent intent = new Intent(getApplicationContext(), MainActivity.class);
        intent.putExtra("toiletList", (Serializable) toiletList);
        startActivity(intent);
        finish();
    }
}

MainActivity

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

    private final String TAG = getClass().getName();
    private List<Toilet> toiletList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent= getIntent();
        Serializable s = intent.getSerializableExtra("toiletList");
        // Check type and cast
        if (s instanceof List<?>) {
            for (Object o : (List<?>) s) {
                if (o instanceof Toilet) {
                    toiletList.add((Toilet) o);
                }
            }
        }

        // SETTING UP FRAGMENTS
    }
}

FragmentExample

public class MainFragment extends Fragment {

    public static List<Toilet> toiletArrayList = new ArrayList<>();
    private final String TAG = this.getClass().getName();

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

        View view = inflater.inflate(R.layout.fragment_main, container, false);

       // SETTING UP UI
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ToiletListViewModel model = ViewModelProviders.of(this).get(ToiletListViewModel.class);
        model.getToiletList().observe(this, new Observer<List<Toilet>>() {
            @Override
            public void onChanged(@Nullable List<Toilet> toilets) {
                //  update UI
            }
        });
    }
}

ToiletListViewModel

public class ToiletListViewModel extends ViewModel {

    private final String TAG = getClass().getName();
    private MutableLiveData<List<Toilet>> toiletList;

    public LiveData<List<Toilet>> getToiletList() {
        if (toiletList == null) {
            toiletList = new MutableLiveData<>();
            loadToilets();
        }
        return toiletList;
    }

    private void loadToilets() {
        // asynchronously fetch toilets
        // HERE IS MY PROBLEM : How to access the toiletList retrieved
        in the SplashActivity ?
        toiletList.setValue(SplashActivity.toiletList);
    }

    @Override
    protected void onCleared() {
        super.onCleared();
        Log.d(TAG, "onCleared() called");
    }
}

Надеюсь, это понятно.Если вам нужна дополнительная информация, не стесняйтесь спрашивать!

Лучший

Ответы [ 3 ]

0 голосов
/ 06 октября 2018

Есть два предложения:

Вы можете добавить данные в список напрямую (не по теме) :

if (s instanceof List<?>) {
    for (Object o : (List<?>) s) {
        if (o instanceof Toilet) {
            toiletList.add((Toilet) o);
        }
    }
}

используйте это вместо:

if (s instanceof List<?>) {
    toiletList.addAll((List<Toilet>)s);
}

Вернуться к основной теме:

Вы можете взять ViewModel экземпляр Activity вместо этого в Fragment.Как?

Возьмите ViewModel в активности, как показано ниже,

ToiletListViewModel model = ViewModelProviders.of(this).get(ToiletListViewModel.class);

& для Fragment поделитесь вот так,

ToiletListViewModel model = ViewModelProviders.of(getActivity()).get(ToiletListViewModel.class);

Это поделится вашим ViewModel между фрагментами внутри деятельности и наблюдайте за своим livedata.

0 голосов
/ 06 октября 2018

Чтобы использовать модель представления, вам необходимо сохранить ссылку на ее экземпляр в ваших действиях, а затем взаимодействовать с ними для изменения данных.

Прежде всего, я бы предложил вам прочитать руководство разработчика для View Model .

Когда вы настраиваете и сохраняете ссылку на модель вваши действия и фрагменты, вы можете добавить в модель метод, такой как setToilets(List<Toilet>), который обновляет туалеты в модели представления, вызывает loadToilets() или сохраняет необработанные туалеты, чтобы loadToilets() мог позже получить к нему доступ и теперь какие туалетыload.
Затем вы можете получить доступ ко всем данным, которые вы хотите представить из других классов, написав соответствующие методы, как вы это делали с getToiletList(LiveData<Toilet>) -методом.

0 голосов
/ 06 октября 2018

Вы можете поделиться вашим ToiletListViewModel между MainActivity и Fragment s.

Так что вам нужно предоставить ViewModel область действия MainActivity(Это означает, что вы привязали жизненный цикл вашего ViewModel к своей Деятельности) и позвоните initToilets, тогда дочерние фрагменты могут легко получить этот ViewModel и наблюдать по его LiveData.

ToiletListViewModel:

public class ToiletListViewModel extends ViewModel {

    private MutableLiveData<List<Toilet>> toiletList = new MutableLiveData();

    public LiveData<List<Toilet>> getToiletList() {
        return toiletList;
    }

    private void initToilets(List<Toilet> toilets) {
        toiletList.setValue(toilets);
    }


}

MainActivity:

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

    private final String TAG = getClass().getName();
    private List<Toilet> toiletList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent= getIntent();
        Serializable s = intent.getSerializableExtra("toiletList");
        // Check type and cast
        if (s instanceof List<?>) {
            for (Object o : (List<?>) s) {
                if (o instanceof Toilet) {
                    toiletList.add((Toilet) o);
                }
            }
        }
     ToiletListViewModel vm = ViewModelProviders.of(this).get(ToiletListViewModel.class);
     vm.initToilets(toiletList);
        // SETTING UP FRAGMENTS
    }
}

Таким образом, когда вызывается setValue, фрагменты, которые прослушивают toiletList живые данные, будутуведомление.

Примечание:

Вы можете создать общий ViewModel без предоставления его на MainActivity вместо вызова

ViewModelProviders.of(this).get(ToiletListViewModel.class);

в вашемФрагмент до

ViewModelProviders.of(getActivity()).get(ToiletListViewModel.class);
...