3

I am using Android TabLayout to generate tabs with FragmentStatePagerAdapter as adapter. Now with this code it generates the items on every tab when I scroll it.

SongManager.getAudioListFromResponse(result) gives a List of Audio objects which each have a String called genre. For example the first audio has rock genre and the second one has blues genre.

The getItem() in SongListAdapter makes a new Fragment that uses attributes of one Audio and adds it to the recylerview to be displayed. (I can add the SongListFragment if needed).

At the moment this code is filling all the tabs with the same Fragments. It does not matter which tab I select, they are all the same.

My question would be.. How can I make it so it would get the Audio's genre and sort it accordingly.

Or how can I catch in the main activity Songmanager.getSonglist... that the tab has been swapped and what the title of the tab is.

And also how can I make it so that when I choose I can add a song to recommended tab.

Here is the code where I create the TabLayout :

SongManager.getSonglist(getApplicationContext(), new OkHttp3Connection.OkHttp3RequestCallback() {
        @Override
        public void onSuccess(String result, String user_tag) {

            ViewPager viewPager = findViewById(R.id.viewpager);

            SongListAdapter songListAdapter =
                    new SongListAdapter(getSupportFragmentManager(), getApplicationContext());
            songListAdapter.setAudioList(SongManager.getAudioListFromResponse(result));
            viewPager.setAdapter(songListAdapter);

            // Give the TabLayout the ViewPager
            TabLayout tabLayout = findViewById(R.id.tab_layout);
            tabLayout.setupWithViewPager(viewPager);

            songListAdapter.setItemListener(new SongListAdapter.SongListViewPagerListViewItemListener() {
                @Override
                public void onClick(Audio audio) {
                    goToCameraView();
                    songGraph.setAudio(audio);
                }
            });

            // Iterate over all tabs and set the custom view
            for (int i = 0; i < tabLayout.getTabCount(); i++) {

                TabLayout.Tab tab = tabLayout.getTabAt(i);

                if (tab != null) {
                    tab.setCustomView(songListAdapter.getTabView(i));
                }
            }
        }

        @Override
        public void onError(String error, String user_tag) {
            System.out.println("HTTP Error: " + error);
        }
    });

And the whole SongListAdapter class:

public class SongListAdapter extends FragmentStatePagerAdapter {

    String tabTitles[] = new String[]{"Recommended", "Popular", "Rock", "Pop", "Blues", "Chill"};
    Context context;



    private ArrayList<Audio> audioList;

    public SongListAdapter(FragmentManager fm, Context context) {
        super(fm);
        this.context = context;
    }

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

    @Override
    public SongListFragment getItem(int position) {
        SongListFragment slf = new SongListFragment();
        slf.setAudioList(getAudioList());
        slf.setItemOnClickListener(new SongListFragment.SongListItemOnClickListener() {
            @Override
            public void onClick(Audio audio) {
                System.out.println("asdfdas");
                itemListener.onClick(audio);
            }
        });
        return slf;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        // Generate title based on item position
        return tabTitles[position];
    }

    public View getTabView(int position) {
        View tab = LayoutInflater.from(context).inflate(R.layout.custom_tab, null);
        TextView tv = tab.findViewById(R.id.custom_text);
        tv.setText(tabTitles[position]);
        return tab;
    }

    public ArrayList<Audio> getAudioList() {
        return audioList;
    }

    public void setAudioList(ArrayList<Audio> audioList) {
        this.audioList = audioList;
    }

    SongListViewPagerListViewItemListener itemListener;

    public void setItemListener(SongListViewPagerListViewItemListener itemListener) {
        this.itemListener = itemListener;
    }

    public interface SongListViewPagerListViewItemListener {
        void onClick(Audio audio);
    }
}

Whole result looks like this:

enter image description here

Richard
  • 1,087
  • 18
  • 52

2 Answers2

2

I'll answer for what understand from your question, that is you want to show different list of Audio based on genre in different tabs.

Okay, so I think the first problem is with how you return fragment's instance from SongsListAdapter's getItem method i.e.

@Override
    public SongListFragment getItem(int position) {
        SongListFragment slf = new SongListFragment();
        slf.setAudioList(getAudioList());
        slf.setItemOnClickListener(new SongListFragment.SongListItemOnClickListener() {
            @Override
            public void onClick(Audio audio) {
                System.out.println("asdfdas");
                itemListener.onClick(audio);
            }
        });
        return slf;
    }

Here you are supposed to return different Instances of SongListFragment having filtered AudioList based on Genre. So this could look somethink like:

@Override
    public SongListFragment getItem(int position) {
        SongListFragment slf = new SongListFragment();
        slf.setAudioList(filterBasedOnGenre(getAudioList(), tabTitles[position]));
        slf.setItemOnClickListener(new SongListFragment.SongListItemOnClickListener() {
            @Override
            public void onClick(Audio audio) {
                System.out.println("asdfdas");
                itemListener.onClick(audio);
            }
        });
        return slf;
    }

public ArrayList<Audio> filterBasedOnGenre(ArrayList<Audio> audioList, String genreToFilter)
    {
        ArrayList<Audio> filteredAudioList = new ArrayList<>();

        for (Audio audio : audioList) {
            if (audio.getGenre().equalsIgnoreCase(genreToFilter)) {
                filteredAudioList.add(audio);
            }  
        }
        return filteredAudioList; 
    }

Considering Audio looks like this:

    public class Audio {
           public Audio(String songName, String singer, String genre) {
                this.songName = songName;
                this.singer = singer;
                this.genre = genre;
            }

            private String songName;
            private String singer;
            private String genre;

            public String getSongName() {
                return songName;
            }

            public void setSongName(String songName) {
                this.songName = songName;
            }

            public String getSinger() {
                return singer;
            }

            public void setSinger(String singer) {
                this.singer = singer;
            }

            public String getGenre() {
                return genre;
            }

            public void setGenre(String genre) {
                this.genre = genre;
            }
        }

Hope it helps.
Let me know if you need any more help.

Man
  • 2,720
  • 2
  • 13
  • 21
  • I am sorry, I actually figured out something close to this out but forgot to answer it here. Anyways, thank you for answering and I im guessing I'll give you the bounty but I will wait a day or so. Maybe there is a better solution. – Richard Jul 05 '18 at 10:39
  • Actually, I know there are better ways to implement, because I myself have tried these.I wanted to give simplest fix in less time. I'm glad you found solution by yourself, well done. – Man Jul 05 '18 at 15:32
1

SO Your Figure out solution yourself good. I am currently working on media player app so if you want to cache your songadapater or whatever you need to create cache file to store your array object.

this method to writes cache file.

void createdcachedreadfile(Context con, String filename) throws IOException {
    String tempfile = null;
    for (Songpojo file : songpojoList) {
        FileOutputStream fos = null;
        try {
            fos = con.openFileOutput(filename, Context.MODE_PRIVATE);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(songpojoList);
            oos.close();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

And to retrive

  public Object readCaheFile(Context context1, String filename) throws IOException, ClassNotFoundException {
    FileInputStream fis = context1.openFileInput(filename);
    ObjectInputStream ois = new ObjectInputStream(fis);
    Object object = ois.readObject();
    return object;
}

Maybe this still Helpful

Happy coding!!!!

Jigar Fumakiya
  • 2,039
  • 1
  • 8
  • 21