Navigating between ListFragment and Fragment - java

My school assignment has an activity that contains a ListFragment and a Fragment. The MainActivity creates the ListFragment, and then each item on the list should open the regular Fragment that just contains a picture, and then when I click on the picture it should go back to the ListFragment.
In all cases, I call the fragments using this code (edited for the specific case of course):
Fragment fragTwo = new FragmentTwo();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment_place, fragTwo);
ft.addToBackStack(null);
ft.commit();
It calls the fragments OK, except that the second fragment will appear OVER the ListFragment, and I can still select things from the list while the second fragment is open. Do I need to create a new fragment object every time I navigate? And how do I disable/enable a fragment from it's own onclick listener?
main_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:name="com.example.w0068332.fragmentstest.FragmentOne"
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

1- Yes you need to create a fragment for each item.
Bundle arguments = new Bundle();
arguments.putInt(FragmentTwo.ARG_ITEM_ID,R.drawable_pic);
FragmentTwo fragment = new FragmentTwo();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
I suppose that you display pictures from resources
2- To disable selection from ListFragment while displaying the second one.
In the parent layout of the second fragment you have to add background and make it clickable as below:
android:background="#color/white"
android:clickable="true"
3- To navigate back for the ListFragment add a click listener for the ImageView and onClick call onBackPressed of the Activity:
getActivity().onBackPressed();
you can also have a look on a template from Android studio for Master and details activity

Related

Programmatically adding map fragment to container adds it to the bottom

I have a contact application. A contact can have multiple addresses. When viewing a contact, a loop iterates through the database data and adds the address(es) to a container, as shown in the image. However, I don't understand why the fragments are added all the way to the bottom of the container, and not right under the respective TextView for that specific loop iteration.
Why can I not place the fragment underneath the TextView and how can I do that?
This is how I create the map fragment and add it to the container:
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MapFragment mapFragment = MapFragment.newInstance();
mapFragment.getMapAsync(onMapReadyCallback1());
fragmentTransaction.add(R.id.dynamic_layout_holder, mapFragment);
fragmentTransaction.commit();
And this is the xml container:
<LinearLayout
android:id="#+id/dynamic_layout_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>

How to set a temporary fragment to my "home screen" Android studio

I have started coding and I really like it, I have been on/off on diffrent project (to learn diffrent things) But now i got a problem, I "app"reciate all the help i can get.
I am using the navigation drawer and got three fragments installed. I can navigate through the navigation drawer and select a fragment and it loads on my screen. But when i start my app the screen is just white and the navigation drawer is on the left and i can pick a fragment. Is it possible to have a fragment on my "home screen" so when I start the app there is a fragment already placed on the screen BUT! when i chosse another fragment in the navigation drawer i would like to have my fragment who loaded at the beginning to disappear. Otherwise both fragments will show on eachother (Text on text). Maybe to have the temporary fragment to "finish" itself somehow. Please look at my imgur image to get my idea.Imgur image press here to view
Here is a generic solution on how to use the FragmentManager. It should give a good idea on how to display a Fragment. Besides that you could include a static Fragment in your layout. It's up to you how to approach it.
So the FragmentManager solution looks like this:
YourActivity.java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = AnyFragment.instantiate(this, AnyFragment.class.getName());
fragmentManager.beginTransaction().add(R.id.fragment_placeholder, fragment).addToBackStack(null).commit();
}
The target id is defined in your activity layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="#+id/fragment_placeholder"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"></FrameLayout>
</LinearLayout>
Later if you want to replace the current Fragment you can use the remove and add method of the FragmentManager (the replace method is kinda buggy).
Fragment currentFragment = fragmentManager.findFragmentById(R.id.fragment_placeholder))
fragmentManager.beginTransaction().remove(currentFragment).add(R.id.fragment_placeholder, yourNewFragment).addToBackStack(null).commit();

