Disclosure up front, this is a school project.
I've been working on an activity in a project that consists of a series of dynamic action bar tabs and list fragments, and have been stuck on the prospect of getting object references to the specific tab fragments in order to set adapters for the list views.
I have it set up at the moment using a ViewPager (the support v4 version) and a FragmentStatePagerAdapter (v13). I've tried methods mentioned in a few SO question threads, namely these three:
Updating fragments/views in viewpager with fragmentStatePagerAdapter
Retrieve a Fragment from a ViewPager
Android ViewPager - can't update dynamically
However, each of these attempts have been to no avail, here is the relevant code from my attempt to try and demonstrate what I'm trying to accomplish.
The code for the FragmentStatePagerAdapter:
/**
* The Class ServerPagerAdapter.
*/
private class ServerPagerAdapter extends FragmentStatePagerAdapter
{
SparseArray<ServerViewFragment> registeredFragments = new SparseArray<ServerViewFragment>();
/**
* Instantiates a new server pager adapter.
*
* @param fm the fragment manager
*/
public ServerPagerAdapter(FragmentManager fm)
{
super(fm);
}
/* (non-Javadoc)
* @see android.support.v13.app.FragmentPagerAdapter#getItem(int)
*/
@Override
public Fragment getItem(int position)
{
ServerViewFragment serverFrag = new ServerViewFragment();
registeredFragments.put(position, serverFrag);
return serverFrag;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object)
{
super.destroyItem(container, position, object);
registeredFragments.remove(position);
}
/* (non-Javadoc)
* @see android.support.v4.view.PagerAdapter#getCount()
*/
@Override
public int getCount()
{
// TODO STATIC VALUE.
return 3;
}
/* (non-Javadoc)
* @see android.support.v4.view.PagerAdapter#getPageTitle(int)
*/
@Override
public CharSequence getPageTitle(int position)
{
//TODO: HARD CODED
switch (position)
{
case 0:
return "Status";
case 1:
return "#chat";
case 2:
return "#help";
}
return null;
}
public ServerViewFragment getFragment(int position)
{
return registeredFragments.get(position);
}
}
The code in the activity that I'm trying to get to work:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_server_view);
/*Code omitted (actionbar navigation)*/
//connect pager
servPagerAdapter = new ServerPagerAdapter(getFragmentManager());
viewPager = (ViewPager)findViewById(R.id.server_view_pager);
viewPager.setAdapter(servPagerAdapter);
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
{
@Override
public void onPageSelected(int position)
{
actionBar.setSelectedNavigationItem(position);
}
});
//populate tabs
for (int i = 0; i < servPagerAdapter.getCount(); i++)
{
Tab tabToAdd = actionBar.newTab();
tabToAdd.setText(servPagerAdapter.getPageTitle(i));
tabToAdd.setTabListener(this);
actionBar.addTab(tabToAdd);
}
svf = servPagerAdapter.getFragment(0);
csvf = servPagerAdapter.getFragment(1);
IRCConnection testConn = new IRCConnection();
testConn.setOnIRCMessageReceivedListener(this);
//adapters are populated in a separate method
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
cadapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
Log.i("ADAPTER", adapter == null ? "Null" : "Not Null");
Log.i("FRAGMENT", svf == null ? "Null" : "Not Null");
//svf.setListAdapter(adapter);
//csvf.setListAdapter(cadapter);
/*code omitted (network call)*/
}
svf and csvf are variables I'm using to just try and test getting it to work, they are typed of a ListFragment based class that is completely cookie cutter. Eventually I want to be able to add and remove tabs from the adapter and manage the listviews in each of them.
At this stage it's probably a just an issue of me not understanding the topic/way the adapter works, and I'm hoping this is just an ignorance based question, and that there's a simple solution.
Edit: I've made some progress, but calling refresh on the visible tab is throwing a null pointer for some reason. Here's the callback from my connection class, the callback being inside the activity class:
@Override
public void onNetworkMessageReceived(String message)
{
final String msg = message;
this.runOnUiThread(new Runnable()
{
@Override
public void run()
{
FragmentData data = fragmentDataMapper.getData("Network");
ServerViewFragment visFrag = servPagerAdapter.getFragment(getActionBar().getSelectedNavigationIndex());
if (data == null)
{
ArrayList<String> chatStrings = new ArrayList<String>();
chatStrings.add(msg);
data = new FragmentData(chatStrings);
visFrag.refresh(data);
fragmentDataMapper.updateData("Network", data);
}
else
{
ArrayList<String> chatStrings = data.getChatStrings();
chatStrings.add(msg);
data = new FragmentData(chatStrings);
visFrag.refresh(data);
fragmentDataMapper.updateData("Network", data);
}
}
});
Log.i("HANDLER", message);
}
The exception is being thrown on either of the visFrag.refresh lines, as visFrag is null. I'm still using the same registeredFragments thing from before.