не могу изменить tabItem (программа падает), когда я удаляю один из моих tabItems с кодом - PullRequest
1 голос
/ 16 апреля 2019

У меня есть приложение, в котором я динамически создаю TabItems и добавляю их в TabLayout.Я покажу вам код ниже.тогда у меня также есть механизм, который при создании tabitem, пользователь может закрыть его одним нажатием кнопки.СЕЙЧАС: проблема происходит здесь.когда пользователь удаляет это tabitem, и программа автоматически направляет пользователя на другую вкладку.Я больше не могу нажимать на другие вкладки, которые я создал в начале приложения.Я могу нажать на них, но программа закрывается с ошибкой

java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 4, found: 3 Pager

, и все это происходит, когда я удаляю tabitem с кодом, написанным для клика.Ниже приведен мой код MainActivity.java:

public class MainActivity extends AppCompatActivity implements ContactsFragment.CallBacks, UserDetailFragment.DetailCallBacks {

    android.support.v7.widget.Toolbar toolbar;

    public static List<Fragment> fragments = new ArrayList<>();
    public static List<String> fragmentsTitle = new ArrayList<>();
    ViewPager viewPager;
    TabLayout tabLayout;
    int tabposition_number;

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

    public List<String> getFragmentsTitle() {
        return fragmentsTitle;
    }

    public void addToFragments(Fragment fragment) {
        fragments.add(fragment);
    }

    public void addToFragmentsTitle(String title) {
        fragmentsTitle.add(title);
    }

    public Fragment getFragmentsWithPosition(int position) {
        return fragments.get(position);
    }

