This is probably a mistake or lack of comprehension on my part, but I am quite confused right now. I'm trying to set a TextView in my Xamarin Android application programmatically. Here's my code:
TextView currentCharacterName =
FindViewById(Resource.Id.characterName);
currentCharacterName.SetText("test");
Unfortunately, this does not work, as I get the error "Argument 1: cannot convert from 'string' to 'int'". After reading in the available methods for SetText, I noticed the method I'm trying to call demands a ResId. I don't really understand why I would need a ResId to modify the text of a TextView.
I tried searching on Google for answers, and I came across this answer from 2014 that had the exact same problem as I do. The solution was to use the Text() method instead to set the TextView. Unfortunately, when I try this solution, I get the error "Non-invocable member 'TextView.Text' cannot be used like a method". When I try to check the Text method description, I see "string TextView {get/set} To be added."
Does this mean there's no implementation yet to set the text of a TextView? I am really reluctant to believe this, as it baffles me that such a big framework like Xamarin wouldn't even have get/set functions for something as simple as setting the text of TextView. I feel like there's a very simple solution for my problem, but I can't seem to find it.
TextView.SetText(X) allows you to set the text from a Resource id:
currentCharacterName.SetText(Resources.Id.MyString);
You are looking for the Text property:
currentCharacterName.Text = "test";
Xamarin: TextView class
Android.Widget.TextView.Text Property
Syntax:
public String Text { get; set; }
Test this code:
TextView currentCharacterName = FindViewById<TextView>(Resource.Id.characterName);
currentCharacterName.Text = "Your Text";
In one of my screen i am using text watcher to check value against a range and for invalid range color of text is being changed.
Now there is one more requirement.
Along with EditText i need to use CheckBox to set completely different range.
The problem i am facing is that changing the checkbox value requires to call afterTextChanged in which i have put all validations for both set of ranges.
So basically my requirement is to update textWatcher anyhow so that afterTextChanged get called after i change value of checkbox.
I get a strange feeling that i am forgetting something very simple here,if so please let me know.
Thanks in advance.
Perhaps move your code from the callback in the textWatcher and put it into another function ie
private void checkRange() {
// do checks here
String color = text.getEditableText().toString();
}
and call this method from your textWatcher and from the listener on the checkbox.
This is a question on performance, not on capability.
When I get a View from findViewById(...), and it's an EditText, but I don't need anything specific to EditText, should I cast the View to TextView or to EditText? TextView is a closer subclass to View, but EditText is what the View actually is.
IMHO, yes you can cast the edittext as textview. But I dont think there is any must-to-follow rule. You can perform operations either by casting to an edittext or a textview.
As you dont need the functionalities of edittext you can surely cast to textview
I can see no problem doing that. If you dont have any EditText specific task then go ahead and cast it to TextView.
P.S.:- I personally do that always.. :D
You should cast it to EditText because otherwise it will through exception and your application will be crashed. And BTW if you are doing such things in your code I don't think you are following good practices. So don't do that.
Here is what I think, for me clarity is more important than any kind of optimization you can think of making in your application. If you have an EditText then leave it as such, otherwise you are only adding confusion to the code.
At the end the object already exists, and it is an EditText, so you will be accessing an EditText, no matter what are you casting it. You are only casting it in order to use it's methods in code, but the object instance doesn't change. So regarding to the inheritance, for example, if the EditText has overriden a method of the TextView, if you cast the object to a TextView and use it, you will still be using the EditText method.
Anyway, the virtual machine should cache the results of method resolution, so it wil be no impact in further use.
Don't worry about premature optimizations. Is this actually a bottleneck in your code? It shouldn't be. Something like this is totally negligible. It shouldn't have any noticeable effect on performance because it's still the same underlying object, just the type is being handled differently.
edit: Also, you may not need the EditText features now, but in the future you may. Just leave it as an EditText to save yourself a maintenance headache in the future.
I've found that there IS benefit in casting an EditText to a TextView in java code.
Doing so can reduce the amount of imports in your code, which can (drastically) reduce the size of your compiled APK.
EditTexts and Buttons can more often than not be referenced as TextViews in code (Buttons could also just be a View). Almost any kind of ViewGroup can be referenced as just ViewGroup. AbsListView instead of ListView (API 11+). AbsSpinner instead of Spinner. Just to name a few easy ones. Doing so has reduced some of my apk sizes by 20-30%.
you can miss the cast. findViewById returns a View object. If you don't need anything specific, work with it as View object
EDIT:
since we are talking about performance, here is a quick test. The results looks a bit random to me, but it looks like there is no significant difference between EditText and TextView. Only the Reflection method is slower:
try {
String text = "";
String result = "";
//Reflection
Long time = SystemClock.elapsedRealtimeNanos();
View v = ctx.findViewById(R.id.hello_text);
Field f = v.getClass().getSuperclass().getDeclaredField("mText");
f.setAccessible(true);
text = f.get(v).toString();
time = SystemClock.elapsedRealtimeNanos() - time;
result = "via Reflection ("+time.toString()+" ms)";
//TextView
time = SystemClock.elapsedRealtimeNanos();
TextView t = (TextView)ctx.findViewById(R.id.hello_text);
text = t.getText().toString();
time = SystemClock.elapsedRealtimeNanos() - time;
result = result + "\nvia TextView ("+time.toString()+" ms)";
//EditText
time = SystemClock.elapsedRealtimeNanos();
EditText e = (EditText)ctx.findViewById(R.id.hello_text);
text = e.getText().toString();
time = SystemClock.elapsedRealtimeNanos() - time;
result = result + "\nvia EditText ("+time.toString()+" ms)";
Toast.makeText(ctx, result, Toast.LENGTH_SHORT).show();
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (NoSuchFieldException e) {
}
}
Let me explain:
I need to show the name of any building block either it is imagebutton, edittext in my textview field depending upon which of above written will be hover over by the user.
So that my textview could behave like some dynamic display plate.
Any help will highly be appreciated.
mrana..
So something that you can do. Since there it no "setText" for imageviews, you can do something like
String name = "imageview";
imageView.setTag(name);
Then in your onFocusedChangedListener call the following method
void displayInTextView(View selectedView) {
String viewName = (String) selectedView.getTag();
mDisplayText.setText(viewName);
}
Since this is a touch device, "hovering" will not be possible. One solution is to show the name on when long-press. See this solution https://stackoverflow.com/a/4433441/1227692
EDI: Thanks Frank and mrana for pointing out. I agree and take back my comment.
I have no idea why this doesn't work. The TextView is defined from an tag in the view. The base TextView doesn't have text set and I want to set it in the View on display.
I have tried placing the below in onCreate and onStart but it doesn't seem to work. The last two lines are just for debugging. I can verify that the header does get the text. The thing is, the TextView doesn't actually get updated. Any ideas?
TextView header=(TextView) findViewById(R.id.acheader);
header.setText(R.string.accounts);
header.invalidate();
header=(TextView) findViewById(R.id.acheader);
String blah=(String) header.getText();
Try again removing the text in 4th line
header=(TextView) findViewById(R.id.acheader);
header.invalidate() is not needed.
Instead of String blah = (String) header.getText() try
String blah = heager.getText().toString();
And why are you verifying a "setText()" on text view using code? Why can't you check the
actual output?
The above code might not work the way you are trying to use it, because the redraw of text view is handled by the framework and generally it tries to group item updates (Dirty rectangles to be specific) and update them all at once. It may do it well after your function exits, Try to validate visually, thats the best way.