проблема с использованием tablayout из динамического числа страниц, получаемых из базы данных - PullRequest
0 голосов
/ 28 октября 2019

Я новичок в Fragments, поэтому извините за вопрос любителя. Мой сценарий в всплеск Activity. Я подключаюсь к API, получаю некоторую информацию и сохраняю их в моем локальном файле (sqlite db), это нормально работает, после этого у меня есть нижняя навигация с 5 кнопками и фрагментами, которые тоже работают нормально, но в категории Fragment язагружаю свою базу данных в Tablayout, где я читаю количество вкладок и имен вкладок из базы данных и снова хочу заполнить вкладки своей базой данных. Здесь я сталкиваюсь с проблемой, когда я получаю некоторые ошибки, но теперь я получаю

  Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.viewpager.widget.ViewPager.setAdapter(androidx.viewpager.widget.PagerAdapter)' on a null object reference

Я уже много искал о Tablayouts и Fragments, но мне ничего не помогло. если вы думаете, что мой полный проект поможет вам лучше помочь мне, или если я пропустил что-то, чтобы показать, вы можете получить к нему доступ через мой git: https://github.com/pouya16/fansyapp

Вот мой HomeActivity, который делает фрагменты для BottomNavigation:

public class HomeActivity extends AppCompatActivity {

final Fragment homeFragment =new HomeFragment();
final Fragment categoriesFragment = new CategoriesFragment();
final Fragment ordersFragment = new OrdersFragment();
final Fragment profileFragment = new ProfileFragement();
final Fragment backupFragment = new BackupFragement();
final FragmentManager fm = getSupportFragmentManager();
Fragment activeFragment = homeFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation_bottom_home);


        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);


        fm.beginTransaction().add(R.id.main_container,backupFragment,"5").hide(backupFragment).commit();
        fm.beginTransaction().add(R.id.main_container,profileFragment,"4").hide(profileFragment).commit();
        fm.beginTransaction().add(R.id.main_container,ordersFragment,"3").hide(ordersFragment).commit();
        fm.beginTransaction().add(R.id.main_container,categoriesFragment,"2").hide(categoriesFragment).commit();
        fm.beginTransaction().add(R.id.main_container,homeFragment,"1").commit();


    }

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        =new BottomNavigationView.OnNavigationItemSelectedListener() {
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
    case R.id.navigation_home:
        fm.beginTransaction().hide(activeFragment).show(homeFragment).commit();
        activeFragment = homeFragment;
        return true;
    case R.id.navigation_categories:
        fm.beginTransaction().hide(activeFragment).show(categoriesFragment).commit();
        activeFragment = categoriesFragment;
        return true;
    case R.id.navigation_orders:
        fm.beginTransaction().hide(activeFragment).show(ordersFragment).commit();
        activeFragment = ordersFragment;
        return true;
    case R.id.navigation_profile:
        fm.beginTransaction().hide(activeFragment).show(profileFragment).commit();
        activeFragment = profileFragment;
        return true;
    case R.id.navigation_backup:
        fm.beginTransaction().hide(activeFragment).show(backupFragment).commit();
        activeFragment = backupFragment;
        return true;
}
        return false;
    }
};
}

Вот фрагмент моей категории, который я хочу создать Tablayout внутри:

public class CategoriesFragment extends Fragment {
    public CategoriesFragment() {
        // Required empty public constructor
    }

    MyApi api = new MyApi();
    TableLayout tabLayout;
    ViewPager viewPager;
    AdaptorViewPager adaptorViewPager;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_categories, container, false);
        tabLayout = (TableLayout) getActivity().findViewById(R.id.tablayout_categories);
        viewPager =(ViewPager) getActivity().findViewById(R.id.viewpager_category);
        try{
            api.createOrOpenDataBase(getActivity());
        }catch (Exception e){
            Toast.makeText(getActivity(),"failed to connect to database",Toast.LENGTH_SHORT);
        }
        SQLiteDatabase db= api.getDatabase();
        int pagesCount = getCount(db);
        String[] pageTitle = new String[pagesCount];
        for(int i = 0;i<pagesCount;i++){
            pageTitle[i] = getPageTitle(db,i);
        }
        Log.i("Log9","number of tabs is: " + pagesCount);
        Log.i("Log9","tab names are: " + pageTitle.toString());
        adaptorViewPager = new AdaptorViewPager(getActivity().getSupportFragmentManager(),pagesCount,pageTitle);
        Log.i("Log9","adaptorViewPager is: " + adaptorViewPager.toString());
        if(adaptorViewPager!=null) {
            viewPager.setAdapter(adaptorViewPager);
            tabLayout.addView(viewPager);
        }
        return view;
    }



    @Override
    public void onResume() {
        super.onResume();
        Log.i("Log1","On resume");
        //getCategories();
    }

    @Override
    public void onPause() {
        Log.i("Log1","on pause");
        super.onPause();
    }

    private String getPageTitle(SQLiteDatabase db, int position) {
        String pageTitle ="";
        try{
            String query = "SELECT * FROM firstcategory";
            Cursor cursor = db.rawQuery(query,null);
            cursor.moveToPosition(position);
            pageTitle = cursor.getString(1);
            Log.i("Log9","pageTitle is: " + pageTitle);

        }catch (Exception e){
            Log.i("Log9","can not respawn category name: " + e.toString());
        }
        return pageTitle;

    }

    private int getCount(SQLiteDatabase db) {
        int pagesCount = 0;
        Log.i("Log9", "Start counting ");
        try{
            String query ="SELECT * FROM firstcategory";
            Cursor cursor = db.rawQuery(query,null);
            while(cursor.moveToNext()){
                pagesCount++;
            }
            Log.i("Log9","page count is: " + pagesCount);

        }catch (Exception e){
            Log.i("Log9","Cant Count ViewPagers Count: " + e.toString());
        }
        return pagesCount;
    }
}

