If I know a variable's pattern such as R.id.edit_x where x (1..N), how can I get a reference to a given EditText, like findViewByID(R.id.edit_1). Is there something like an "eval" function in Dalvik ? Thanks.
Try Java reflection. Discussion on retrieving static final fields via reflection is here - Accessing Java static final ivar value through reflection
hoha's answer is good. Another thing you can do is create a look-up table that maps 1..N to the resource IDs. (Presumably you know all the resource IDs ahead of time.)
maybe, you can check roboguice. it is a ioc framework for android and it's realy easy to use. i copy some code from the sample from the project to show how to use it:
public class AstroboyMasterConsole extends RoboActivity {
#InjectView(R.id.self_destruct) Button selfDestructButton;
#InjectView(R.id.say_text) EditText sayText;
#InjectView(R.id.brush_teeth) Button brushTeethButton;
#InjectView(tag="fightevil") Button fightEvilButton; // we can also use tags if we want
}
then you can you these injected variables in your code!
Related
I have an annotation processing library that generates RecyclerView adapters in compile time.
I'm currently rebuilding it from the ground up with many changes and improvements, but while testing, I received a warning stating:
Resource IDs will be non-final in Android Gradle Plugin version 7.0,
avoid using them as annotation attributes
This is a problem because it means I won't be able to use R.layout variables in annotations.
I currently use it to associate the layout file's integer value with the R class variable name; this is to locate the layout file from the resource folder and later call inflate(layoutResId).
Currently, I solve this issue like so
Example
Given a simple ViewHolder annotation.
annotation class ViewHolder(val layoutResId: Int)
With the usage
#ViewHolder(R.layout.sample)
data class Sample(val text: String) : GencyclerModel
And the Generated R.layout class.
public final class R {
public static final class layout {
public static final int sample = 567541283;
}
}
When processing the ViewHolder annotation, the processor would receive the integer value 567541283.
In the first processing cycle, the processor would analyze the R class and create a table to map the integer to the layout name, in this case, 567541283 <-> sample.
With that info, I can iterate over the layout resource directory and find the layout file with the name sample.xml.
and I can also later call inflate(R.layout.sample)
The field will be non-final in the new version, thus throw a compile-time error.
An annotation argument must be a compile-time constant.
Possible solutions
(Butterknife solution) Creating a duplicate R class that will generate the R.layout variables as static final, thus removing my R class dependency.
(AndroidAnnotations solution). Using strings instead of the Resources class. I'm not too fond of this solution because it will cause issues if the layout is renamed or a typo.
I'm not sure how happy I feel about both, but I honestly don't see other ways to solve it.
If anyone has a better way to solve this, I would love to hear, and if not, which solution would you prefer?
Thanks
I'm linking the issue that I opened in the GitHub project in case you want to contribute.
Another solution would be adding a method to GencyclerModel which returns the layout reference and remove that reference from your annotation. I guess the only problem this approach is going to make, is your checking condition about the existence of layout file in your compiler. But using this approach you won't hardcode layout references in annotations and you'll get them from a method inside each model
I'm getting an underline in some variables on Android Studio (in this case on the 'position' variable). I think it's not an error because the application runs perfectly and the compiler passes everything ok.
I'm wondering what does that mean?
It could be a sign of "Reassigned parameter"
I believe the underlined variables are representative of constants (final or effectively final), because in my experience I only see this decoration when I declare a final object for use inside an anonymous class. I can't seem to find it in the documentation, though.
I've found the answer for this question here.
The decoration is a syntax highlighting preference. Take a look at File > Settings > Editor > Color Scheme > Java/Kotlin
In the case of Java, you can find this effect for example at Parameters > Implicit anonymous class parameter. It's the checkbox Effects.
The same with Kotlin at Properties and Variables > Var (mutable variable, parameter or property).
This means the variable was declared outside the current method. For example, in this case, position is probably declared as a class member outside the new DialogInterface.OnClickListener(), in the class where you're implementing the onItemLongClick() method.
They are declared like this:
public class MyClass{
private int position;
// Other code...
}
It may be because a immutable variable is subjected to modification. Like reassigning a String or trying to modify a final declared variable.
String buffer = "";
buffer = buffer + "new string";
Will underline the buffer, since string are of immutable Objects.
If you know what is the side effect in programming then it will be easy for you. To protect your variable from the side effect, the IDE shows the underline as a warning to you. Which is sometimes very helpful to reduce logical bugs in your code.
why Google calls variables with the prefix "m" for example:
private int mSectionResourceId;
private int mTextResourceId;
I see it in all examples. But i not understand why they do it?
And now i have some example where it practic very good. If a called variabels without prefix i need write
public SimpleSectionedRecyclerViewAdapter(Context context, int sectionResourceId, int textResourceId,
RecyclerView.Adapter baseAdapter) {
this.sectionResourceId = sectionResourceId;
this.textResourceId = textResourceId;
but if i use prefix i can write
public SimpleSectionedRecyclerViewAdapter(Context context, int sectionResourceId, int textResourceId,
RecyclerView.Adapter baseAdapter) {
mSectionResourceId = sectionResourceId;
mTextResourceId = textResourceId;
I think it more readable. Who can explain to me the pros and cons of a prefix?
The variables starting with m are telling you they are variables in the scope of your class. Member of the class.
Link to Android Code Style Guide
The m just stands for 'Member'. It is simply declared that your Variable is a Class-Member.
It is more readable Code, because you know where Class Members got declared, so you can find it pretty fast. You don't need to write this, even if you don't prefix your Variables with an m.
In your Example, this only makes it more readable when there is no prefix-m. Another developer knows that it is a instance variable (member variable) and so declared on top or bottom of the class.
It is a prefix for class member variables. It's just a naming convention.
Mostly sure, taken from Hungarian Notation where similar prefix: m_ stands for exactly the same).
Referring to pros & cons:
Pros:
it allows to type fewer chars during programming,
programmers that are used to use Hungarian Notation may found it easier to follow the code.
Cons:
as the code changes very often, it is easy to forget about changing prefixes every time, when variable changes it's purpose (especially during prototyping),
it makes the code starts to smell bad,
Generally, it is some kind of reinventing the wheel. Java has this keyword that should be more than enough for accessing proper variable. If it's not, the code requires refactoring, maybe because of naming glitches or using too wide variable scopes.
Personally, I do not recommend to use Hungarian Notation (even the part of Android Code Style). We have great IDEs that increases the readability of the code.
There is an exception. The code, where Hungarian Notation (or more general, specific code style) was already been used. It is a matter of consistency.
The m is just a member variable. A class member if you will. Useable with constructors like WebView M WebView then later on you would use something like mWebView.loadurl("example.com"); it's just a placeholder for the variable you created. You don't have to add the member class variable as an m but it's more organized if you do
I need to store a few values that are going to be use in several activities. I know could easily create a Constants class , a Interface or extend the Application class and put those constants there.
But not wanting to reinvent the wheel, I want to ask you if Android have something like appSettings in Asp.net or the Application Descriptor that we had in the old Java Me.
Thanks in advance.
Since you are using constants, there are two solutions:
Create an interface or class with public static final fields.
Create a XML resource file. See Resource Types for details about the resource types.
Personally I prefer 1 for constants that are used in my Java code because 2 requires a Context object and calls to getResources(). This just makes for more code than is really necessary.
Note that I don't give SharedPreference as a possible solution. This is because SharedPreferences should be used to store calculated or user data rather than constant values.
You could use SharedPreferences
Complete Docs
Is there a way to have an global settings variable for an android application, which is accessable as well from any help java classes without giving them context?!
I try to explain what I mean.
I have an application version as string value in strings.xml
I can get its value from every android activity, but not from help java classes withought giving context
What I do now, is saving it in a static variable of my first activity, but it seems, that sometimes it will be erased and set to null.
May be I do something wrong?!
Sorry for newbie question.
And thank you in advance,
Mur
P.s.
I wrote a small tutorial for this topic, to show the solution.
A variable declared as public, static, and final will be visible to all of your classes and never get erased.
public static final String VERSION = "1.2.3.4";
You could make a public static variable in your application class that you fill with the value from strings.xml in the onCreate method. The application class is a singleton and will be the last thing that is killed as part of your app so it will always be there and if you make it public static there will be only one instance.
I'm guessing that you have a JAVA class for some common utility functions. You get the value of your string using a context in your Activity/Service and then pass in that value to the JAVA class function as a parameter.