Search code examples
androidandroid-fragmentsgridviewadapterandroid-tablayout

How can I use same fragment in different viewpager with different data?


CategoryPagerAdapter.class

public class CategoryPagerAdapter extends FragmentPagerAdapter {

    private Context context;

    private String tabs[] = {"Text","Images","Videos"};

    public CategoryPagerAdapter(Context context, FragmentManager fm) {
        super(fm);

        this.context = context;

    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return tabs[position];
    }

    @Override
    public Fragment getItem(int position) {

        switch (position){
            case 0:
                Fragment textFragment = new CategoryFragment();

                Bundle args = new Bundle();

                args.putString("TEXT","textFragment");

                textFragment.setArguments(args);

                return textFragment;

            case 1:
                Fragment imageFragment = new CategoryFragment();

                Bundle args1 = new Bundle();

                args1.putString("IMAGE","imageFragment");

                imageFragment.setArguments(args1);

                return imageFragment;


            case 2:
                Fragment videoFragment = new CategoryFragment();

                Bundle args2 = new Bundle();

                args2.putString("VIDEO","videoFragment");

                videoFragment.setArguments(args2);

                return videoFragment;

        }
        return null;
    }

    @Override
    public int getCount() {
        return tabs.length;
    }
}

CategoryGridViewAdapter.class This is the gridview class where i want to show different data on selection of diffrent tab.

public class CategoryGridViewAdapter extends BaseAdapter {

    private Context context;

    public CategoryGridViewAdapter(Context context) {

        this.context = context;
    }


    @Override
    public int getCount() {

        return 20;
    }

    @Override
    public Object getItem(int position) {

        return null;
    }

    @Override
    public long getItemId(int position) {

        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater layoutInflater = LayoutInflater.from(context);

        if (convertView == null) {

            convertView = layoutInflater.inflate(R.layout.adapter_category, parent, false);
        }

        return convertView;
    }
}

CategoryFragment.class This is the fragment class which can be the same.

public class CategoryFragment extends Fragment {

    Context context;

    GridView gv_categories;

    View view;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        // Inflate the layout for this fragment

        Bundle args = getArguments();

        String key = args.getString("TEXT");

        if(key.equals("TEXT")){

            view = inflater.inflate(R.layout.fragment_category, container, false);

            context = view.getContext();

            gv_categories = view.findViewById(R.id.gv_categoryGridView);

            CategoryGridViewAdapter categoryGridViewAdapter = new CategoryGridViewAdapter(context);

            gv_categories.setAdapter(categoryGridViewAdapter);



        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            gv_categories.setNestedScrollingEnabled(true);

        }

        gv_categories.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                Intent textStatusIntent = new Intent(context, TextStatus.class);

                textStatusIntent.putExtra("text",""+position);

                context.startActivity(textStatusIntent);

        }

        return view;
    }

}

Solution

  • To support different data set, you must need to pass different data to your adapter based on fragment. For that you can create one interface say Item and give the implementation of this interface for all TextItem, ImageItem and VideoItem.

    Here is rough idea you may use.

    public interface Item {
       String getName();
       String getType();
       String getDescription();
       // Add methods as many you need
    }
    
    public class TextItem implements Item {
     // implement all the methods
    }
    
    public class ImageItem implements Item {
     // implement all the methods
    }
    
    public class VideoItem implements Item {
     // implement all the methods
    }
    

    Then pass List<Item> to the adapter for each fragment.

    Finally modify your CategoryGridViewAdapter .

    private List<Item> listItem;
    
    public CategoryGridViewAdapter(Context context, List<Item> listItem ) {
        this.context = context;
        this.listItem = listItem;
    }
    
    @Override
    public int getCount() {
        return listItem.size();
    }
    
    @Override
    public Object getItem(int position) {
        return listItem.get(position);
    }
    

    Modify your CategoryFragment accordingly

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
       Bundle args = getArguments();
       if(args.contains("TEXT")){
          // do stuff related to TEXT
       } else if(args.contains("IMAGE")){
          // do stuff related to IMAGE
       } else if(args.contains("VIDEO")){
          // do stuff related to VIDEO
       }
    }