Это Fragment, который должен отображать информацию на каждой вкладке:

public class TabLayoutFragment extends Fragment {
    private int position = 0;


    public TabLayoutFragment(int pos) {
        position = pos;
        // Required empty public constructor
    }

    MyApi api = new MyApi();
    Category category;
    ArrayList<Category> categoryList = new ArrayList<>();
    ListViewAdaptor adaptor;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        api.createOrOpenDataBase(getActivity());
        Log.i("Log7","DataBase Opened Successfully");
        View view =  inflater.inflate(R.layout.fragment_tab_layout, container, false);
        ListView listView = (ListView) getActivity().findViewById(R.id.category_list_item);
        try {
            String query = "SELECT * FROM firstcategory WHERE autoId = '" + position + "'";
            Cursor cursor = api.getDatabase().rawQuery(query, null);
            Log.i("Log7","cursor had made and fetched data");
            cursor.moveToFirst();
            Log.i("Log7","cursor moved to first successfully");
            int child = cursor.getInt(5);
            String parentid = cursor.getString(0);
            int coded = Integer.parseInt(parentid);
            coded = coded - 10;
            if (child > 0) {
                String query1 = "SELECT * FROM secondcategory WHERE parentid = '" + coded + "'";
                Cursor cursor2 = api.getDatabase().rawQuery(query1, null);
                Log.i("Log7","cursor1 created successfully");
                while (cursor2.moveToNext()) {
                    String catTitle = cursor.getString(1);
                    byte[] byteImage = cursor.getBlob(2);
                    Bitmap catImage = BitmapFactory.decodeByteArray(byteImage, 0, byteImage.length);
                    String id = cursor.getString(6);
                    int children = cursor.getInt(8);
                    Category currentCategory = new Category(id, catTitle, catImage, children);
                    categoryList.add(currentCategory);
                }
            } else {

            }
            if(categoryList!=null){
                adaptor = new ListViewAdaptor(getActivity(), categoryList);
                Log.i("Log7","adaptor had made");
            }else{
                Log.i("Log7","adaptor did not made");
            }
            if(adaptor!=null) {
                listView.setAdapter(adaptor);
                Log.i("Log7","ListView had made");
            }else{
                Log.i("Log7","ListView did not made");
            }
        }catch (Exception e){
            Log.i("Log7","Problem Reading tabs from db: " + e.toString());
        }

        return view;
    }

    public static TabLayoutFragment newInstance(int pos) {

        Bundle args = new Bundle();

        TabLayoutFragment fragment = new TabLayoutFragment(pos);
        fragment.setArguments(args);
        return fragment;
    }

}

И последний, но не менее важный адаптер ViewPager:

public class AdaptorViewPager extends FragmentPagerAdapter {
    SQLiteDatabase db;
    int tabsNumber;
    String[] tabNames;


    public AdaptorViewPager(@NonNull FragmentManager fm,int tabCount,String[] tabnames) {
        super(fm);
        tabsNumber=tabCount;
        tabNames = tabnames;
    }

    public AdaptorViewPager(@NonNull FragmentManager fm) {
        super(fm);
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        Log.i("Log10", "Start StartFragments ");
        if(position<0||position>position){
            return null;
        }
        return TabLayoutFragment.newInstance(position);
    }
//Count the numbers of pages in viewpagers
    @Override
    public int getCount() {

        return tabsNumber;
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        String pageTitle =tabNames[position];
        return pageTitle;
    }
}

Данная ошибка:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.esppad.fansy4, PID: 24898
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.esppad.fansy4/com.example.esppad.fansy4.Activities.HomeActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.viewpager.widget.ViewPager.setAdapter(androidx.viewpager.widget.PagerAdapter)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.viewpager.widget.ViewPager.setAdapter(androidx.viewpager.widget.PagerAdapter)' on a null object reference
        at com.example.esppad.fansy4.fragments.CategoriesFragment.onCreateView(CategoriesFragment.java:53)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2595)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:434)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2076)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1866)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1821)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2660)
        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2610)
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1334)
        at android.app.Activity.performStart(Activity.java:7029)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2741)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6494) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 
...