I have a flexible UI layout. One fragment in handheld devices and 2 fragments in a tablet. In the Details Fragment, this will contain a youtube video and some other views. I am using Youtube API to do this.
I have tried using YoutubePlayerSupportFragment defined in the xml file and it works fine on first load. But when going back to the List view and then reopening the details view, I get a duplicate ID error. This is because the onCreateView for the DetailsFragment is loading the layout again.
I tried to replace this with FrameLayout and dynamically add the YoutubeFragment which solved the problem above. However, when changing orientation, it reloads the entire fragment and the youtube video is restarted from the beginning.
What I want is to have the youtube video inside the fragment and handle screen changes (like orientation or fullscreen mode) without the video rebuffering. There was a sample app provided in android developer page to accomplish this but they are using YoutubePlayerView in the XML file which requires the container to be an activity inheriting from YoutubeBaseActivity which doesn't work in my situation since I'm using a Fragment. What is the proper way of implementing this?
DetailFragment.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView .. />
<fragment
android:id="#+id/youtube_fragment"
android:name="com.google.android.youtube.player.YouTubePlayerSupportFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button ... />
</LinearLayout>
DetailFragment.java
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater
.inflate(R.layout.DetailFragment, container, false);
...
YouTubePlayerSupportFragment youTubeView = (YouTubePlayerSupportFragment) getActivity()
.getSupportFragmentManager().findFragmentById(
R.id.youtube_fragment);
youTubeView.initialize(Utilities.DEVELOPER_KEY, this);
return view;
}
Related
I am using Google Maps in fragment using Google Support Map Fragment to replace the parent fragment container with the Maps. Below is my code..
In my Fragment Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.--.--.--.fragments.LocationFragment">
<FrameLayout
android:id="#+id/locationFragMapContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
and then in my Fragment OnCreateView()
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_location,container,false);
/**
* Get the Child fragment and replace it in the parent fragment container
*/
mSupportMapFragment = CustomChildMapFragment.newInstance();
getChildFragmentManager().beginTransaction().replace(R.id.locationFragMapContainer,mSupportMapFragment).commit();
return view;
}
One Solution to change location button from top to bottom can be found here but I want to change the location button to the left bottom just above the Google Icon on the Maps.
// Align it to - parent BOTTOM|LEFT
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
I got the above solution from Github GIST but it doesn't seem to work out.
Is Google trying to enforce to stop bad people from overriding their Brand Logo ? Or am I doing something wrong here ?
I have no intention to override or replace Google Logo it is just the requirement that I have. I will be keeping the button above the Logo complying to guidelines
I am attempting to replace a nested fragment inside a tabLayout fragment.
My app structure follows this pattern.
Here is the XML for the Tab Fragment 2
<FrameLayout
android:id="#+id/scene_root"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".Home"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<FrameLayout
android:id="#+id/shows_fragment_list"
android:tag="list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/shows_fragment_details"
android:tag="details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/shows_fragment_info"
android:tag="info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
I am using this code to add the NestedFragment to the TabFragment FrameLayout
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View root = inflater.inflate(R.layout.shows_fragment_layout, container, false);
ShowDetailsFragment newNestedFragment = new ShowDetailsFragment();
android.support.v4.app.FragmentManager fragmentManager = getChildFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction
.add(R.id.show_fragment_details, newNestedFragment)
.addToBackStack("null")
.commit();
return root;
}
But when I add the Nested Fragment to the Tab Fragment, only the last part of my layout appears, in this case it is a list view (highlighted in red), but it always seems to be the which ever element is declared last when the layout is inflated by the corresponding Java file.
When I inflate these layouts as there own activity, there are no inflation problems, so it must relate to my implementation of fragments, any ideas where I am going wrong?
A good idea is always to use the Android Device Monitor to debug your layout.
I would also add some logging on the onCreateView of your fragments.
Ok so my problem was that in my XML layout for my ShowDetailsFragment (The Nested Fragment) I had a FrameLayout as the root, but there were two separate RelativeLayouts as children, meaning only the last element was being displayed, the problem was solved by nesting these two Relative Layouts in another single Relative Layout.
Props go to ctarabusi for pointing me in the right direction, although I am still unsure why this only caused a problem when inflating as a Fragment and not as an Activity.
I have the following parent layout for an activity:
<?xml version="1.0" encoding="utf-8"?> <ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
I also have the following layout for a Fragment that goes into that ViewPager:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<FrameLayout
android:id="#+id/mapLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</RelativeLayout>
</LinearLayout>
At runtime the FrameLayout gets populated on the onCreateView() method of the Fragment like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
ViewGroup MapView = (ViewGroup) inflater.inflate(R.layout.frament_mood_map, container, false);
if(savedInstanceState == null) {
Fragment mapFragment = new SupportMapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
//Adding map fragment to the FrameLayout.
transaction.add(R.id.mapLayout, mapFragment, "map").commit();
}
//Adding the mood panel.
ViewGroup mapLayout = (ViewGroup) MapView.findViewById(R.id.mapLayout);
mapLayout.addView(inflater.inflate(R.layout.mood_panel_layout, null));
...
return MapView;
}
The expected behavior is that since the container that gets populated by the Fragment and the View is a FrameLayout, the former gets added first to the container, and then the later would be on top of the map, I want to show a map with a little panel on top which has buttons, I cannot define the Fragment inside the XML because (citing the docs, and yes I've tried to do it):
Note: You cannot inflate a layout into a fragment when that layout
includes a . Nested fragments are only supported when added
to a fragment dynamically
What am I doing wrong? how can I workaround this?
After hours of fiddling and trying to find a workaround I found out that there's a updated MapView on Google Maps Android API v2, so for those having the same issue where you need to nest within a ViewPager page fragment a MapFragment just use the MapView.
I found about MapView in the following SO question: Should I use MapView or MapFragment
I can't get my ViewPager not clipping its pages contents.
I'm currently using ViewPager with a FragmentStatePagerAdapter in my application. I have 3 pages, each page is showing a different fragment.
Everything works fine, but now I want to be able to draw outside of my pages bounds, like in this image:
I set clipChildren and clipToPadding to false in my all views parents to the views that needs to draw outside their bounds, but here's what I get : my views get clipped according to pages bounds.
Some additional info : In order to fix that issue, I used hierarchyviewer to check my view hierarchy and see if some "under the hood" views could have a clipping behaviour. And bingo : each of my fragments' root views is added under a NoSaveStateFrameLayout. I suspect this guy to clip its children...
Is my last assumption correct in your opinion? How would you do to get unclipped pages?
There are a few different Views that require disabled clipping. First, the FrameLayout that is at the root of the ViewPager needs to have clipping disabled. You can do this wherever you initialize your view pager. You also need to set the off-screen page limit to 2 to allow for an extra fragment to be loaded during a swipe. Without this, you'll see a pop going from 1->2 as 3 loads and adds it's overflow content to 2 once 2 has finished loading (this loads both 2 and 3 ahead of time).
mViewPager.setClipChildren(false);
mViewPager.setClipToPadding(false);
mViewPager.setOffscreenPageLimit(2);
Second, the XML you inflate in your FragmentStatePagerAdapter needs to include the appropriate tags or it can be done programmatically. Last, you need to force the NoSaveStateFrameLayout to not clip as well. This can be done after the view has been created in onViewCreated. Here's an example fragment:
public static class PlaceholderFragment extends Fragment {
public static PlaceholderFragment newInstance() {
PlaceholderFragment fragment = new PlaceholderFragment();
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout rootView = (LinearLayout) inflater.inflate(R.layout.fragment_main, container, false);
//This can be done in XML
rootView.setClipChildren(false);
rootView.setClipToPadding(false);
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//This is the NoSaveStateFrameLayout - force it to not clip
FrameLayout frameLayout = (FrameLayout) getView();
frameLayout.setClipChildren(false);
frameLayout.setClipToPadding(false);
}
}
I have tested this solution and am certain it works.
Full activity example:
https://gist.github.com/grantamos/d664f01a30f9ad97ba53
I had the same problem. I fixed this by adding
android:clipChildren="false"
android:clipToPadding="false"
to ViewPager and ViewGroup which is parent of ViewPager
For instance, if you have a layout like that:
<?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">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:clipChildren="false"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:clipChildren="false"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</FrameLayout>
</RelativeLayout>
then only LinearLayout and ViewPager should have
android:clipChildren="false"
android:clipToPadding="false"
Have you tried to use a negative value for the margin between pages (using ViewPager.setPageMargin(int))? You will also have to set offscreen page limit to at least 2 (using ViewPager.setOffscreenPageLimit(int)).
Try this:
#Override
public float getPageWidth(int position) {
return 0.80f;
}
This is working for me perfectly
1. (Parent Layouts).setClipChildren(false);
(Parent Layouts).setClipToPadding(false);
2. `mViewPager.setPagerMargin(dp)`
3. `mViewPager.setOffscreenPageLimit(numberOfPage);`
I am using actionbarsherlock library to have action-bar in my application,
I am also using view-pager to switch between the page,
Now the problem is i want only one tab with two fragment to display data regarding each other.
What could be the possible way to do this?
I have been going through like the one below but unsuccessful
In main fragment i am inflating a xml like this
<code>
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View fragView = inflater.inflate(R.layout.album_view_main, container, false);
return fragView;
}
</code>
xml fie is look like this
<code>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<fragment
android:id="#+id/fragment_album_view"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_weight="3"
class="com.nix.music.activity.fragments.AlbumFragMent" />
<FrameLayout
android:id="#+id/frame_list_song"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_weight="2" >
</FrameLayout>
</LinearLayout>
</code>
but the problem is i cannot find "frame_list_song" in AlbumFragment class it appears null
what could be the way around ?
thank you
This layout should be set in the parent activity using setContentView(). Then, you would be able to do something like getActivity().findViewById(R.id.frame_list_song) from your AlbumFragment. The better way would be to use an interface and transfer control to the main activity, and not access other fragments directly.