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>
Related
I'm struggling with something really simple. ( or at least this was my idea.. )
I would need to put a simple button on top of a map inside a viewpager.
Actually I'm creating the supportmapfragment programmatically and adding it to the crated viewpager adapter .
ViewPagerAdapter adapter = new ViewPagerAdapter
(getSupportFragmentManager());
mapFrag = new SupportMapFragment();
mapFrag.getMapAsync(this);
adapter.addFragment(mapFrag, getString(R.string.maptab));
now... to put a button on top I would need the view from supportmapfragment so I can push up "my button_" via addview.
I cannot understand how to retrieve the view without extending the class for supportmapfragment but this would need me to create a custom supportmapfragment class.
any idea?
after suggestion: I made a test with a relative layout :
<fragment
android:id="#+id/rlMap"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</fragment>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Button 1"/>
this make button appear for a second (before map load) then being uncovered by map . even putting button inside the fragment sort same effect
Even if you try and put the button over the fragment's view, you will still need to set a click listener and do some logic when it's pressed. I think that would make the existing code a bit messy, passing a responsibility of the fragment (registering the button click listener) to the activity.
What I would do if I were you would be create a new Fragment with some ConstraintLayout that contains the underlying map and the button (but does not extend SupportMapFragment). It would be a wrapper fragment where you can also handle the button with its events, and whatever would be needed more.
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();
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
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.
Im adding another Fragment to the screen. This screen already has en MapView in a SupportMapFragment so the added Fragment should be on top of the MapView. This new view cover like 2/3 of the screen and a big part of the Map but when I scroll on the View it scrolls the MapView underneath. This is not what i expected because the new View is added on top of the MapView. The new view exist of a relative layout containing a ImageView which wraps it contents. So when scrolling on the imageview (which has totally no functionality) it scrolls the MapView. Can anyone explain why this happens and if possible, provide me with a solution?
EDIT:
basically i have a MapView which fills the whole screen. This code sets up my mapview:
public void setUpMapIfNeeded(int satelliteMode, LatLng startPoint, float zoomLevel) {
// Do a null check to confirm that we have not already instantiated the map.
if (mapView == null) {
// Try to obtain the map from the SupportMapFragment.
mapView = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapview))
.getMap();
// Check if we were successful in obtaining the map.
if (mapView != null) {
setUpMap(satelliteMode, startPoint, zoomLevel);
}
}
}
private void setUpMap(int satelliteMode, LatLng startPoint, float zoomLevel) {
// more settings
}
Then when a user clicks a marker a fragment must be shown on top of the mapview.
public void createDetailView() {
detailView = new DetailViewFragment();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.viewLayout, detailView).commit();
fragmentManager.executePendingTransactions();
}
This all works fine. The view is shown (which is about 2/3 of the whole screen) but user can scroll the map when swiping the detailview. The detailview consist of a relative layout with a lot of text and buttons:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginTop="45sp">
<!-- a lot of text and buttons here -->
</RelativeLayout>
So I still havent found a proper way to deal with this. Instead I just disabled all touches and clicks on the mapview when another view is on top of the mapview which btw works ok.
Just in case it might still be relevant, the way I've handled this kinds of layouts (one view appearing "on top of" another) is to use LinearLayout instead of a RelativeLayout in the following way:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<SomeView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<PopOutView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:visibility="gone" />
</LinearLayout>
In your case the map would be that SomeView and the relative layout the PopOutView. Then in the code you would just call popOutView.setVisibility = View.VISIBLE whenever you would like it to show up. It shrinks the first view instead of being drawn on top (thus having a bit different visual effect) but at least this way the touch events should go to the right view.
Set the fragment's layout clickable property to true. It will stop the touch events from propagating down.
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFF"
android:clickable="true">
</FrameLayout>