Home > Software design >  Pass data from Parent activity to tab Fragments via an Interface
Pass data from Parent activity to tab Fragments via an Interface

Time:10-25

I have two-tab fragments in my app and in my parent activity I have a DatePicker. I want to load data according to the DatePicker's year and month. I am using an Interface to pass year and month to both fragments. Initially I can send data to both fragments. But after I change values using DatePicker and try to pass year month only the second tab fragment gets the values. First one not even hit. If I remove the interface from the second fragment, then first one works.

BranchProfitabilityActivity

public class BranchProfitabilityActivity extends AppCompatActivity {

    private SendData sendData;
    private Calendar calendar;
    private int selectedMonth, selectedYear;

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

        calendar = Calendar.getInstance(TimeZone.getDefault());

        selectedMonth = calendar.get(Calendar.MONTH);
        selectedYear = calendar.get(Calendar.YEAR);

        String[] tabTiles = {"LIFE", "GENERAL"};

        ViewPager2 viewPager = findViewById(R.id.view_pager);
        TabLayout tabLayout = findViewById(R.id.profit_tabs);

        ProfitabilityViewPagerAdapter myAdapter = new ProfitabilityViewPagerAdapter(this);

        // add Fragments in your ViewPagerFragmentAdapter class
        myAdapter.addFragment(new BranchProfitabilityFragmentLife());
        myAdapter.addFragment(new BranchProfitabilityFragmentGeneral());

        // set Orientation in your ViewPager2
        viewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);

        viewPager.setAdapter(myAdapter);

        new TabLayoutMediator(tabLayout, viewPager,
                (tab, position) -> tab.setText(tabTiles[position])).attach();

    }

    public interface SendData {
        void SendYearMonth(int iYear, int iMonth);
    }

    public void setSendData(SendData sendData) {
        this.sendData = sendData;
        LoadDataFromYearMonth(selectedYear, selectedMonth);
    }

    private void LoadDataFromYearMonth(int year, int month) {
        if (sendData != null) {
            sendData.SendYearMonth(year, month);
        }
    }
}

BranchProfitabilityFragmentLife

public class BranchProfitabilityFragmentLife extends Fragment implements BranchProfitabilityActivity.SendData {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View xView = inflater.inflate(R.layout.fragment_branch_profitability_life, container, false);

        if (getActivity() instanceof BranchProfitabilityActivity) {
            ((BranchProfitabilityActivity) getActivity()).setSendData(this);
        }

        return xView;
    }

    @Override
    public void SendYearMonth(int iYear, int iMonth) {
        RequestData(iYear, iMonth);
    }
}

BranchProfitabilityFragmentGeneral

public class BranchProfitabilityFragmentGeneral extends Fragment implements BranchProfitabilityActivity.SendData {

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View xView = inflater.inflate(R.layout.fragment_branch_profitability_general, container, false);

        if (getActivity() instanceof BranchProfitabilityActivity) {
            ((BranchProfitabilityActivity) getActivity()).setSendData(this);
        }

        return xView;
    }

    @Override
    public void SendYearMonth(int iYear, int iMonth) {
        RequestData(iYear, iMonth);
    }

}

CodePudding user response:

in your Activity you have only one sendData instance. Both fragments are calling registration method setSendData(this), so Activity will save only latter one. if you want both/all this should be stored in some collection, e.g. HashSet or ArrayList

private SendData sendDataSet = new HashSet<SendData>();

public void setSendData(SendData sendData) {
    sendDataSet.add(sendData);
    LoadDataFromYearMonth(selectedYear, selectedMonth);
}

private void LoadDataFromYearMonth(int year, int month) {
    Iterator<SendData > it = sendDataSet.iterator();
    while (it.hasNext()) {
        SendData sendData = it.next()
        sendData.SendYearMonth(year, month);
    }
}

public void removeSendData(SendData sendData) {
    sendDataSet.remove(sendData);
}

don't forget to unregister your interfaces with removeSendData(this) call when Fragment gets killed, e.g. in onDestroyView

  • Related