I'm following an example from a book and I can't understand why findViewById returns null.
This is my activity:
package it.mt.compass;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
public class CompassActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
CompassView cv = (CompassView)this.findViewById(R.id.compassView1);
// this crashes the application
//cv.setBearing(45);
// some debug code
Toast test_result;
if(cv == null) {
test_result = Toast.makeText(this, "1", Toast.LENGTH_SHORT);
test_result.show();
}
else {
test_result = Toast.makeText(this, "0", Toast.LENGTH_SHORT);
test_result.show();
}
// it shows 1
}
}
and this is the res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<it.mt.compass.CompassView
android:id="#+id/compassView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
Already cleaned (as suggested in other similar topics; what does "Clean" do?) the project with no luck.
Many thanks in advance.
Mirko
As requested, the constructors' code:
// Constructors
public CompassView(Context context) {
super(context);
initCompassView();
}
public CompassView(Context context, AttributeSet attrs) {
super(context);
initCompassView();
}
public CompassView(Context context, AttributeSet ats, int defaultStyle) {
super(context);
initCompassView();
}
That's the correct version (the problem was I didn't passed the parameters correctly to the superclass constructor):
// Constructors
public CompassView(Context context) {
super(context);
initCompassView();
}
public CompassView(Context context, AttributeSet attrs) {
super(context, attrs);
initCompassView();
}
public CompassView(Context context, AttributeSet ats, int defaultStyle) {
super(context, ats, defaultStyle);
initCompassView();
}
CompassView constructor implementation is incorrect. You're not passing the attributes to superclass and hence the id is lost.
Change here the superclass constructor invocation
public CompassView(Context context, AttributeSet attrs) {
super(context);
to super(context, attrs);
and
public CompassView(Context context, AttributeSet ats, int defaultStyle) {
super(context);
to super(context, attrs, defaultStyle); if the superclass has a ctor that accepts three args. Otherwise just use super(context, attrs). Oh, and rename the arg name from ats, even though the name doesn't matter.
In eclipse do:
Projects -> Clean.
Eefresh your app.
Run.
this will clear generated old R class.
I would try closing eclipse completely and then open it again. I've seen some really bizarre things like this happening. Another way you can try this is to just add a "textView" and try to do a findById on that and see if it's returning null. You could be loading the wrong xml view..
ie: your are loading a layout from one directory but it's actually loading a different view in a different directory with the same name...
add import it.mt.compass.R;
and try another View, like a Image or TextView instead
Related
There is a crash on a Samsung Galaxy S 7 Edge when a user is interacting with an EditText that has a LengthFilter InputFilter applied. How would a user cause the method AccessibilityInteractionController.performAccessibilityActionUiThread to be called?
I looked at the source of AccessibilityInteractionController but I cannot find good documentation of how a user would trigger that method.
My crash's stack trace is similar to what is posted in these questions:
Android exception - Unknown origin (possibly widget)
My Android App has IndexOutOfBoundsException,how to solved?
Looking into Android's issue tracker, it seems that this issue is due to password managers using Accessibility events to generate passwords. However, generated password don't respect the maxLength property, causing the crash.
The suggested solution seems to work: creating a subclass, and using that instead. (Copying the code for reference)
public class SafePinEntryEditText extends EditText {
public SafePinEntryEditText(Context context) {
super(context);
}
public SafePinEntryEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SafePinEntryEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(21)
public SafePinEntryEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
public void setSelection(int index) {
// prevent index out of bounds caused by AccessibilityService events
if (index > length()) {
index = length();
}
super.setSelection(index);
}
#Override
public void setSelection(int start, int stop) {
// prevent index out of bounds caused by AccessibilityService events
if (start > length()) {
start = length();
}
if (stop > length()) {
stop = length();
}
super.setSelection(start, stop);
}
}
I'm trying to add a custom view to an Android layout, but get this error when I run it:
Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]
I thought that meant it was missing a constructor, but it doesn't appear to be. Here are the constructors I have for the class:
public ChartView(Context context) {
super(context);
init();
}
public ChartView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ChartView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
I checked the imports, and it is using android.content.Context and android.util.AttributeSet. I tried rebuilding the app, and reinstalling on my device, but no dice. The view is implemented as an inner class of the Activity that contains it, but is public. I feel think I missed something really obvious...
I have created a public class in my main activity e.g.:
public class ActivityMain extends FragmentActivity {
// ...
public class MyClass extends Something implements SomethingListener{
public MyClass(Context context) {
super(context);
}
public MyClass(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyClass(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
// Listener overrides
}
}
And I use it in my layout xml like:
<my.package.ActivityMain.MyClass
app:pstsShouldExpand="true"
//parameters
/>
That way I get a ClassNotFoundException just on the setContentView(R.layout.my_layout) line in Activity's onCreate().
Also the xml design editor on Android Studio complains about this class:
Exception Details java.lang.NoSuchMethodException:
my.package.ActivityMain$MyClass.<init>(android.content.Context, android.util.AttributeSet)
If I used in the xml the class which I extend, all render good. E.g:
xml:
<external.package.Something
android:id="#+id/object"
app:pstsShouldExpand="true"
//parameters
/>
ActivityMain:
Something something = (Something) findViewById(R.id.object)
something.setSomethingListener(new SomethingListener( ... ))
Of course the above solves this issue but is it possible to use a class created in an Activity in my XML?
Update:
The Something class has custom attributes e.g. app:pstsShouldExpand="true" not sure if they are passed down to it from my MyClass. It might be the issue.
Hello i have a problem with the elimination of NullEx ...
I set mContext = context and now i have errors:
Implicit super constructor LinearLayout() is undefined. Must explicitly invoke another constructor
Constructor call must be the first statement in a constructor
public DigitalClock(Context context) {
mContext=context;
this(context, null);
}
Earlier thread Android alarm Clock which shows problem.
You need a superclass constructor call.
public DigitalClock(Context context) {
super(context); // Add a line like this.
// Consult constructor documentation for correct usage.
this(context, null); // this line must also be at the top.
mContext=context;
}
I would assume that you are extending View, in that case you need at least two constructors.
//...Override Constructors...
public DigitalClock(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DigitalClock(Context context){
super(context);
}
See if that helps.
I want to implement my own Tokenizer base on the file
"MultiAutoCompleteTextView.java",
but I encounter an error "com.android.internal.R cannot be resolved" when I try to
import "MultiAutoCompleteTextView.java" to my project.
code:
public class MultiAutoCompleteTextView extends AutoCompleteTextView {
private Tokenizer mTokenizer;
public MultiAutoCompleteTextView(Context context) {
this(context, null);
}
public MultiAutoCompleteTextView(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.autoCompleteTextViewStyle);
}
public MultiAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
.
.
.
}
I haven't research any solutions to resolve this problem.How to correct "com.android.internal.R.attr.autoCompleteTextViewStyle" my own attr?
Thank you for any suggestions.
You could use
public MultiAutoCompleteTextView(Context context, AttributeSet attrs) {
this(context, attrs,
Resources.getSystem().getIdentifier("autoCompleteTextViewStyle", "attr", "android");
}
You cannot access id's of com.android.internal.R at compile time, but you can access the defined internal resources at runtime and get the resource by name.
You should be aware that this is slower than direct access and there is no guarantee, that an internal resource will be available in future versions of android or in vendor-specific builds.
Try copying the attr entry from attrs.xml:
<attr name="autoCompleteTextViewStyle" format="reference" />
Add a res/values/attrs.xml to your application and put this line in there.
Finally, update your code to reference R from your package:
import com.your.package.R;
...
public MultiAutoCompleteTextView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.autoCompleteTextViewStyle);
}
Credit to inazaruk for this procedure.
Yes you can use the internal R with Java reflection.
To get autoCompleteTextViewStyle:
Class clasz = Class.forName("com.android.internal.R$attr")
Field field = clasz.getDeclaredField("autoCompleteTextViewStyle");
field.setAccessible(true);
int autoCompleteTextViewStyle= (int)field.get(null);
As said before, this way is a hack, usually Android provides a public style similar or same based on android.R
This works:
int id = Resources.getSystem().getIdentifier("config_sms_capable", "bool", "android");
Resources res = Resources.getSystem();
boolean configSMSCapable = res.getBoolean(id);
TextView displayText = findViewById(R.id.displayText);
String configSMSCapableString = configSMSCapable ? "TRUE" : "FALSE";
displayText.setText("config_sms_capable = " + configSMSCapableString);
You need to specify the variable you want in the same way.
I am not sure if you can import and reference from internal.
As a workaround download the references from the android source, and include in your own resources, and reference from your package.