Как обмениваться данными между фрагментами, используя ViewModel - PullRequest
2 голосов
/ 20 сентября 2019

У меня есть основной фрагмент, а внутри основного фрагмента у меня есть ViewPager, который состоит из Nested Fragment (Подробный фрагмент и Сводный фрагмент).Если я нажму кнопку в основном фрагменте, данные будут установлены как в основном фрагменте, так и во фрагментах сведений в ViewPager.Проблема в том, как мне получить данные из основных фрагментов, которые можно использовать во фрагментах Detail?

Я пытался использовать ViewModel в основном фрагменте.Предположим, что данные должны передаваться в подробном фрагменте.

// Основной фрагмент

private void initializeViewPager()
{
    vpExpenses.setOffscreenPageLimit(2);
    setupViewPager(vpExpenses);
}

private void setupViewPager(final ViewPager viewPager)
{
    adapter = new ViewPagerWithTitleAdapter(getFragmentManager());
    adapter.addFragment(new ExpensesDetailsListFragment(), "Detail");
    adapter.addFragment(new ExpensesSummaryListFragment(), "Summary");
    viewPager.setAdapter(adapter);

    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()
    {
        @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
        @Override public void onPageScrollStateChanged(int state) { }
        @Override public void onPageSelected(int position) {
            if(position == 0)
            {
                tvDetailExpenses.setSelected(true);
                tvSummaryExpenses.setSelected(false);
            }
            else if(position == 1)
            {
                tvDetailExpenses.setSelected(false);
                tvSummaryExpenses.setSelected(true);
            }
        }
    });

    tvDetailExpenses.setSelected(true);
    viewPager.setCurrentItem(0);

    tvDetailExpenses.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v)
        {
            viewPager.setCurrentItem(0,false);
        }
    });

    tvSummaryExpenses.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            viewPager.setCurrentItem(1,false);
        }
    });

}

//Expenses Details List
private void setupExpensesDetailsList(String expenseCategoryId)
{
    expensesViewModel = ViewModelProviders.of(this.getActivity()).get(ExpensesViewModel.class);
    expensesViewModel.setToken(token);
    expensesViewModel.setUserId(userId);
    expensesViewModel.setDeviceId("ABCDE1234567890");
    expensesViewModel.setCarId("24");
    expensesViewModel.setExpensesId(expenseCategoryId);

    getExpensesDetailsList();
}

public void getExpensesDetailsList()
{
    expensesViewModel.getExpensesDetailsList().observe(this, expensesdetailslistObserver);
}

public Observer<ExpensesDetailsListResult> expensesdetailslistObserver = new Observer<ExpensesDetailsListResult>() {
    @Override
    public void onChanged(@Nullable ExpensesDetailsListResult result)
    {
        if(result.getStatus())
        {
            summary = result.getData().getSummary();

            tvTotalExpenses.setText("RM"+summary.getYearly());
            tvExpensesPerDay.setText("/ "+summary.getDaily_avg()+" per day");
        }
        else
        {
            if(!result.getStatus())
            {
                if(result.getCode() == 300)
                {
                    new MaterialDialog.Builder(getActivity())
                            .title("Failed")
                            .content(result.getMsg())
                            .positiveText("OK")
                            .show();
                }
                else if(result.getCode() == 302)
                {
                    new MaterialDialog.Builder(getActivity())
                            .title("Failed")
                            .content(result.getMsg())
                            .positiveText("OK")
                            .show();
                }
            }

            if(result.getRedirectLogin() != null)
            {
                if (result.getRedirectLogin())
                {
                    func.showErrorExpired();
                }
            }
        }
    }
};

// Подробный фрагмент

private ExpensesDetailsListResult expensesDetails;
private List<ExpensesTypes> listExpensesType;

private Unbinder unbinder;
private ExpensesViewModel expensesViewModel;

private Function func;

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

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    View view = inflater.inflate(R.layout.fragment_expenses_list_details, container, false);
    unbinder = ButterKnife.bind(this, view);
    func = new Function(getActivity());

    expensesViewModel = ViewModelProviders.of(this.getActivity()).get(ExpensesViewModel.class);

    expensesViewModel.getExpensesDetailsList().observe(this, item -> {
        //expensesDetails = expensesViewModel.setExpensesDetailsList(item);
    });

    return view;
}

// Просмотреть модель

public ExpensesViewModel(@NonNull Application application)
{
    super(application);
}

public void setToken(String token)
{
    this.token = token;
}

public void setUserId(String userId)
{
    this.userId = userId;
}

public void setDeviceId(String deviceId)
{
    this.deviceId = deviceId;
}

public void setCarId(String carId)
{
    this.carId = carId;
}

public void setExpensesId(String expensesId)
{
    this.expensesId = expensesId;
}

//THIS IS THE MAIN FUNCTION THAT UI CONTROLLER CAN OBSERVE FOR CHANGES

//Expenses Category
public MutableLiveData<ExpensesCategoryResult> getExpensesCategory()
{
    expensescategoryObservable = ExpensesRepository.getInstance().getExpensesCategory(token, userId, deviceId);
    return expensescategoryObservable;
}

//Expenses Details List
public MutableLiveData<ExpensesDetailsListResult> getExpensesDetailsList()
{
    expensesdetailslistObservable = ExpensesRepository.getInstance().getExpensesDetailsList(token, userId, deviceId, carId, expensesId, "1");
    return expensesdetailslistObservable;
}

enter image description here

1 Ответ

0 голосов
/ 20 сентября 2019

Вы передаете неправильного владельца жизненного цикла, когда наблюдаете за данными вашей ViewModel.Чтобы оба фрагмента могли обмениваться данными через ViewModel, владельцем жизненного цикла должно быть действие.

Оба фрагмента должны содержать что-то вроде следующего:

// Get the View Model with the Activity as the owner
expensesViewModel = ViewModelProviders.of(getActivity()).get(ExpensesViewModel.class);

// Observe the LiveData by passing in the Activity as the owner, & the observer
expensesViewModel.getExpensesDetailsList().observe(getActivity(),  new Observer<ExpensesDetailsListResult>(){
    @Override
    public void onChanged(ExpensesDetailsListResult result) {
        // Do something with the data according to which Fragment this is in
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...