Cannot Access Views inside Included layout - android

I am using an "include" layout that is part of a fragment. Here is where I inflate the layout that includes the "include" (and below it is the layout itself):
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.hourly_fragment, null);
return v;
}
hourly_fragment.xml
<include
android:id="#+id/visualization"
style="#style/Visualization"
android:layout_width="match_parent"
layout="#layout/visualization_with_spinner" />
<include
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="#layout/list_fragment" />
<include
android:id="#+id/hourly_amazon_details"
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="#layout/amazon_details" />
I can access the items in the other 2 included layouts, but not from the "amazon_details" layout....any ideas why?

Since a Project > Clean did not solve your problem, try setting the parent to the container currently visible in your Content View:
(As you posted in your comment response:)
inflater.inflate(R.layout.hourly_fragment, container, false);

I'm an idiot! I totally overlooked a layout in the layout-large and I am testing on a tablet. Now the views are not null, I just have to figure how to get it to show under the list. I apologize if I wasted anyone's time...my bad and thanks for all the efforts!

Related

java.lang.IllegalStateException: RecyclerView has no LayoutManager in Fragment

I was in the process of changing an Activity into a Fragment and got the following error as soon as I inflated the RecyclerView.
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
----> View rootView = inflater.inflate(R.layout.layout_containing_recyclerview,
container, false);
java.lang.IllegalStateException: RecyclerView has no LayoutManager
Before I changed my Activity to a Fragment the inflate went just fine.
Some further research showed that removing all my child elements from the recyclerview layout helped solve the problem. However I do not understand why that would change anything and why it did work work with an activity before.
WORKS
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:scrollbars="vertical" >
</android.support.v7.widget.RecyclerView>
DOES NOT WORK
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:scrollbars="vertical" >
<View
android:id="#+id/randomview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</android.support.v7.widget.RecyclerView>
Anything I am missing here?
This question is quite old but for the benefit of people still facing this issue I thought I would leave an answer. I am just learning Android development and this issue was frustrating. Later on I found out that you are not supposed to add any views or view groups under RecyclerView. The layout that you want to appear under the RecyclerView needs to be defined separately in an independent resource file.
Then in the adapter implementation (the one that extends RecyclerView.Adapter<>, in the overridden method public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) when you inflate the layout for the view (this is inflating the layout for each item of the recycler view), you can specify the above separate layout that you created. Android then inflates this layout for every item that needs to be added to the recycler view.
This article helped me see this clearly.
RecyclerView is a ViewGroup that requires LayoutManager that will do the layouting of its children. In your case RecyclerView needs the child view to be passed to the LayoutManager, but I'm not sure if it is possible to pass xml reference of View to LayoutManager.
I had same issue when I tried to use android-parallax-recycleview.
The solution was simple, you can create the layout manager manager manually.
Code snippet from example-parallaxrecycler:
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setOrientation(LinearLayoutManager.VERTICAL);
myRecycler.setLayoutManager(manager);
I ended up just inflating the views afterwards like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_catalog_viewer, container, false);
recyclerView = (RecyclerView)rootView.findViewById(R.id.my_recycler_view);
getLayoutInflater(savedInstanceState).inflate(R.layout.catalog_child, container);
return rootView;
}
Still null pointer exception even if I initialize it in onCreateView.
Add it programatically.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- <android.support.v7.widget.RecyclerView
android:id="#+id/rvPromotions"
android:layout_width="match_parent"
android:layout_height="match_parent" /> -->
</LinearLayout>
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
// create recyclerview
...
LinearLayout llContainer = (LinearLayout) v.findViewById(R.id.llContainer);
llContainer.addView(recyclerView);
return v;
}

Custom ListView in ListFragment or Fragment?

I am working on a simple app, so that the main activity has two fragments that user can swipe to go to. On one of them, I want to have custom list. For example, something like this https://github.com/JakeWharton/SwipeToDismissNOA, where each item in the list can be deleted by swiping. I was able to get a regular list to work inside the ListFragment, but can't get this custom list to work. As I understand, ListFragment needs to have a simple .xml with one , but the one that I want to use, has a bit more stuff in it. Something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:baselineAligned="false"
android:padding="16dp">
<LinearLayout android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:orientation="vertical">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:listSeparatorTextViewStyle"
android:text="ListView" />
<ListView
android:id="#android:id/list"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>
So when I am trying to getListView() using this .xml, it either returns null or when I am trying to do something like this:
View view = inflater.inflate(R.layout.fragment_section_dummy, null);
ListView ls = (ListView) view.findViewById(android.R.id.list);
It throws this error:
10-15 20:25:28.895: E/AndroidRuntime(8081):
java.lang.UnsupportedOperationException: addView(View, LayoutParams) is not supported in AdapterView.
Thanks.
For me, is easiest work with my own IDs, so I would change your ListView ID to another one. For my example, I choose android:id="#+id/myList".
In your fragment, in your onCreateView method, try inflating your layout and getting your view by ID.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.yourDummyLayout, container, false);
//You should get your ListView there
ListView yourListView = rootView.findViewById(R.id.myList);
[......]
return rootView;
}
Try with this ;) Good luck !

Do not clip ViewPager pages

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);`

Android overlapping layouts

I has a Sliding ViewPager with about 5 pages. Each layout is inflated like this:
public static class SectionFragment extends Fragment {
...
#Override
public View onCreateView(LayoutInflater inflater, ...) {
...
rootView = inflater.inflate(R.layout.gridpage1,container,false);
...
}
Now I want to check if a condition is true and if Yes, I want to inflate the gridpage1 layout first, then another layout on top of it.
How can i do this? All I need is the help on inflating two views one on top of the other.
Inflating a view basically just means creating it from an XML file and returning it.
In your specific case, you just need to return your fragment content view from the onCreateView function. This must be a single view, so if your condition is true and you want 2 views do the following:
Create a FrameLayout view yourself programmatically
Something like: FrameLayout frameLayout = new FrameLayout(context);
Add the 1st view to your FrameLayout after inflating it
Either do frameLayout.addView(inflater.inflate(R.layout.gridpage1,frameLayout,false));
or even inflater.inflate(R.layout.gridpage1,frameLayout,true); is enough because true tells it to add the view to the container.
Add the 2nd view to your FrameLayout after inflating it
Return the FrameLayout from your onCreateView
Addition:
How to save the reference to each view:
Option 1:
View v1 = inflater.inflate(R.layout.gridpage1,frameLayout,false);
this.v1Reference = v1;
frameLayout.addView(v1);
Option 2:
inflater.inflate(R.layout.gridpage1,frameLayout,true);
this.v1Reference = frameLayout.findViewById(...);
You can use the <include /> tag in your main layout and then hide/show the views you want with setVisibility(View.GONE/VISIBLE).
For example:
<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="#string/hello_world" />
<include android:id="#+id/gridpage1_layout" layout="#layout/gridpage1"/>
<include android:id="#+id/gridpage2_layout" layout="#layout/gridpage2"/>
...
</RelativeLayout>
And in your Fragment, you can inflate only the root layout and find the other views by ID.

need help regarding ActionBar And Fragmentation

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.

Categories

Resources