I want my Android Fragment to cover the MainActivity screen (I don't want to see any MainActivity text, buttons, etc.)

This seems to be such a fundamental question that I'm embarrassed to ask it, but I'm so frustrated by my Fragment learning curve that I'll expose my ignorance.
An example in a textbook that cuts a lot of corners that make expanding them difficult, if they even work, had no button to click; MainActivity simply loaded FragmentA. OK, keep it basic. I get that.
So I added a button to MainActivity to click to load FragmentA, but the button shows on the FragmentA screen, sort of like this (not an actual screen shot, but close):
How do I prevent that? Should I use a second Activity instead of a Fragment? Since this endeavor is to be utilized in a much larger project, I don't want to do anything considered not best practice. I realize that the main use of Fragment is to enable side-by-side "screens" on devices that are large enough. That's not what I want to do, but it IS possible to accomplish what I want with a Fragment, isn't it?
MainActivity.java
public class MainActivity extends Activity {
#Override protected void onCreate(Bundle savedInstanceState)
{
super.onCreate( savedInstanceState);
setContentView(R.layout.activity_main);
}
public void btnLoadFragmentAByClick(View view)
{
FragmentA fragmentA;
fragmentA = new FragmentA();
FragmentTransaction ft ;
ft = getFragmentManager().beginTransaction();
ft.replace(R.id.layout_container, fragmentA);
ft.addToBackStack("example");
ft.commit();
}
}
FragmentA.java
public class FragmentA extends Fragment
{
#Override
public View onCreateView(LayoutInflater _inflater,
ViewGroup _container,
Bundle _savedInstanceState)
{
return _inflater.inflate(R.layout.fragment_a,
_container,
false);
}
}
activity_main.xml
<RelativeLayout
xmlns:android ="http://schemas.android.com/apk/res/android"
xmlns:tools ="http://schemas.android.com/tools"
android:layout_width ="match_parent"
android:layout_height ="match_parent"
tools:context =".MainActivity" >
<LinearLayout
android:id ="#+id/layout_container"
android:orientation ="vertical"
android:layout_width ="wrap_content"
android:layout_height="wrap_content"
>
</LinearLayout>
<Button
android:id ="#+id/btnLoadFragmentA"
android:text ="Load Fragment A"
android:onClick="btnLoadFragmentAByClick"
android:layout_width ="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
fragment_a.xml
<RelativeLayout
xmlns:android ="http://schemas.android.com/apk/res/android"
android:layout_width ="match_parent"
android:layout_height ="match_parent" >
<TextView
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:text ="Layout for fragment A"
android:textAppearance ="?android:attr/textAppearanceLarge"
>
</TextView>
</RelativeLayout>
EDIT
I realize that I could hide the MainActiviy button (and any other objects) before loading FragmentA and show them after returning, but I was hoping for a one-or-two-line "fix".
How do I prevent that?
Well, to some extent, you don't, insofar as this has nothing to do with fragments.
Your activity_main.xml has the Button floating over top of the LinearLayout (???) that you are using for your fragment container. If you do not want the Button floating over top of the fragment container, then fix the layout file to not have the Button floating over top of the fragment container.
I realize that I could hide the MainActiviy button (and any other objects) before loading FragmentA and show them after returning, but I was hoping for a one-or-two-line "fix".
The typical solution for full-UI replacement using fragments is to have everything in fragments. Your replace() would replace your original fragment with a replacement. So, in this case, your Button would be managed by one fragment, and clicking the Button would replace() that fragment with another fragment. Given that your FragmentTransaction has addToBackStack(), pressing BACK would get rid of the replacement fragment and return you to your Button fragment.

Changing fragments with FragmentTransaction not working?

When the user clicks an element in a ListView in one fragment, the listener is notified through an interface and it should change the fragment next to the menu.
My current code looks like this
Fragment f = null;
switch(fragmentId) {
case 0:
f = new xFragment();
break;
case 1:
f = new yFragment();
break;
...
}
System.out.println(f.getClass().getName()); // Prints the name of the class correctly
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragmentContainer, f);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.commit();
When I select some option from the menu, this function in the activity that contains the fragment is called. It correctly prints the fragmentId and the name of the class is correct as told in the code sample.
However, the fragment isn't changed. I tried to replace the f variable in the replace method by new xFragment() but it didn't help.
The XML layout file looks this.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<fragment
android:id="#+id/menuFragment"
android:layout_width="300dp"
android:layout_height="match_parent"
android:name="fi.peltoset.mikko.home.Navigation" />
<LinearLayout
android:id="#+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
The LinearLayout fragmentContainer is the container for the fragments.
At startup I use the same code I showed above except I changed replace to add to add the right fragment when the application starts. This works fine.
What's wrong?
Are you attempting to replace the fragment whose ID is 'menuFragment'? If so then you cannot do this as any fragment specified in the XML layout cannot be replaced.
Can you try to replace the LinearLayout by FrameLayout?
please refer to https://groups.google.com/forum/#!topic/android-developers/gAhaoLlBob4 even though nobody explain why.
What version of Android are you targeting?
Try using the support fragment manager:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
http://developer.android.com/reference/android/support/v4/app/FragmentActivity.html#getSupportFragmentManager()
First of all, "fragmentContainer" is not a fragment itself. Also, you can't replace static fragments with each other. They must be "dynamically added" fragments. Take a look at this post
To replace dynamically created fragments, take a look at this post.

