I'm new to Android programming and am trying to figure out how to go about this. I have a fragment that hosts inner tabs, one of them being a ListFragment. On the tabhost fragment I have a button that calls a DialogFragment. When "Yes" is clicked on that DialogFragment I need to refresh that ListFragment if it's currently active in order to show the item added onto the list.
What is the best way to go about this? I am thinking I should put an interface on the DialogFragment and then implement the listener on the Activity which would then call the refresh in the ListFragment. I would need to be able to pull the ListFragment's tag in order to determine if it's active, however and not sure how to do that.
I just started to learn programming a few months ago and this is my first post on this site. I searched for this answer and couldn't find anything. I apologize if my methods or formatting are wrong. Any tips are appreciated, thanks.
TabFragment:
public class Items extends Fragment implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener, View.OnClickListener {
MyPageAdapter pageAdapter;
private ViewPager mViewPager;
private TabHost mTabHost;
static final String ARG_ID = "id";
static final String name = "name";
long id;
String itemName;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.tab_test);
Bundle args = getArguments();
long id = args.getLong(ARG_ID);
String itemName = args.getString(name);
View v = inflater.inflate(R.layout.item_tab, container, false);
mViewPager = (ViewPager) v.findViewById(R.id.pager);
// Tab Initialization
//initialiseTabHost
mTabHost = (TabHost) v.findViewById(android.R.id.tabhost);
mTabHost.setup();
// TODO Put here your Tabs
List<Fragment> fragments = getFragments();
FragmentActivity context = getActivity();
this.AddTab(context, this.mTabHost, this.mTabHost.newTabSpec("ItemList").setIndicator("ItemList"));
mTabHost.setOnTabChangedListener(this);
// Fragments and ViewPager Initialization
pageAdapter = new MyPageAdapter(getChildFragmentManager(), fragments);
mViewPager.setAdapter(pageAdapter);
mViewPager.setOnPageChangeListener(this);
if (savedInstanceState == null) {
}else {
int pos = savedInstanceState.getInt("tab");
mTabHost.setCurrentTab(pos);
}
Button addItemButton = (Button) v.findViewById(R.id.addItem);
addItemButton.setOnClickListener(this);
return v;
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.addItem:
DialogFragment addItem = new AddItemDialogFragment();
Bundle itemArgs = getArguments();
addItem.setArguments(itemArgs);
addItem.show(getChildFragmentManager(), "addItem");
Toast.makeText(getActivity(), "Adding Item", Toast.LENGTH_LONG).show();
break;
}
}
// Method to add a TabHost
private static void AddTab(FragmentActivity activity, TabHost tabHost, FragmentTabHost.TabSpec tabSpec) {
tabSpec.setContent(new MyTabFactory(activity));
tabHost.addTab(tabSpec);
}
// Manages the Tab changes, synchronizing it with Pages
public void onTabChanged(String tag) {
int pos = this.mTabHost.getCurrentTab();
this.mViewPager.setCurrentItem(pos);
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
// Manages the Page changes, synchronizing it with Tabs
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
int pos = this.mViewPager.getCurrentItem();
this.mTabHost.setCurrentTab(pos);
}
@Override
public void onPageSelected(int arg0) {
}
private List<Fragment> getFragments(){
List<Fragment> fList = new ArrayList<Fragment>();
// TODO Put here your Fragments
Bundle args = getArguments();
long id = args.getLong("val");
ItemList f1 = ItemList.newinstance(id);
fList.add(f1);
return fList;
}
public class MyPageAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments;
public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
}
}
ListFragment within Tab:
public class ItemList extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
String DATABASE_TABLE;
String Query;
String Order;
String name;
MainActivity home;
View view;
public static MyListAdapter mAdapter;
private static Cursor c;
static ItemList newinstance(long rowId) {
ItemList itemList = new ItemList();
// Supply val input as an argument.
Bundle args = new Bundle();
args.putLong("val", rowId);
//args.putString("name", itemName);
itemList.setArguments(args);
return itemList;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle args = getArguments();
int itemId= (int) args.getLong("val");
mAdapter = new MyListAdapter(getActivity(), R.layout.list_row, c, from, to);
setListAdapter(mAdapter);
setListShown(false);
getLoaderManager().initLoader(itemId, null, this);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// View progressBar = getView().findViewById(R.id.progressbar_loading);
// progressBar.setVisibility(View.VISIBLE);
return new RawCursorLoader(getActivity(), Query + Order);
}
// Called when a previously created loader has finished loading
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
//View progressBar = getView().findViewById(R.id.progressbar_loading);
// progressBar.setVisibility(View.GONE);
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
mAdapter.swapCursor(data);
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
// Called when a previously created loader is reset, making the data unavailable
public void onLoaderReset(Loader<Cursor> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
mAdapter.swapCursor(null);
}
}
Dialog:
public class AddItemDialogFragment extends DialogFragment {
UpdateItemListener mListener;
public interface UpdateItemsListener {
public void onItemAdded();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mListener = (UpdateItemListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement UpdateItemListener");
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Add " + itemName + "?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
postItem(ItemId);
mListener.onItemAdded();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
// Create the AlertDialog object and return it
return builder.create();
}
}
I was able to figure it out, my brain just got stuck for a while.
The first problem was that I was using FragmentStatePagerAdapter which does not set tags when instantiating the fragments. I set it to this since FragmentPagerAdapter was being buggy and another thread recommending extending that class instead. I was able to get it working with FragmentPagerAdapter which sets a tag. I then call getTag() during the onAttach() method of the ItemList fragment and set the variable on the activity. I then have an interface on the AddItemDialogFragment when the item is added and a listener on the activity. The listener then calls:
ItemList itemList= (ItemList)
getSupportFragmentManager().findFragmentByTag("Items")
.getChildFragmentManager().findFragmentByTag("itemListTag");
if(itemList != null) {
itemList.listChange();
}