Как инициализировать интерфейс, определенный в Activity, который реализован с помощью установки 3 фрагментов с ViewPager через TabLayout? - PullRequest
0 голосов
/ 26 февраля 2020

У меня есть действие, которое содержит настройку TabLayout с ViewPager с 3 фрагментами. Эти 3 фрагмента содержат некоторые методы, уникальные для каждого, и их нужно вызывать по нажатию кнопки, которая является элементом меню в меню, которое нужно накачать для родительская активность этих 3 фрагментов.

Теперь я не могу инициализировать мой интерфейс, определенный в Activity с именем OnMenuSaveButonClickListener, потому что я получаю ошибку:

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)

Код для родительской активности с ViewPager (с фрагменты в 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();
    }

}

Код для класса AdPater ViewPager:

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


Код для фрагмента 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();
    }

}

Код для фрагмента 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();

    }

}

Код для фрагмента 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();
    }
}

Tab 1

Tab 2Tab 3

Ответы [ 3 ]

1 голос
/ 26 февраля 2020
  1. получить выбранную позицию вкладки из TabLayout, чтобы вы могли нацелить текущий видимый фрагмент

    int selectedTab = tabLayout.getSelectedTabPosition ();

  2. вызов OnMenuSaveButonClickListener метода реализации из этого фрагмента

    ((OnMenuSaveButonClickListener) фрагментов.get (selectedTab)). onMenuButonClick ();

это код входит в вашу деятельность в onOptionsItemSelected , вы можете поместить эти logi c в функцию, чтобы избежать повторения тех же строк для другой опции menuitem.

Убедитесь, что вы удалили mCallback и это назначение из вашего кода.

Я предлагаю вам также удалить определение интерфейса OnMenuSaveButonClickListener из вашей деятельности и иметь его в своем собственном. java (OnMenuSaveButonClickListener. java )> Слабая связь.

0 голосов
/ 26 февраля 2020

Итак, у вас есть список фрагментов в адаптере, добавьте один метод получения, чтобы получить список фрагментов

public List<Fragments> getFragments(){
    return fragments;
}

и по клику сделайте вот так:

final List<Fragment> fragments = productTabs.getFragments();
    for (Fragment fragment : fragments) {
        if (fragment instanceof OnMenuSaveButonClickListener) {
            ((OnMenuSaveButonClickListener) fragment).onMenuButonClick();
        }
    }
0 голосов
/ 26 февраля 2020

фрагменты реализуют интерфейс, поэтому вызовите метод следующим образом:

((OnMenuSaveButonClickListener)fragments.get(i)).onMenuButonClick();

и удалите строку 53.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...