    public String getFragmentsTitleWithPosition(int position) {
        return fragmentsTitle.get(position);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = new MenuInflater(this);
        menuInflater.inflate(R.menu.top_main_menu,menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == R.id.remove_tab) {
            remove_tab_details(3);
        }
        return super.onOptionsItemSelected(item);
    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_page_drawer);
        this.tabLayout = findViewById(R.id.tab_layout);
        this.viewPager = findViewById(R.id.view_pager);
        tabLayout.setupWithViewPager(viewPager);
        SetUpViewPager(viewPager);
        this.toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        NavigationView navigationView = findViewById(R.id.navigation_view);
        navigationView.setItemIconTintList(null);

        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener(){

            @Override
            public void onTabSelected(TabLayout.Tab tab) {

                if(tab.getPosition() > 2) {
                    tabposition_number = tab.getPosition();
                }

//                viewPager.setCurrentItem(tab.getPosition());

                if(tab.getPosition() == 1) {
                    toolbar.setBackgroundColor(ContextCompat.getColor(MainActivity.this,R.color.tab_contacts));
                    tabLayout.setBackgroundColor(ContextCompat.getColor(MainActivity.this,R.color.main_contacts));
                    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        getWindow().setStatusBarColor(ContextCompat.getColor(MainActivity.this,R.color.status_contacts));
                    }
                } else if(tab.getPosition() == 2) {
                    toolbar.setBackgroundColor(ContextCompat.getColor(MainActivity.this,R.color.tab_register));
                    tabLayout.setBackgroundColor(ContextCompat.getColor(MainActivity.this,R.color.main_register));
                    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        getWindow().setStatusBarColor(ContextCompat.getColor(MainActivity.this,R.color.status_register));
                    }
                } else {
                    toolbar.setBackgroundColor(ContextCompat.getColor(MainActivity.this,R.color.tab_signin));
                    tabLayout.setBackgroundColor(ContextCompat.getColor(MainActivity.this,R.color.main_signin));
                    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        getWindow().setStatusBarColor(ContextCompat.getColor(MainActivity.this,R.color.status_signin));
                    }
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

    }

    public void SetUpViewPager(ViewPager viewPager) {
        MyViewPagerAdapter Adapter = new MyViewPagerAdapter((getSupportFragmentManager()));
        Adapter.AddFragmentPage(new SignInFragment(),"ورود");
        Adapter.AddFragmentPage(new ContactsFragment(),"ارتباطات");
        Adapter.AddFragmentPage(new RegisterFragment(),"ثبت نام");
        Adapter.notifyDataSetChanged();
        viewPager.setAdapter(Adapter);
    }

    @Override
    public void create_user_detail_tab(UserObject userObject) {
        MyViewPagerAdapter Adapter = new MyViewPagerAdapter(getSupportFragmentManager());
        UserDetailFragment userDetailFragment = new UserDetailFragment();
        Bundle bundle = new Bundle();
        bundle.putString("name",userObject.getName());
        bundle.putString("family",userObject.getFamily());
        bundle.putString("email",userObject.getEmail());
        userDetailFragment.setArguments(bundle);
        Adapter.AddFragmentPage(userDetailFragment,userObject.getName());
        viewPager.setAdapter(Adapter);
        TabLayout.Tab tab = tabLayout.getTabAt(1);
        tab.select();
    }

    @Override
    public void delete_previous_tab(int tabposition_number) {
        remove_tab_details(tabposition_number);
        MyViewPagerAdapter myViewPagerAdapter = new MyViewPagerAdapter(getSupportFragmentManager());
        myViewPagerAdapter.notifyDataSetChanged();
    }

    @Override
    public void changeTabItem(boolean mustdelete) {
        ContactsFragment contactsFragment = new ContactsFragment();
        if(tabposition_number > 2 && mustdelete) {
            contactsFragment.setTextView(tabposition_number,mustdelete);
            TabLayout.Tab tab = tabLayout.getTabAt(1);
            tab.select();
        }
    }

    public class MyViewPagerAdapter extends FragmentPagerAdapter {


        public MyViewPagerAdapter(FragmentManager manager) {
            super(manager);
        }

        public void removeTabPage(int position) {
                fragments.remove(position);
                fragmentsTitle.remove(position);
                MyViewPagerAdapter myViewPagerAdapter = new MyViewPagerAdapter(getSupportFragmentManager());
                myViewPagerAdapter.notifyDataSetChanged();
                myViewPagerAdapter.notifyDataSetChanged();
        }

        public void AddFragmentPage(Fragment frag,String title) {
            MainActivity.this.addToFragments(frag);
            MainActivity.this.addToFragmentsTitle(title);
            MyViewPagerAdapter myViewPagerAdapter = new MyViewPagerAdapter(getSupportFragmentManager());
            myViewPagerAdapter.notifyDataSetChanged();
        }

        public Fragment getItem(int position) {
            return MainActivity.this.getFragmentsWithPosition(position);
        }

        public CharSequence getPageTitle(int position) {
            return MainActivity.this.getFragmentsTitleWithPosition(position);
        }


        public int getCount() {
            return fragments.size();
        }
    }

    public void remove_tab_details(int tab_to_delete) {
        //            TabLayout.Tab tab = tabLayout.getTabAt(2);
//            tab.select();
        tabLayout.removeTabAt(tab_to_delete);
        MyViewPagerAdapter Adapter = new MyViewPagerAdapter(getSupportFragmentManager());
        Adapter.removeTabPage(tab_to_delete);
        Adapter.notifyDataSetChanged();
    }



}

и код для UserDetailFragment (который создается, когда пользователь нажимает на один из элементов во фрагменте списка.

public class UserDetailFragment extends Fragment {

    View view;
    DetailCallBacks detailCallBacks;

    public UserDetailFragment() {}

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.user_detail_fragment,null);
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        final Bundle bundle = getArguments();
        String name = (String) bundle.get("name");
        String family = (String)bundle.get("family");
        String email = (String)bundle.get("email");
        TextView nameFamilytv = view.findViewById(R.id.user_detail_name_and_family);
        String nameAndfamily = name + " " + family;
        nameFamilytv.setText(nameAndfamily);
        TextView emailtv = view.findViewById(R.id.user_detail_email);
        emailtv.setText(email);
        Button closebtn = view.findViewById(R.id.detail_close_button);
        closebtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                detailCallBacks.changeTabItem(true);
            }
        });
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        detailCallBacks = (DetailCallBacks)context;
    }

    public interface DetailCallBacks {
        public void changeTabItem(boolean mustdelete);
    }

и последнийно не в последнюю очередь: код для этого элемента списка, который создает динамические вкладки, когда пользователь нажимает на его элементы:

