I'm running into issues opening a fragment from another fragment. My Main Activity implements the newest Nav Drawer and each of the options in the Nav Bar list opens a new fragment. That much is implemented and working well. The problem I have is with the next layer of fragments. I have an Event Fragment with an imageButton. When this is clicked I need to navigate to a new fragment for this sub event. I tried creating an onclicklistener in the Event Fragment the opened the sub event page but i get the following error.
No view found for id 0x7f08000a (com.ikimuhendis.ldrawer.sample:id/imagefrag) for fragment imageFragment1 {348db088 #0 id=0x7f08000a}
public class EventFragment extends Fragment
{
ImageButton test;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_event, container, false);
SliderLayout sliderShow = (SliderLayout) rootView.findViewById(R.id.slider);
sliderShow.setDuration(8000);
sliderShow.setPresetTransformer(SliderLayout.Transformer.ZoomOut);
//get the button view
test = (ImageButton) rootView.findViewById(R.id.imageButton);
test.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Fragment videoFragment = new imageFragment1();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.imagefrag, videoFragment)
.commit();
}
});
HashMap<String, Integer> file_maps = new HashMap<String, Integer>();
file_maps.put("Munster Vs Leinster", R.drawable.rugby);
file_maps.put("Ennio Morricone", R.drawable.ennio);
file_maps.put("Leinster Vs Harlequins", R.drawable.heino);
file_maps.put("WWE Live", R.drawable.wwe);
for (
String name
: file_maps.keySet())
{
TextSliderView textSliderView = new TextSliderView(getActivity());
textSliderView
.description(name)
.image(file_maps.get(name));
sliderShow.addSlider(textSliderView);
}
getActivity().setTitle("Events");
return rootView;
}
}
The code above is meant to open this image fragment
public class imageFragment1 extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.imagefragment1, container, false);
return rootView;
}
}
imageFragment1 xml code
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:id="@id/imagefrag" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="This is a test"
android:id="@+id/textView"
android:layout_marginTop="41dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
How to replace the activity's fragment from the fragment itself?
I'm pretty unsure about where the fragment transaction should take place. In my main activity the fragment transaction takes place in a switch block for the navigation drawer. I've read that "Please note that fragment should NOT directly replace itself or any other fragments. Fragments should be separate entities. What fragment should do is to notify its parent activity that some event has happened. But it is, again, NOT a fragment job to decide what to do with that! It should be activity to decide to i.e. replace the fragment on phone, but to i.e. add another to existing one on tablets. So you are basically doing something wrong by design"
Another poster mentions "A better way to handle this situation is by creating a callback implementation for the main activity to handle requests such as start a new fragment" How do i set this up in my main activity so that it communicates to the sub fragments of my drawer fragments. Any thoughts on this much appreciated.
Main Activity
public class SampleActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerArrowDrawable drawerArrow;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
CustomDrawerAdapter adapter;
List<DrawerItem> dataList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
ActionBar ab = getActionBar();
ab.setDisplayHomeAsUpEnabled(true);
ab.setHomeButtonEnabled(true);
dataList = new ArrayList<DrawerItem>();
dataList.add(new DrawerItem("Home", R.drawable.home));
dataList.add(new DrawerItem("How It Works", R.drawable.howitworks));
dataList.add(new DrawerItem("Events", R.drawable.events));
dataList.add(new DrawerItem("Profile", R.drawable.signin));
mTitle = mDrawerTitle = getTitle();
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.navdrawer);
drawerArrow = new DrawerArrowDrawable(this)
{
@Override
public boolean isLayoutRtl() {
return false;
}
};
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
drawerArrow, R.string.drawer_open,R.string.drawer_close)
{
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
adapter = new CustomDrawerAdapter(this, R.layout.custom_drawer_item,
dataList);
/* ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, mNames); */
mDrawerList.setAdapter(adapter);
mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
{
displayView(position);
// Running Fragment Transaction code here
}
}
// Method that updates content frame with different fragments
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
Bundle args = new Bundle();
switch (position) {
case 0:
fragment = new TitleFragment();
mDrawerToggle.setAnimateEnabled(true);
drawerArrow.setProgress(1f);
mDrawerToggle.syncState();
break;
case 1:
fragment = new HowFragment();
mDrawerToggle.setAnimateEnabled(true);
drawerArrow.setProgress(1f);
mDrawerToggle.syncState();
break;
case 2:
fragment = new EventFragment();
mDrawerToggle.setAnimateEnabled(true);
drawerArrow.setProgress(1f);
mDrawerToggle.syncState();
break;
case 3:
fragment = new ProfileFragment();
mDrawerToggle.setAnimateEnabled(true);
drawerArrow.setProgress(1f);
mDrawerToggle.syncState();
break;
}
fragment.setArguments(args);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment).addToBackStack(null).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(dataList.get(position).getItemName());
mDrawerLayout.closeDrawer(mDrawerList);
}
});
}
@Override
public void setTitle(CharSequence title)
{
mTitle = title;
getActionBar().setTitle(mTitle);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item))
{
return true;
}
return false;
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
}