FragmentPagerAdapter 第一个 Tab 显示错误数据

FragmetPagerAdapter first Tab showing wrong data

我正在尝试使用基于 Cursor 的动态创建的选项卡实现 FragmentPagerAdapter,它从 SQLite 数据库列中检索不同的值。 然后 ListFragment 基于第二个 Cursor 加载数据,即 selects 数据,并使用基于选项卡名称的过滤器。 最后我添加了一个选项卡来包含 "All" 数据,而不是一个子集。

除了将正确的数据输入第一个 "All" sheet 之外,一切正常。 ListFragment onCreateLoader 永远不会达到 select "All" 并根据第二个选项卡的名称以某种方式在第一个和第二个选项卡中提取数据。

My code (filtered for relevance; hopefully not too much)

MainActivity

public class MainActivity extends AppCompatActivity {

    // arraylist of tabs in which tab details are stored
    private ArrayList<String> tabNames;
    // to hold tabs data when first fetch from sqlite db
    private Cursor tabCursor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(com.simsolec.flavorsaver.R.layout.activity_main);

        getTabs();

        // Create an adapter that knows which fragment should be shown on each page
        FlavorFragmentPagerAdapter adapter = new FlavorFragmentPagerAdapter(
                getSupportFragmentManager(), MainActivity.this, tabNames);

        // Find the view pager that will allow the user to swipe between fragments
        ViewPager mViewPager = findViewById(com.simsolec.flavorsaver.R.id.viewpager);
        // Set the adapter onto the view pager
        mViewPager.setAdapter(adapter);

        // Give the TabLayout the ViewPager
        TabLayout tabLayout = findViewById(com.simsolec.flavorsaver.R.id.sliding_tabs);
        tabLayout.setupWithViewPager(mViewPager);
    }
    
    private void getTabs( ){
        try{
            String[] Projection = { FlavorEntry.COLUMN_FLAVOR_RANGE };
            tabCursor = getContentResolver().query(
                    FlavorEntry.CONTENT_URI_DISTINCT,
                    Projection,
                    null,
                    null,
                    FlavorEntry.COLUMN_FLAVOR_RANGE );

            tabNames = new ArrayList();
            tabNames.add("All");

            if (tabCursor != null && tabCursor.getCount() > 0) {
                if(tabCursor.moveToFirst()) {
                    do{
                        String tabName;
                        tabName = tabCursor.getString(0);
                        tabNames.add(tabName);

                    }while (tabCursor.moveToNext());
                }
                tabCursor.close();
            }
        }catch (NullPointerException  | SQLException e) {

        }
        finally {
            tabCursor.close();
        }
    }
}

FragmentPagerAdapter

public class FlavorFragmentPagerAdapter extends FragmentPagerAdapter {
    private Context context;
    private ArrayList<String> mTabNames;

    public FlavorFragmentPagerAdapter(FragmentManager fm, Context context, ArrayList<String> tabNames) {
        super(fm);
        this.context = context;
        mTabNames = tabNames;
    }

    @Override
    public int getCount() {
        //return PAGE_COUNT;
        return mTabNames.size();
    }

    @Override
    public Fragment getItem(int position) {
        // return FlavorListFragment.newInstance(position + 1);
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        String tabName = mTabNames.get(position);
        return FlavorListFragment.newInstance(tabName);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        //Generate title based on item position
        //return tabTitles[position];
        String tabName = mTabNames.get(position);
        return  tabName;
    }
}

ListFragment

public class FlavorListFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>{

    // The fragment argument representing the tab name & number for this fragment.
    private static final String ARG_TAB_NAME ="tabName";

    // Store the tabName for later use
    private static String mTabName;

    public static FlavorListFragment newInstance(String tabName) {
        FlavorListFragment fragment = new FlavorListFragment();
        mTabName = tabName;
        Bundle args = new Bundle();
        args.putString(ARG_TAB_NAME, tabName);
        fragment.setArguments(args);
        return fragment;
    }

