I have a problem using fragments.
First of all some basic Informations. I'm using an Actionbar
(support.v4) with 3 Tabs / Fragments. The first two fragments cause problems. First fragments extends ListFragment, Second extends Fragment. Both has a ListView
and one ArrayAdapter
(different ArrayAdapters).
My Fragments:
In both Fragments I create a
ContextMenu
(different menus / menuitems):In both Fragments I override
onCreateContextMenu(..)
andonContextItemSelected(..)
.My Adapters:
Both Adapters override the getView method.
My Problems:
If I select a
ContextItem
of fragment 2, theonContextItemSelected
Method of frament 1 is called.If I update fragment 2, also getView of fragment 1 is called.
With your help and StackOverflow I already find out, that if one fragment is active the two fragments directly next to it are already active. So if both fragments have the same overridable method the first will be chosen. Problem is, I didnt find a Solution ;-)
Is anyone here, who understand my problem and / or has ever dealing with that, too?
EDIT: Source Code
public class ActionBarActivity extends FragmentActivity implements
ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.actionbarlayout);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
android.support.v4.app.FragmentManager fm = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
android.support.v4.app.Fragment myFirstFragment = (Fragment) new Fragment_ONE();
android.support.v4.app.Fragment mySecondFragment = (Fragment) new Fragment_TWO();
android.support.v4.app.Fragment myThirdFragment = (Fragment) new Fragment_THREE();
ft.add(R.id.pager, myFirstFragment, "FIRSTFRAGTAG");
ft.add(R.id.pager, mySecondFragment, "SECONDFRAGTAG");
ft.add(R.id.pager, myThirdFragment, "THIRDFRAGTAG");
ft.commit();
fm.executePendingTransactions();
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
Fragment myFirstFragment = new Fragment_ONE();
return myFirstFragment;
case 1:
Fragment mySecondFragment = new Fragment_TWO();
return mySecondFragment;
case 2:
Fragment myThirdFragment = new Fragment_THREE();
return myThirdFragment;
default:
Fragment defaultFragment = new Fragment_ONE();
return defaultFragment;
}
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
@Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
}
public class FirstAdapter extends ArrayAdapter<xxx> {
public BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//SOME CODE
}
};
public FirstAdapter(Context context, ArrayList<xxx> items) {
super(context, 0, items);
// SOME CODE
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// SOME CODE: codeONE
return convertView;
}
}
public class SecondAdapter extends ArrayAdapter<xxx> {
public BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//SOME CODE
}
};
public SecondAdapter(Context context, ArrayList<xxx> items) {
super(context, 0, items);
// SOME CODE
}
public class Fragment_ONE extends ListFragment{
public Fragment_ONE() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.firstfragment, container, false);
setRetainInstance(true);
return rootView;
}
@Override
public void onActivityCreated (Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mFirstListView =(ListView) getView().findViewById(android.R.id.list);
registerForContextMenu(mFirstListView);
mFirstAdapter = new FirstAdapter(myInstance, mItemsONE);
mFirstListView.setAdapter(mFirstAdapter);
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
if (v.getId() == android.R.id.list) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
menu.setHeaderTitle("CONTEXTMENU");
menu.add(FIRST_FRAGMENT_GROUP_ID, 0, 0, "1");
menu.add(FIRST_FRAGMENT_GROUP_ID, 1, 1, "2");
menu.add(FIRST_FRAGMENT_GROUP_ID, 2, 2, "3");
menu.add(FIRST_FRAGMENT_GROUP_ID, 3, 3, "4");
menu.add(FIRST_FRAGMENT_GROUP_ID, 4, 4, "5");
menu.add(FIRST_FRAGMENT_GROUP_ID, 5, 5, "6");
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
if (item.getGroupId()==FIRST_FRAGMENT_GROUP_ID){
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
.getMenuInfo();
int ListItemIndex = info.position;
Intent broadcast = new Intent(UPDATEREQUEST);
broadcast.putExtra(UPDATEREQUESTEXTRA, 1);
ActionBarActivity.getMyInstance().getApplicationContext().sendBroadcast(broadcast);
return true;
}
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
}
}
public class Fragment_TWO extends Fragment {
public Fragment_TWO() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.secondfragment, container, false);
setRetainInstance(true);
return rootView;
}
@Override
public void onActivityCreated (Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mySecondListView = (ListView) getView().findViewById(R.id.secondListView);
mySecondAdapter = new SecondAdapter(myInstance, myItemsTWO);
mySecondListView.setAdapter(mySecondAdapter);
registerForContextMenu(mySecondListView);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
menu.setHeaderTitle("Options");
menu.add(SECOND_FRAGMENT_GROUP_ID, 1, 1, "1");
menu.add(SECOND_FRAGMENT_GROUP_ID, 2, 2, "2");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
super.onContextItemSelected(item);
// SOME CODE
Intent broadcast = new Intent(UPDATEREQUEST);
broadcast.putExtra(UPDATEREQUESTEXTRA, 1);
ActionBarActivity.getMyInstance().getApplicationContext().sendBroadcast(broadcast);
return true;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// SOME CODE: codeTWO
return convertView;
}
}
Android FragmentManager handles overrides for contextMenuItem selection by iterating through all the Fragments, so each of your Fragments that handles context menu clicks needs to have logic for whether it handles the call or if the call should be passed to the next Fragment.
See this answer: Wrong fragment in ViewPager receives onContextItemSelected call