Add fragments before main activity shows main content view

Splash
I have main activity UI startup operations that take between 5-10 seconds (that need to be handled on the main UI thread) - so I would like to use a splash screen rather than the default black or non-responsive main UI.
A good solution to the splash screen is provided below
which is to first set setContentView(R.layout.splash),
then do the necessary main UI processing (on UI thread but with main view that is not visible)
and when that is ready show setContentView(R.layout.main)
Android Splash Screen before black screen
Splash with Fragments
I'm also using fragments, which normally require setContentView(R.layout.main) to be called before fragment instantiation - so that the fragment manager could find the view stubs in R.layout.main to inflate the fragments into (strictly speaking view stubs are a different thing).
But I cannot call setContentView(R.layout.main) before creating the fragments, because that replaces the splash screen with the (not-yet-ready) main screen.
My fear is that what I want to do cannot be done?
Unfortunately, there is no overload like fragmentTransaction.add(viewNotViewId, fragment);
Almost-Answer
Here's all but the key, which is that setContentView is called before the fragment transactions:
How do I add a Fragment to an Activity with a programmatically created content view
You could try replacing your fragments in your FragmentActivity, here is the idea partially coded:
Suppose you have your fragments layout like this (main.xml):
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal">
<LinearLayout android:id="#+id/waiting" ...>
</LinearLayout>
<!-- hidden layout -->
<LinearLayout>
<LinearLayout android:id="#+id/layout_list_items" ...>
</LinearLayout>
<LinearLayout android:id="#+id/layout_detail" ...>
</LinearLayout>
</LinearLayout>
</LinearLayout>
And your FragmentActivity like this:
public class FragmentsActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
Fragment fragA = new WaitingTransaction();
FragmentTransaction fragTrans = this.getSupportFragmentManager().beginTransaction();
fragTrans.add(R.main.waiting, fragA);
fragTrans.commit();
}
private void afterProcessing(){
//show hidden layout and make the waiting hidden through visibility, then add the fragment bellow...
FragmentTransaction fragTrans = this.getSupportFragmentManager().beginTransaction();
fragTrans.add(R.main.layout_list_items,
new FragmentList());
fragTrans.replace(R.main.layout_detail,
new FragmentB());
fragTrans.commit();
}
}
Try this code without calling any setContentView
fragmentTransaction.add(android.R.id.content, Fragment.instantiate(MainActivity.this, SplashFragment.class.getName()));
The main approach here is placing fragment in view with id android.R.id.content which is always present before any layout is inflated via setContentView

Categories