My custom SurfaceView is null after findViewById() [duplicate] - java
First of all: yes, I read all the other threads on this topic. And not only those from this site... (you see, I'm a little frustrated)
Most of them come with the advice to use android:id instead of just id in the XML file. I did.
From others, I learned, that View.findViewById works different than Activity.findViewById. I handled that, too.
In my location_layout.xml, I use:
<FrameLayout .... >
<some.package.MyCustomView ... />
<LinearLayout ... >
<TextView ...
android:id="#+id/txtLat" />
...
</LinearLayout>
</FrameLayout>
In my Activity I do:
...
setContentView( R.layout.location_layout );
and in my custom view class:
...
TextView tv = (TextView) findViewById( R.id.txtLat );
which returns null. Doing this, my Activity works fine. So maybe it's because of the Activity.findViewById and View.findViewById differences. So I stored the context passed to the customs view constructor locally and tried:
...
TextView tv = (TextView) ((Activity) context).findViewById( R.id.txtLat );
which also returned null.
Then, I changed my custom view to extend ViewGroup instead View and changed the location_layout.xml to let the TextView be a direct child of my custom view, so that the View.findViewById should work as supposed. Suprise: it didn't solve anything.
So what the heck am I doing wrong?
I'll appreciate any comments.
which returns null
Possibly because you are calling it too early. Wait until onFinishInflate(). Here is a sample project demonstrating a custom View accessing its contents.
Possibly, you are calling findViewById before calling setContentView?
If that's the case, try calling findViewById AFTER calling setContentView
Make sure you don't have multiple versions of your layout for different screen densities. I ran into this problem once when adding a new id to an existing layout but forgot to update the hdpi version. If you forget to update all versions of the layout file it will work for some screen densities but not others.
FindViewById can be null if you call the wrong super constructor in a custom view. The ID tag is part of attrs, so if you ignore attrs, you delete the ID.
This would be wrong
public CameraSurfaceView(Context context, AttributeSet attrs) {
super(context);
}
This is correct
public CameraSurfaceView(Context context, AttributeSet attrs) {
super(context,attrs);
}
Alongside the classic causes, mentioned elsewhere:
Make sure you've called setContentView() before findViewById()
Make sure that the id you want is in the view or layout you've given to setContentView()
Make sure that the id isn't accidentally duplicated in different layouts
There is one I have found for custom views in standard layouts, which goes against the documentation:
In theory you can create a custom view and add it to a layout (see here). However, I have found that in such situations, sometimes the id attribute works for all the views in the layout except the custom ones. The solution I use is:
Replace each custom view with a FrameLayout with the same layout properties as you would like the custom view to have. Give it an appropriate id, say frame_for_custom_view.
In onCreate:
setContentView(R.layout.my_layout);
FrameView fv = findViewById(R.id.frame_for_custom_layout);
MyCustomView cv = new MyCustomView(context);
fv.addView(cv);
which puts the custom view in the frame.
In my case, I had 2 activites in my project, main.xml and main2.xml. From the beginning, main2 was a copy of main, and everything worked well, until I added new TextView to main2, so the R.id.textview1 became available for the rest of app. Then I tried to fetch it by standard calling:
TextView tv = (TextView) findViewById( R.id.textview1 );
and it was always null. It turned out, that in onCreate constructor I was instantiating not main2, but the other one. I had:
setContentView(R.layout.main);
instead of
setContentView(R.layout.main2);
I noticed this after I arrived here, on the site.
#Override
protected void onStart() {
// use findViewById() here instead of in onCreate()
}
A answer for those using ExpandableListView and run into this question based on it's title.
I had this error attempting to work with TextViews in my child and group views as part of an ExpandableListView implementation.
You can use something like the following in your implementations of the getChildView() and getGroupView() methods.
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.child_layout, null);
}
I found this here.
FWIW, I don't see that anyone solved this in quite the same way as I needed to. No complaints at compile time, but I was getting a null view at runtime, and calling things in the proper order. That is,
findViewById()
after
setContentView().
The problem turned out that my view is defined in content_main.xml, but in my activity_main.xml, I lacked this one statement:
<include layout="#layout/content_main" />
When I added that to activity_main.xml, no more NullPointer.
I'm pretty new to Android/Eclipse, by mistake I added the UI stuff to activity_main.xml instead of fragment_main.xml. Took me some hours to figure that out...
I had this same problem. I was using a third-party library that allows you to override their adapter for a GridView and to specify your own layout for each GridView cell.
I finally realized what was happening. Eclipse was still using the library's layout xml file for each cell in the GridView, even though it gave no indication of this. In my custom adapter, it indicated that it was using the xml resource from my own project even though at runtime, it wasn't.
So what I did was to make sure my custom xml layouts and ids were different from those still sitting in the library, cleaned the project and then it started reading the correct custom layouts that were in my project.
In short, be careful if you're overriding a third-party library's adapter and specifying your own layout xml for the adapter to use. If your layout inside your project has the same file name as that in the library, you might encounter a really difficult-to-find bug!
In my particular case, I was trying to add a footer to a ListView. The following call in onCreate() was returning null.
TextView footerView = (TextView) placesListView.findViewById(R.id.footer);
Changing this to inflate the footer view instead of finding it by ID solved this issue.
View footerView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.footer_view, null, false);
Just wanted to throw my specific case in here. Might help someone down the line.
I was using the directive in my Android UI XML like this:
Parent view:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="home_phone"
android:background="#color/colorPrimary">
...
<include
layout="#layout/retry_button"
android:visibility="gone" />
Child view (retry_button):
<com.foo.RetryButton
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/retry"
android:layout_gravity="center"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="140dp">
.findViewById(R.id.retry) would always return null. But, if I moved the ID from the child view into the include tag, it started working.
Fixed parent:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="home_phone"
android:background="#color/colorPrimary">
...
<include
layout="#layout/retry_button"
android:id="#+id/retry"
android:visibility="gone" />
Fixed child:
<com.foo.RetryButton
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_gravity="center"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="140dp">
In my case, I was using ExpandableListView and I had set android:transcriptMode="normal". This was causing few children in expandable group to disappear and I used to get NULL exception when ever I used scroll the list.
For me I had two xml layouts for the same activity - one in portrait mode and one in landscape. Of course I had changed the id of an object in the landscape xml but had forgotten to make the same change in the portrait version. Make sure if you change one you do the same to the other xml or you will not get an error until you run/debug it and it can't find the id you didn't change. Oh dumb mistakes, why must you punish me so?
Set the activity content from a layout resource.
ie.,setContentView(R.layout.basicXml);
In addition of the above solutions you make sure the
tools:context=".TakeMultipleImages"
in the layout is same value in the mainfest.xml file :
android:name=".TakeMultipleImages" for the same activity element.
it is occur when use copy and paste to create new activity
I have the same problem, but I think its worth sharing with you guys.
If you have to findViewById in custom layout, for example:
public class MiniPlayerControllBar extends LinearLayout {
//code
}
you cannot get the view in constructor.
You should call findViewById after view has inflated.
Their is a method you can override onFinishInflate
My case is none like above, no solutions worked. I assume my view was too deep into layout hierarchy. I moved it one level up and it was not null anymore.
INFLATE THE LAYOUT !! (which contains the id)
In my case findViewById() returned null, because the layout in which the element was written, was not inflated...
Eg.
fragment_layout.xml
<ListView
android:id="#+id/listview">
findViewById(R.id.listview) returned null, because I had not done
inflater.inflate(R.layout.fragment_layout, ..., ...);
before it.
Hope this answer helps some of y'all.
In my case I had inflated the layout but the child views were returning null. Originally I had this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history);
footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listview_footer, null, false);
pbSpinner = (ProgressBar) findViewById(R.id.pbListviewFooter);
tvText = (TextView) findViewById(R.id.tvListviewFooter);
...
}
However, when I changed it to the following it worked:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history);
footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listview_footer, null, false);
pbSpinner = (ProgressBar) footerView.findViewById(R.id.pbListviewFooter);
tvText = (TextView) footerView.findViewById(R.id.tvListviewFooter);
...
}
The key was to specifically reference the already inflated layout in order to get the child views. That is, to add footerView:
footerView.findViewById...
It crashed for me because one of fields in my activity id was matching with id in an other activity. I fixed it by giving a unique id.
In my loginActivity.xml password field id was "password". In my registration activity I just fixed it by giving id r_password, then it returned not null object:
password = (EditText)findViewById(R.id.r_password);
In my experience, it seems that this can also happen when your code is called after OnDestroyView (when the fragment is on the back stack.) If you are updating the UI on input from a BroadCastReceiver, you ought to check if this is the case.
findViewById also can return null if you're inside a Fragment. As described here: findViewById in Fragment
You should call getView() to return the top level View inside a Fragment. Then you can find the layout items (buttons, textviews, etc)
In my case, findViewById returned null when I moved the call from a parent object into an adapter object instantiated by the parent. After trying tricks listed here without success, I moved the findViewById back into the parent object and passed the result as a parameter during instantiation of the adapter object.
For example, I did this in parent object:
Spinner hdSpinner = (Spinner)view.findViewById(R.id.accountsSpinner);
Then I passed the hdSpinner as a parameter during creation of the adapter object:
mTransactionAdapter = new TransactionAdapter(getActivity(),
R.layout.transactions_list_item, null, from, to, 0, hdSpinner);
I was facing a similar problem when I was trying to do a custom view for a ListView.
I solved it simply by doing this:
public View getView(int i, View view, ViewGroup viewGroup) {
// Gets the inflater
LayoutInflater inflater = LayoutInflater.from(this.contexto);
// Inflates the layout
ConstraintLayout cl2 = (ConstraintLayout)
inflater.inflate(R.layout.custom_list_view, viewGroup, false);
//Insted of calling just findViewById, I call de cl2.findViewById method. cl2 is the layout I have just inflated.
TextView tv1 = (TextView)cl2.findViewById(cl2);
Ways to debug and find the issue:
Comment out all findViewById in your activity.
Comment out everything except onCreate and setContentView
Run the project and see if any layout is set
In my case, I was using activity_main.xml in both my app module and also my library module. So when I performed the above steps, instead of the layout which I designed in the library, the layout inside app module was inflated.
So I changed the activity_main.xml file name to activity_main_lib.xml.
So make sure you do not have any duplicate layout names in your whole project.
The issue for me was that I had two layouts with the same file name activity_main.xml. (The layouts were in different libraries but in the same app) The issue was solved by renaming one of them to a unique name.
For me it returned null because the given control was (programmatically) hidden. When I put a condition to call findViewByID(id) only when the control is visible, it started working again.
For me it was only null when using Evaluate Expression or the Debug Watch View of the IDE.
Related
Binary XML file line #50: Error inflating class fragment [duplicate]
I have a very frustrating error that I cannot explain. I created an Android application that uses Android AppCompat to make it compatible with older versions. Here is my main activity layout file: <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="#+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <!-- As the main content view, the view below consumes the entire space available using match_parent in both dimensions. --> <FrameLayout android:id="#+id/container" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- android:layout_gravity="start" tells DrawerLayout to treat this as a sliding drawer on the left side for left-to-right languages and on the right side for right-to-left languages. If you're not building against API 17 or higher, use android:layout_gravity="left" instead. --> <!-- The drawer is given a fixed width in dp and extends the full height of the container. --> <fragment android:id="#+id/navigation_drawer" android:layout_width="#dimen/navigation_drawer_width" android:layout_height="match_parent" android:layout_gravity="start" android:name="com.fragment.NavigationDrawerFragment" /> </android.support.v4.widget.DrawerLayout> And here is main code of my activity : public class MainActivity extends ActionBarActivity { #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } } The main problem here is : above code run smoothly on almost devices (stimulated device, or some real devices). But when I run it on Samsung S3. It notices this error: java.lang.RuntimeException: Unable to start activity ComponentInfo{view.MainActivity}: android.view.InflateException: Binary XML file line #25: Error inflating class fragment at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2081) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2106) at android.app.ActivityThread.access$700(ActivityThread.java:134) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1217) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4856) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774) at dalvik.system.NativeStart.main(Native Method) Caused by: android.view.InflateException: Binary XML file line #25: Error inflating class fragment at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) at android.view.LayoutInflater.rInflate(LayoutInflater.java:746) at android.view.LayoutInflater.inflate(LayoutInflater.java:489) at android.view.LayoutInflater.inflate(LayoutInflater.java:396) at android.view.LayoutInflater.inflate(LayoutInflater.java:352) at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:316) at android.app.Activity.setContentView(Activity.java:1901) at android.support.v7.app.ActionBarActivity.superSetContentView(ActionBarActivity.java:208) at android.support.v7.app.ActionBarActivityDelegateICS.setContentView(ActionBarActivityDelegateICS.java:111) at android.support.v7.app.ActionBarActivity.setContentView(ActionBarActivity.java:76) Please tell me how to fix error, thanks :)
After long time for debugging, I have fixed this problem. (Although I still cannot explain why). That I change property android:name to class. (although on Android Document, they say those properties are same, but it works !!!) So, it should change from : android:name="com.fragment.NavigationDrawerFragment" to class = "com.fragment.NavigationDrawerFragment" So, new layout should be : <!-- As the main content view, the view below consumes the entire space available using match_parent in both dimensions. --> <FrameLayout android:id="#+id/container" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- android:layout_gravity="start" tells DrawerLayout to treat this as a sliding drawer on the left side for left-to-right languages and on the right side for right-to-left languages. If you're not building against API 17 or higher, use android:layout_gravity="left" instead. --> <!-- The drawer is given a fixed width in dp and extends the full height of the container. --> <fragment android:id="#+id/navigation_drawer" android:layout_width="#dimen/navigation_drawer_width" android:layout_height="match_parent" android:layout_gravity="start" class = "com.fragment.NavigationDrawerFragment" /> Hope this help :)
TL/DR: An exception occurred during the creation of a fragment referenced from a higher-level layout XML. This exception caused the higher-level layout inflation to fail, but the initial exception was not reported; only the higher-level inflation failure shows up in the stack trace. To find the root cause, you have to catch and log the initial exception. The initial cause of the error could be a wide variety of things, which is why there are so many different answers here as to what fixed the problem for each person. For some, it had to do with the id, class, or name attributes. For others it was due to a permissions issue or a build setting. For me, those didn't fix the problem; instead there was a drawable resource that existed only in drawable-ldrtl-xhdpi, instead of in an applicable place like drawable. But those are just details. The big-picture problem is that the error message that shows up in logcat doesn't describe the exception that started it all. When a higher-level layout XML references a fragment, the fragment's onCreateView() is called. When an exception occurs in a fragment's onCreateView() (for example while inflating the fragment's layout XML), it causes the inflation of the higher-level layout XML to fail. This higher-level inflation failure is what gets reported as an exception in the error logs. But the initial exception doesn't seem to travel up the chain well enough to be reported. Given that situation, the question is how to expose the initial exception, when it doesn't show up in the error log. The solution is pretty straightforward: Put a try/catch block around the contents of the fragment's onCreateView(), and in the catch clause, log the exception: public View onCreateView(LayoutInflater inflater, ViewGroup contnr, Bundle savedInstSt) { try { mContentView = inflater.inflate(R.layout.device_detail_frag, null); // ... rest of body of onCreateView() ... } catch (Exception e) { Log.e(TAG, "onCreateView", e); throw e; } } It may not be obvious which fragment class's onCreateView() to do this to, in which case, do it to each fragment class that's used in the layout that caused the problem. For example, in the OP's case, the app's code where the exception occurred was at android.app.Activity.setContentView(Activity.java:1901) which is setContentView(R.layout.activity_main); So you need to catch exceptions in the onCreateView() of any fragments referenced in layout activity_main. In my case, the root cause exception turned out to be Caused by: android.content.res.Resources$NotFoundException: Resource "com.example.myapp:drawable/details_view" (7f02006f) is not a Drawable (color or path): TypedValue{t=0x1/d=0x7f02006f a=-1 r=0x7f02006f} This exception didn't show up in the error log until I caught it in onCreateView() and logged it explicitly. Once it was logged, the problem was easy enough to diagnose and fix (details_view.xml existed only under the ldrtl-xhdpi folder, for some reason). The key was catching the exception that was the root of the problem, and exposing it. It doesn't hurt to do this as a boilerplate in all your fragments' onCreateView() methods. If there is an uncaught exception in there, it will crash the activity regardless. The only difference is that if you catch and log the exception in onCreateView(), you won't be in the dark as to why it happened. P.S. I just realized this answer is related to #DaveHubbard's, but uses a different approach for finding the root cause (logging vs. debugger).
I couldn't solve my problem using provided answers. Finally I changed this: <fragment android:id="#+id/fragment_food_image_gallery" android:name="ir.smartrestaurant.ui.fragment.ImageGalleryFragment" android:layout_width="match_parent" android:layout_height="200dp" android:layout="#layout/fragment_image_gallery" tools:layout="#layout/fragment_image_gallery" /> to this : <FrameLayout android:id="#+id/fragment_container" android:layout_width="match_parent" android:layout_height="200dp" /> , private void showGallery() { ImageGalleryFragment fragment = new ImageGalleryFragment() getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, fragment) .commit(); } and it works. If you are using it inside fragment, use getChildFragmentManager instead of getSupportFragmentManager.
I had the same problem, issue, tried all the answers in this thread to no avail. My solution was, I hadn't added an ID in the Activity XML. I didn't think it would matter, but it did. So in the Activity XML I had: <fragment android:name="com.covle.hellocarson.SomeFragment" android:layout_width="wrap_content" android:layout_height="wrap_content"/> But should've had: <fragment android:id="#+id/some_fragment" android:name="com.covle.hellocarson.SomeFragment" android:layout_width="wrap_content" android:layout_height="wrap_content"/> If someone would be happy to comment on why this is, I'm all ears, to other, I hope this helps.
It might not be needed for you anymore, but if further readers find it helpful. I have exact same android.view.InflateException:...Error inflating class fragment. I had all right libraries included. Solved by adding one more user permission in the AndroidManifest.xml file i.e. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> Btw I was running Android Studio 0.8.9 on Ubuntu 12.04.
I have the same problem because I did not implement the listener. See the following code with /*Add This!*/. public class SomeActivity extends AppCompatActivity implements BlankFragment.OnFragmentInteractionListener /*Add this!*/ { #Override /*Add This!*/ public void onFragmentInteraction(Uri uri){ /*Add This!*/ } /*Add This!*/ } FYI, my fragment class is something like the following: public class SomeFragment extends Fragment { private OnFragmentInteractionListener mListener; #Override public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (OnFragmentInteractionListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener"); } } public interface OnFragmentInteractionListener { public void onFragmentInteraction(Uri uri); } } Edit: I also notice this same error message under another circumstances when there is an exception in the onCreate function of the Fragment. I have something as the following: #Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); int ID = getArguments().getInt("val"); return rootView; } Because I reuse this fragment, I total forget to set arguments. Then the result of getArguments() is null. Obviously, I get a null pointer exception here. I will suggest you keep an eye on mistakes like this as well.
Is your NavigationDrawerFragment extending the android.support.v4.app.Fragment? In other words, are you importing the correct package? import android.support.v4.app.Fragment;
I also had this issue. I solved it by replacing the import in MainActivity and NavigationDrawerFragment From import android.app.Activity; import android.app.ActionBar; To import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity; I updated MainActivity to extends ActionBarActivity instead of Activity public class MainActivity extends ActionBarActivity implements NavigationDrawerFragment.NavigationDrawerCallbacks Also use ActionBar actionBar = getSupportActionBar(); to get the ActionBar And I updated the following function in NavigationDrawerFragment private ActionBar getActionBar() { return ((ActionBarActivity)getActivity()).getSupportActionBar(); }
i faced this problem and solved it by using following codes. I was beginning fragment transaction by using childfragment manager. layout: <fragment class="com.google.android.youtube.player.YouTubePlayerSupportFragment" android:id="#+id/youtube_fragment" android:layout_width="match_parent" android:layout_height="wrap_content"/> this is how i began fragment transaction: youTubePlayerFragment = (YouTubePlayerSupportFragment) getChildFragmentManager().findFragmentById(R.id.youtube_fragment); the following codes explains how i removed the fragment which added by using childfragmentmanger. #Override public void onDestroyView() { super.onDestroyView(); youTubePlayerFragment = (YouTubePlayerSupportFragment) getChildFragmentManager().findFragmentById(R.id.youtube_fragment); if (youTubePlayerFragment != null) { getChildFragmentManager().beginTransaction().remove(youTubePlayerFragment).commitAllowingStateLoss(); } youTubePlayer = null; }
I have had similar problems on and off. The error message often provides very little detail, regardless of actual cause. But I found a way to get more useful info. It turns out that the internal android class 'LayoutInflater.java' (in android.view package) has an 'inflate' method that re-throws an exception, but does not pick up the details, so you lose info on the cause. I used AndroidStudio, and set a breakpoint at LayoutInflator line 539 (in the version I'm working in), which is the first line of the catch block for a generic exception in that 'inflate' method: } catch (Exception e) { InflateException ex = new InflateException( parser.getPositionDescription() + ": " + e.getMessage()); ex.initCause(e); throw ex; If you look at 'e' in the debugger, you will see a 'cause' field. It can be very helpful in giving you a hint about what really occurred. This is how, for example, I found that the parent of an included fragment must have an id, even if not used in your code. Or that a TextView had an issue with a dimension.
Just in case someone needs this. Assumptions: Device phone hooked up to USB cable and your IDE reading to launch the app. Go to the command prompt to determine issue: enter adb logcat Then launch your app from IDE. You will an exception. In my case: I was deploying an Android app of Version 2.3 to a mobile device that did not support the widget "Space"
Add this name field in navigation android:name="androidx.navigation.fragment.NavHostFragment" <fragment android:id="#+id/container" android:layout_width="match_parent" android:layout_height="0dp" android:name="androidx.navigation.fragment.NavHostFragment" app:navGraph="#navigation/navigation" app:layout_constraintBottom_toTopOf="#+id/bottomNavigationView" app:layout_constraintTop_toTopOf="parent">
This problem arises when you have a custom class that extends a different class (in this case a view) and does not import all the constructors required by the class. For eg : public class CustomTextView extends TextView{} This class would have 4 constructors and if you miss out on any one it would crash. For the matter of fact I missed out the last one which was used by Lollipop added that constructor and worked fine.
we must also need to add following in build.gradle(app) compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:design:23.1.1' whenever we are using new layouts or new design features. hope this helps you.
As mentioned in a previous post, rename android:name="com.fragment.NavigationDrawerFragment" to class = "com.fragment.NavigationDrawerFragment" Still, it did not work for me. I then just used the Class Name without the com.fragment part and voila it worked. So change it finally to class = "NavigationDrawerFragment"
After none of the answers here helped me, I opted to run app in debug mode moving across every line of onCreateView in my fragment (NavigationDrawerFragment in your case). And noticed that fragment was having difficulty with inflating because of a NullPointerException. E.g. mySeekBar = (SeekBar) getActivity().findViewById(R.id.mySeekBar); mySeekBar.setOnSeekBarChangeListener(this); Here mySeekBar was set to null (because I had missed adding the control in appropriate layout) and the next line got into NPE which came out as InflateException. Also, as suggested above, rename android:name to class. This issue can arise for various reasons mentioned above. I would recommend line-by-line debug flow to know what is wrong.
After long time of tries, this is how I solved the problem after none of the above answers could. Extend AppCompatActivity for your Main activity instead of Activity. Add android:theme="#style/Theme.AppCompat.Light" to your <Activity..../> in the AndroidManifest.xml In your NavigationDrawerFragment Class, change your ActionBar instances to ActionBar mActionBar=((AppCompatActivity)getActivity()).getSupportActionBar(); EDIT It should be a consistency between the Activity and Layout. If the Layout has one of the AppCompat Theme such like Theme.AppCompat.Light, your Activity should extends AppCompatActivity. I wanted to have the burger icon and a Navigation Drawer that looks like the Android Gmail App, but I ended up with an ugly Navigation Drawer. All that because all my Classes extends Activity instead of AppCompatActivity. I re-factored the entire project to extend AppCompatActivity, then Right-Click on the Layout Folder, chose new -> Activity then Navigation Drawer Activity and Boom, everything is done for me!
android.view.InflateException: Binary XML file line #16: Error inflating class com.google.android.material.bottomappbar.BottomAppBar The view can be anything that is failing to get inflated, this kind of error comes when there is a clash in resolving the class names or name attribute of a view referred in the XML file. When I get the same error I just got everything clean and safe in UI-XML file, the view I was using, <com.google.android.material.bottomappbar.BottomAppBar android:id="#+id/bottomAppBar" style="#style/Widget.MaterialComponents.BottomAppBar.Colored" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" app:hideOnScroll="true" app:menu="#menu/bottom_app_bar" app:navigationIcon="#drawable/ic__menu_24"/> I was using a style attribute which was referring the Material components property. But my styles.xml had... <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> .... </style> Where the class resolving was facing the conflict. My view attributes referred a property that was not defined in my app theme. The right parent theme from material components helped me. So I changed the parent attribute to... <style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar"> ... </style> Which resolved the issue.
For some of you that still haven't found a solution for this, in my case it was happening because I had an OOM (Out of Memory) issue. This can happen when you have for example a memory leak in your app when using it for a long time. In my stack trace, this was the main reason.
I don't know if this will help. I had this problem with a TextView I had in the layout I was trying to inflate (android.view.InflateException: Binary XML file line #45: Error inflating class TextView). I had set the following XML attribute android:textSize="?android:attr/textAppearanceLarge" which wasn't allowing for the layout to be inflated. Don't know exactly why, (I'm still a bit new to Android - less than a year of experience), might have something to do with calling system attributes, idk, all I know is as soon as I used plain old #dimen/md_text_16sp (which is a custom of mine), problem solved :) Hope this helps...
I had this on a 4.4.2 device, but 5+ was fine. The cause: inside a custom view's initialisation, I was creating a TextView(Context context, AttributeSet attrs, #AttrRes int defStyleAttr, #StyleRes int defStyleRes), which is API 21+. Android Studio 2.1 doesn't complain about it even though it is annotated TargetApi(21). Apparently, Android Studio 2.2 will correct this and properly show it as an error. Hope this helps someone.
I am a bit late to the party but Non of these answer helped me in my case. I was using Google map as SupportMapFragment and PlaceAutocompleteFragment both in my fragment. As all the answers pointed to the fact that the problem is with SupportMapFragment being the map to be recreated and redrawn. But I also had problem with PlaceAutocompleteFragment. So here is the working solution for those who are facing this problem because of SupportMapFragment and SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.mapFragment); FragmentManager fm = getChildFragmentManager(); if (mapFragment == null) { mapFragment = SupportMapFragment.newInstance(); fm.beginTransaction().replace(R.id.mapFragment, mapFragment).commit(); fm.executePendingTransactions(); } mapFragment.getMapAsync(this); //Global PlaceAutocompleteFragment autocompleteFragment; if (autocompleteFragment == null) { autocompleteFragment = (PlaceAutocompleteFragment) getActivity().getFragmentManager().findFragmentById(R.id.place_autoCompleteFragment); } And in onDestroyView clear the SupportMapFragment and SupportMapFragment #Override public void onDestroyView() { super.onDestroyView(); if (getActivity() != null) { Log.e("res","place dlted"); android.app.FragmentManager fragmentManager = getActivity().getFragmentManager(); android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.remove(autocompleteFragment); fragmentTransaction.commit(); autocompleteFragment = null; } }
In my particular case the problem was I added this line to a TextView : android:background="?attr/selectableItemBackground" After removing this, everything started to work fine.
I don`t know what happened, but Changing Fragment to FrameLayout solved my problem after many hours of struggle. <FrameLayout android:id="#+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" />
I think the basic problem is with "android:targetSdkVersion" which is defined in AndroidManifest.xml. In my case, the initial value which I have defined as: android:targetSdkVersion=16 I changed it to: android:targetSdkVersion=22 which resolved my all of the error. So, setting up the correct "targetSdkVersion" is also important before building an android app.
In case someone else comes here and the answers do not help solve the problem, one more thing to try. As others have mentioned, this usually is caused by an issue nested in the XML itself as opposed to something you did wrong in your Java. In my case, it was a super easy (and stupid) mistake to fix. I had code like this: <view android:layout_width="fill_parent" android:layout_height="1dip" android:id="#+id/view44" android:background="#color/gray" /> When all I had to do was capitalize the v in 'View' so that the system recogized it. Check that your custom views (Or Fragments, recyclerviews, etc) all have the proper capitalized declaration up front so that the XML auto-complete will match it to the appropriate view.
I had this error too, and after very long debugging the problem seamed to be that my MainClass extended Activity instead of FrameActivity, in my case, the xml wasn't a problem. Hope to help you.
In my case . The layout i was trying to inflate had <include layout = "...." /> tag, removing it fixed it. I was trying to inflate a previous layout designed for a Actvity into the view-pager adapter.
My error was caused by a different problem. I was passing a bundle from an Activity to its fragment. When I commented the code receiving the bundle in the fragment the error was gone. As it turns out, my error was due to the below "getArguments();" part which was returning null. Bundle args = getArguments(); Upon checking the Activity sending code, I realized I had a silly mistake in the below; Bundle bundle =new Bundle(); bundle.putInt("recipeID", recipe_position); Fragment mainFragment = new MainActivityFragment(); mainFragment.setArguments(bundle); FragmentManager fragmentManager = getSupportFragmentManager(); --> fragmentManager.beginTransaction() .replace(R.id.container, new MainActivityFragment(), DetailRecipeActivityFragment.TAG) .commit(); I was creating a NEW fragment in the line with the arrow. Whereas I should have used the pre-instantiated fragment that already had my bundle. So it should have been: Bundle bundle =new Bundle(); bundle.putInt("recipeID", recipe_position); Fragment mainFragment = new MainActivityFragment(); mainFragment.setArguments(bundle); Fragment mainFragment = new MainActivityFragment(); FragmentManager fragmentManager = getSupportFragmentManager(); -->fragmentManager.beginTransaction() .replace(R.id.container, mainFragment, DetailRecipeActivityFragment.TAG) .commit(); I don't know why exactly it throws this error instead of an NPE, but this solved my error in case someone is having the same scenario
I was having the same problem, in my case the package name was wrong, fixing it solved the problem.
Cannot Programmatically Set EditText ID
I am creating a dynamic number of editTexts and want to eventually pull the ID for each to call .getText() on the editText. However, I noticed that it is difficult to programmatically set the ID, so I am using the .setTag() method instead: private void createAnswerChoice(int answerNumber) { ViewGroup layout = (ViewGroup) mRootView.findViewById(R.id.create_poll_questions_answer_layout); EditText editText = new EditText(getActivity()); editText.setHint(getResources().getString(R.string.answer_text) + " " + answerNumber); editText.setSingleLine(true); editText.setImeOptions(EditorInfo.IME_ACTION_DONE); String editTextID = ((getResources().getString(R.string.created_answer_editText_id))+String.valueOf(answerNumber)); editText.setTag(editTextID); Toast.makeText(getActivity().getApplicationContext(), editTextID, Toast.LENGTH_SHORT).show(); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); editText.setLayoutParams(layoutParams); TextInputLayout newAnswer = new TextInputLayout(getActivity()); newAnswer.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); newAnswer.addView(editText, layoutParams); layout.addView(newAnswer); } How would I get the value of each editText if I know the tag and not the ID? Also, what is the purpose of the .setTag() method (how does it relate to .setID()?)
create resource file(id.xml) in res/values/id.xml <?xml version="1.0" encoding="utf-8"?> <resources> <item type="id" name="edittext_hello" /> </resources> and then set, editText.setId(R.id.edittext_hello);
findViewById() and findViewWithTag() are methods intended to obtain a reference to a View that was inflated from XML. If you are creating the Views, you have them already then there's no need to use those methods. Keep the reference to the View somewhere.
I do not recommend using tags to get views from your hierarchy but if you must this SO post describes how to do it: https://stackoverflow.com/a/16262479/6526330. Tags should be used when you need to cache some data in a view to grab out later when you have the view again (yes I know very generic). Some examples would be if you are using a holder in a list view or if you have a lot of views on a screen and want a global click listener vs listeners for each view. I stole both of these examples from the answers on this post which do a hell of a better job at describing the use cases than I can.
Telling the Difference between two Android GUI objects with the same ID
Say we have two XML files, of which these are snippets: firstxml.xml <?xml version="1.0" encoding="utf-8"?> <Button android:layout_width="match_parent" android:layout_height="match_parent" android:id="#+id/button1 /> secondxml.xml <?xml version="1.0" encoding="utf-8"?> <Button android:layout_width="match_parent" android:layout_height="match_parent" android:id="#+id/button1 /> In our onCreate() method: //Assume all packages necessary are imported public class Example { public void onCreate(Bundle sis) { super.onCreate(sis); setContentView(R.layout.firstxml); Button thisButton = (Button) findViewbyId(R.id.button1); } } Which button is called and instantiated when this code runs? Since the two buttons are in two different files, will the button in firstxml.xml be called because it is the content view of the function? Thanks in advance for your answers!
When you set the firstxml to be the content view, that layout gets inflated. findViewById will find the id's in the current layout that's inflated rather than on every layout. setContentView method description kind of answers your question.
You are referencing the the first XML layout file R.layout.firstxml in the activity's onCreate(Bundle...) method, so the search here will be made. Any call to findViewById(int id); will search in your inflated layout R.layout.firstxml. The R.java file is automatically generated when you are defining/adding a new view to your layout. You can use the same id multiple times, but not in the same layout !
The code will call and instantiate the button1 set on your firstxml.xml file. Note For future readers. If the layout file doesnot contain button1 it will throw null pointer exception and the editor wont know that there is an error. This is because R.id.button1 is static field in your R.java class. Also provide better naming convention to your variables for maintainability.
Which button is called and instantiated when this code runs? Since you used the firstxml.xml as the layout of the activity you are calling the reference of that button from that xml not the button from the secondxml.xml. And in your R.java it will only generate one instance of that id. sample: public static final class id { public static final int button1=0x7f090009; } so when you used that reference of that button it will first find/check the layout's id if it exist if it does not exist then it will throw NPE.
Difference between fragment_main.xml and activity_main.xml
I'm following along with the tutorial here https://developer.android.com/training/basics/firstapp/building-ui.html and I'm confused as to why they say to edit fragment_main.xml instead of activity_main.xml. In the MainActivy.java file, the onCreate() method has a line that says setContentView(R.layout.activity_main); Why does it complain when I try to change it to setContentView(R.layout.fragment_main); Any pointers would be appreciated.
The activity is a container of fragments, a fragment is like an UI layer which can be added, modified or deleted in execution time. also in the activity layout you can have added "static" fragments. There can be a lot of causes for your error if you swap the layouts, maybe your activity code tries to reference some views that are not in the fragment layout or viceversa, maybe the activity layout has references to fragments, etc... You can name your layouts as you want, but you need to set the layout that matches with your code in your activities/fragments
you have to use setContentView(R.layout.activity_main); in your program where as setContentView(R.layout.fragment_main); is used when you use Different Fragments in One Activity and you getting error because there is no xml file present named fragment_main.xml in res folder.
its just name fragment_main or activity_main if you wish you can give your GF :D name also, i.e when you add a layout file to res/layout path an entry will be maid in R.java say you create main.xml in res/layout, and when you clean your project an entry R.layout.main will be added to R.java its just the name whatever you give to file. may be you getting error because that file not there or might be that file don't hold layout in it.
Both are optional. But, It's always better using one layout to avoid confusion into your code. Which in this case I will suggest using activity_main.xml and delete the fragment_activity.xml following the below procedure: 1.Creat project normally. 2.Copy fragment_main.xml to activity_main.xml (content). Then delete fragment_main.xml 3.In MainActivity.java delete the following content : if (savedInstanceState == null) { getFragmentManager().beginTransaction() .add(R.id.container, new PlaceholderFragment()).commit(); } and /** * A placeholder fragment containing a simple view. */ public static class PlaceholderFragment extends Fragment { public PlaceholderFragment() { } #Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); return rootView; } } Hope this help
NullPointerException when acting on a View
For some reason I'm getting a nullPointerException when working with any new View I place in my XML. The view type (TextView, EditText, etc) doesn't matter. Any views I originally had work - it's isolated to any newly added views. I've tried cleaning the project numerous times, deleted the entire XML file, restarted eclipse, then re-pasted the XML back into a new file, no luck. Appears to be similar as this question, but nothing has gotten this working. I really don't want to have to re-create the entire project, but I'm not sure what else to do if recreating the XML and cleaning isn't enough. Code is as follows: XML ... <TextView android:id="#+id/dlg_add_proj_test_text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Test Text" /> ... Activity ... public void fireDlg() { final Dialog dialog = new Dialog(this); dialog.setContentView(R.layout.dialog_add_proj); dialog.setTitle("Add Project"); //Other previous views TextView newTxtView = (TextView) findViewById(R.id.dlg_add_proj_test_text); newTxtView.setText("New Text"); //Null Pointer Here } ...
you should be using dialog.findViewById(R.id.dlg_add_proj_test_text) instead of just findViewById. The findViewById uses the activity's method while dialog.findViewById uses the method in the dialog.