I have an activity which contains TabLayout setup with ViewPager with 3 fragments These 3 fragments contain some methods unique to each and they need to be called on the click of a button which is a Menu item in a menu to be inflated for the parent activity of these 3 fragments.
Now i am unable to initialize my interface defined in the Activity named OnMenuSaveButonClickListener because im getting an error:
Caused by: java.lang.ClassCastException: com.blah.blah.EditProductInfoActivity cannot be cast to com.blah.blah.EditProductInfoActivity$OnMenuSaveButonClickListener
at com.blah.blah.EditProductInfoActivity.onCreate(EditProductInfoActivity.java:53)
Code for Parent Activity with ViewPager(with fragments in TabLayout):
public class EditProductInfoActivity extends AppCompatActivity {
TabLayout tabLayout;
ViewPager mViewPager;
OnMenuSaveButonClickListener mCallback;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_product_info);
tabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager = (ViewPager) findViewById(R.id.v_pager_prod);
mCallback = (OnMenuSaveButonClickListener) this; //line:53 with error
initViewPager();
private void initViewPager() {
ArrayList<Fragment> fragments = new ArrayList<>();
fragments.add(new CatalogueItemInfoFragment());
fragments.add(new CatalogueItemInventoryFragment());
fragments.add(new CatalogueItemNotesFragment());
ProductTabsViewPagerAdapter productTabs = new ProductTabsViewPagerAdapter(
getSupportFragmentManager(),this, fragments);
mViewPager.setAdapter(productTabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.getTabAt(0).setText("Product Info");
tabLayout.getTabAt(1).setText("Inventory");
tabLayout.getTabAt(2).setText("Notes");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.item_info_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.item_check:
mCallback.onMenuButonClick();
return true;
default: return super.onOptionsItemSelected(item);
}
}
public interface OnMenuSaveButonClickListener{
void onMenuButonClick();
}
}
Code for ViewPager Adpater Class:
public class ProductTabsViewPagerAdapter extends FragmentPagerAdapter {
private Context context;
private List<Fragment> fragments;
public ProductTabsViewPagerAdapter(FragmentManager fm, Context context, List<Fragment> fragments) {
super(fm);
this.context = context;
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
Code for Fragment 1:
public class CatalogueItemInfoFragment extends Fragment implements EditProductInfoActivity.OnMenuSaveButonClickListener {
...
...
public void setItemFromItemForm(){
productViewModel.setSize(productSizeText.getText().toString());
productViewModel.setSizeSelection(productSizeSelectionText.getText().toString());
productViewModel.setColor(productColorText.getText().toString());
}
@Override
public void onMenuButonClick() {
setItemFromItemForm();
}
}
Code for Fragment 2:
public class CatalogueItemInventoryFragment extends Fragment implements EditProductInfoActivity.OnMenuSaveButonClickListener {
...
...
private void setItemInventoryInfo() {
productViewModel.setAvailableQuantity(Integer.parseInt(availableQtyText.getText().toString()));
productViewModel.setIsOutOfStock(outOfStockSwitch.isChecked());
productViewModel.setIsShowOutOfStock(showOutOfStockSwitch.isChecked());
productViewModel.setIsForceAllowOrder(forceAllowOrderSwitch.isChecked());
}
@Override
public void onMenuButonClick() {
setItemInventoryInfo();
}
}
Code for Fragment 3:
public class CatalogueItemNotesFragment extends Fragment implements EditProductInfoActivity.OnMenuSaveButonClickListener {
...
...
private void setItemMoreDetails() {
mStaticProduct.setNotes(productNotesText.getText().toString());
productViewModel.setNotes(productNotesText.getText().toString());
}
@Override
public void onMenuButonClick() {
setItemMoreDetails();
}
}
get the selected tab position from TabLayout so you could target the current fragment visible
int selectedTab = tabLayout.getSelectedTabPosition();
call the OnMenuSaveButonClickListener implementation method from that fragment
((OnMenuSaveButonClickListener) fragments.get(selectedTab)).onMenuButonClick();
this code goes in you activity in the onOptionsItemSelected you can put that logic in a function to avoid repeating the same lines for other menuitem option.
Make sure you remove mCallback and it's assignment from your code.
I suggest you also remove the OnMenuSaveButonClickListener interface definition from your activity and have it in it's own .java (OnMenuSaveButonClickListener.java) > loose coupling.
fragments are implementing the interface, so call method like this:
((OnMenuSaveButonClickListener)fragments.get(i)).onMenuButonClick();
and remove line 53.
So you have the list of fragments in the adapter, add one getter method to get the list of fragments
public List<Fragments> getFragments(){
return fragments;
}
and on click do like this,
final List<Fragment> fragments = productTabs.getFragments();
for (Fragment fragment : fragments) {
if (fragment instanceof OnMenuSaveButonClickListener) {
((OnMenuSaveButonClickListener) fragment).onMenuButonClick();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.