如何使用ViewModel在片段之间共享数据

时间:2019-09-20 04:19:13

标签: java android viewmodel

我有一个主片段,在主片段内,我有一个由嵌套片段(详细片段和摘要片段)组成的ViewPager。如果单击主片段中的按钮,则将在ViewPager的主片段和明细片段中设置数据。问题是如何从详细片段中可以使用的主要片段中获取数据?

我尝试在主片段中使用ViewModel。假设数据应该在Detail Fragment中传递。

//主要片段

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 :(得分:1)

当您观察ViewModel的数据时,您传递了错误的Lifecycle Owner。为了使两个片段都可以通过ViewModel共享数据,生命周期所有者应为Activity。

两个片段都应包含以下内容:

// 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
    }
});