public class ContactsFragment extends ListFragment {

    CallBacks callBacks;
    View view;
    public static int came_fromTabItem;
    public static boolean do_delete;

    public ContactsFragment() { }
    ArrayList<UserObject> userObjects;
    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            userObjects = intent.getParcelableArrayListExtra(Intent_Service.SERVICE_PAYLOAD);
            ArrayAdapter<UserObject> userObjectArrayAdapter = new UserArrayAdapter(context,0,userObjects);
            setListAdapter(userObjectArrayAdapter);
        }
    };

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = new Intent(getActivity(), Intent_Service.class);
        getActivity().startService(intent);

        LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).
                registerReceiver(broadcastReceiver,new IntentFilter(Intent_Service.SERVICE_MESSAGE));
    }

    public void setTextView(int position,Boolean mustDelete) {
        came_fromTabItem = position;
        do_delete = mustDelete;
    }

    @Override
    public void onResume() {
        super.onResume();
        if(came_fromTabItem > 2 && do_delete) {
                final Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                  @Override
                  public void run() {
                      callBacks.delete_previous_tab(came_fromTabItem);
                      do_delete = false;
                      Toast.makeText(getActivity().getApplicationContext(),String.valueOf(came_fromTabItem),Toast.LENGTH_LONG).show();
                  }
    }, 2000);

        }
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        this.view = inflater.inflate(R.layout.fragment_contacts,null);
        return this.view;
    }

    public void onListItemClick(ListView l, View v, int position, long id) {
        UserObject userObject = userObjects.get(position);
        callBacks.create_user_detail_tab(userObject);
    }

    public interface CallBacks {
        public void create_user_detail_tab(UserObject userObject);
        public void delete_previous_tab(int positions);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.callBacks = (CallBacks)context;
    }
}

Итак ... кто-нибудь может мне помочь, пожалуйста? Проблема проста, почему ошибка The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 4, found: 3 появляется, когда убирается табитем, как я могу его решить? спасибо ..

Ответы [ 2 ]

0 голосов
/ 17 апреля 2019

Я решил свою проблему, но, взломав, вы видите, что ошибка была в том, что: TabItems рассчитывает и индексирует от 0, но поскольку мои страницы создаются динамически, я установил getCount() метод моего FragmentPagerAdapter для возврата размера ArrayList<Fragment> fragments, с fragments.size(), с другой стороны, размер ArrayList не считается 0. поэтому для 3 элементов вместо 0 1 2 или номер 2 возвращается к номеру 3.

Итак, вернемся к делу, я был вынужден добавить ноль в мой ArrayList и один ноль в мои заголовки ArrayList, поэтому, когда я удалил свой последний TabItem, программа больше не падает, и чтобы было удобнее, когда пользователь закрывает все Tabs, каждый раз, когда пользователь открывает (добавляет) новый tab, я вызываю fragments.removeAll(Collections.singleton(null));, чтобы очистить каждый нулевой элемент, который я вставил, для TabTitles Too.

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

0 голосов
/ 16 апреля 2019

проблема возникает из-за того, что вы удаляете элемент вкладки, а у вашего пейджера по-прежнему 4 в количестве элементов, вы должны сделать динамический счетчик элементов пейджера и вызывать notifyDataSetChanged() после удаления элемента

.пример

public class MyPagerAdapter extends FragmentPagerAdapter {

int nbrItem;

public ProfilPagerAdapter(FragmentManager fm,String token,Int nbrItem) {
    super(fm);
    this.nbrItem= nbrItem;

  }

@Override
public Fragment getItem(int position) {
     switch(position) {
        case 0 :
            new SignInFragment();    
        case 1 :
            new ContactsFragment()
        case 2 :
            new RegisterFragment()    

    }
    return null;
}

@Override
public int getCount() {

    return nbrItem;
}

   public void setNbrItem(int nbrItem) {
    this.nbrItem= nbrItem;
}

теперь, когда вы удаляете предмет, вы переходите на новый номер предмета к вашему адаптеру

getAdapter().setNbrItem(2);
getAdapter().notifyDataSetChanged();
...