    /** Identifier for the flavor data loader */
    private static final int FLAVOR_LOADER = 0;

    /** Adapter for the ListView */
    FlavorCursorAdapter mCursorAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(com.simsolec.flavorsaver.R.layout.fragment_flavor_list,
                container, false);

        // Find the ListView which will be populated with the flavor data
        ListView flavorListView = rootView.findViewById(com.simsolec.flavorsaver.R.id.flavor_list);

        // Setup an Adapter to create a list item for each row of flavor data in the Cursor.
        // There is no flavor data yet (until the loader finishes) so pass in null for the Cursor.
        mCursorAdapter = new FlavorCursorAdapter(getActivity(), null);
        flavorListView.setAdapter(mCursorAdapter);

        // Kick off the loader
        getLoaderManager().initLoader(FLAVOR_LOADER, null, this);

        // Setup the item click listener
        flavorListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                // Create new intent to go to {@link FlavorActivity}
                Intent intent = new Intent(getContext(), FlavorActivity.class);

                // Form the content URI that represents the specific flavor that was clicked on,
                // by appending the "id" (passed as input to this method) onto the
                // {@link FlavorEntry#CONTENT_URI}.
                // For example, the URI would be "content://com.simsolec.flavorsaver/flavors/2"
                // if the flavor with ID 2 was clicked on.
                Uri currentFlavorUri = ContentUris.withAppendedId(FlavorEntry.CONTENT_URI, id);

                // Set the URI on the data field of the intent
                intent.setData(currentFlavorUri);

                // Launch the {@link FlavorActivity} to display the data for the current flavor.
                startActivity(intent);
            }
        });

        return rootView;
    }

    @Override
    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
        // Define a projection that specifies the columns from the table we care about.
        String[] projection = {
                FlavorEntry._ID,
                FlavorEntry.COLUMN_FLAVOR_NAME,
                FlavorEntry.COLUMN_DESCRIPTION_SHORT,
                FlavorEntry.COLUMN_CUP_IMAGE,
                FlavorEntry.COLUMN_RATING };

        // This loader will execute the ContentProvider's query method on a background thread
        String[] selectionArgs;
        if (mTabName=="All") {
            selectionArgs = new String[] {"*"};
        } else {
            selectionArgs = new String[] {mTabName};
        }
        String selection = FlavorEntry.COLUMN_FLAVOR_RANGE + " in (";
        for (int s = 0; s < selectionArgs.length; s++) {
            selection += "?, ";
        }
        selection = selection.substring(0, selection.length() - 2) + ")";
        return new CursorLoader(getActivity(),   // Parent activity context
                FlavorEntry.CONTENT_URI,   // Provider content URI to query
                projection,             // Columns to include in the resulting Cursor
                selection,                   // No selection clause
                selectionArgs,                   // No selection arguments
                FlavorEntry.COLUMN_FLAVOR_NAME + " ASC");                  // Default sort order
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        // Update {@link FlavorCursorAdapter} with this new cursor containing updated flavor data
        mCursorAdapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        // Callback called when the data needs to be deleted
        mCursorAdapter.swapCursor(null);
    }

}

有人能指出我正确的方向吗?

谢谢, -Joost

从 Bundle 而不是 newInstance() 方法中设置 mTabName 的值,因为 mTab​​Name 被定义为静态,因此从 mTabName

中删除静态关键字
 public static FlavorListFragment newInstance(String tabName) {
        FlavorListFragment fragment = new FlavorListFragment();
       // mTabName = tabName;
        Bundle args = new Bundle();
        args.putString(ARG_TAB_NAME, tabName);
        fragment.setArguments(args);
        return fragment;
    }

FlavorListFragment

的 OnCreateView
 @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(com.simsolec.flavorsaver.R.layout.fragment_flavor_list,
                    container, false);


        Bundle b= getArguments();
        //mTabName=b.getString(mTabName);
mTabName=b.getString(ARG_TAB_NAME);
}