Meaning of R.layout.activity_main in android development (JAVA language) - java

What is the meaning of R.layout.activity_main ?
I understand that "." operator is used to define variables of a particular object but in this case its been used twice so I can't make anything out of it. Also what exactly is "R" and "layout"?
I mean obviously they are classes (right?) but what is their function ? Basically explain R.layout.activity_main !
Please comment if question too vague or too broad.

R.java is a class (with inner classes, like layout or string) generated during the build process with references to your app's resources. Every resource you create (or which is provided by Android) is referenced by an integer in R, called a resource id.
R.layout.* references any layout resource you have created, usually in /res/layout. So if you created an activity layout called activity_main.xml, you can then use the reference in R.layout.activity_main to access it. Many built-in functionality readily accepts such a resource id, for example setContentView(int layoutResid) which you use during the creation of your activity and where you probably encountered this particular example.
If you create a string resource (in strings.xml) like this:
<string name="app_name">Application name</string>
it will get a new reference in R.string.app_name. You can then use this everywhere where a string resource is accepted, for example the android:label for your application in AndroidManifest.xml, or on a TextView; either in the xml:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
/>
or in code: textview.setText(R.string.app_name).
You can access resources programmatically using the Resources class, to which you can get a reference by calling getResources on any context (like your activity). So for example you can get your app name described above in your activity by calling this.getResources().getString(R.string.app_name).
You can also supply different resources for different device properties/settings (like screen size or language), which you can access using the same references in R. The easiest example here, imho, is strings: if you add a new values folder in /res with a language specifier (so /res/values-nl for Dutch) and you add strings with the same identifier but a different translation and the resource management system cleverly figures out which one to provide for you based on your user's device.
I hope this helps a bit. For more information on resources see the documentation.

R is an auto-generated class, and describe the resources of your project. It contains static inner classes. layout is one of them. R.layout refers to the inner class called layout. activity_main is a public static final member of the class layout

In Android R is an Java-class that is auto-generated from your resources by the build process.
The R.layout member is a auto-generated class that contains all IDs for layouts.
R.layout.activity_main is a static final int member that represents the ID of the layout-file in layout/activity_main.xml.

Okay, so R is a generated class. If you're lucky enough you'll never see it nor have to touch it, otherwise you did something very wrong.
When you make a layout, or any change to a layout, Android Studio generates quite a couple files for you. This includes a R.java file. Here's a piece of an R.java class:
public final class R {
public static final class anim {
public static final int abc_fade_in = 0x7f050000;
public static final int abc_fade_out = 0x7f050001;
public static final int abc_grow_fade_in_from_bottom = 0x7f050002;
public static final int abc_popup_enter = 0x7f050003;
public static final int abc_popup_exit = 0x7f050004;
public static final int abc_shrink_fade_out_from_bottom = 0x7f050005;
public static final int abc_slide_in_bottom = 0x7f050006;
public static final int abc_slide_in_top = 0x7f050007;
public static final int abc_slide_out_bottom = 0x7f050008;
public static final int abc_slide_out_top = 0x7f050009;
}
public static final class attr {
public static final int actionBarDivider = 0x7f010062;
public static final int actionBarItemBackground = 0x7f010063;
public static final int actionBarPopupTheme = 0x7f01005c;
public static final int actionBarSize = 0x7f010061;
public static final int actionBarSplitStyle = 0x7f01005e;
public static final int actionBarStyle = 0x7f01005d;
public static final int actionBarTabBarStyle = 0x7f010058;
public static final int actionBarTabStyle = 0x7f010057;
public static final int actionBarTabTextStyle = 0x7f010059;
As you can see, in this case if I'd type
R.anim.abc_fade_in
I'd be selecting the value 0x7f050000;.
Every layout file is mapped out in this R file, and gets an ID by which android recognizes it. The layouts are located in R.Layout. So, R.layout.activity_main gets you the value of variable activity_main of the class layout of the class R.
And again, don't try finding or changing your generated R file. Things can go very wrong if you do that.

From https://stackoverflow.com/a/4953282/1393766
R is a class containing the definitions for all resources of a particular application package. It is in the namespace of the application package.
If you want to inflate a layout inside your activity class,you can use R.layout.activity_main where layout specifies that your resource is a layout and it's name is activity_main.
If you want to use a drawable image in a layout inside your activity class,you can use R.drawable.image_name where drawable specifies that your resource is a drawable image.
Also,R.java class is an autogenerated class which is not supposed to alter manually.

Related

What is the best practice for passing object reference to different methods?

First, I would like to thank you in advance for reading/answering my first question on stack overflow. I am new to java (android studio) and struggling a bit with understanding all these objects…
I am building my first app and I have created a new class to store and handle some Tile properties.
What I want, is to instantiate the object once then use a reference to that object and I will pass it to other methods for changing the data inside TileProperties. (I believe this is a good optimization of the memory usage)
I have tried a few solutions that I found but couldn’t make them work fully or couldn’t understand the code.
Here is what I did, which works now but I am wondering if it’s the best practice and also if it's a good option for the future:
public class TileProperties {
private String length ;
private String width ;
public static TileProperties object; // I created a static object TileProperties
// which I use to pass the reference
public String getLength() {
return length;
}
public void setLength(String length) {
this.length = length;
}
The code below shows my activity class where the user enters all the properties
Also, its where I initiate my object Tiles
public class TileSettingActivity extends AppCompatActivity {
TileProperties tiles = new TileProperties();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tile_setting);
}
public void clickOkButton (View view) {
TileProperties.object = tiles; // save the object reference tiles to be used by others
EditText lengthTile = findViewById(R.id.editText2);
tiles.setLength(lengthTile.getText().toString());
Log.i("Length:", tiles.getLength());
}
And then in my main activity I wrote this:
public class MainActivity extends AppCompatActivity {
public void clickScanButton(View view){
TileProperties obj ; // define object reference
obj = TileProperties.object; // get the reference of the orginal object Tiles
Log.i("info:", obj.getLength());
}
Thank you!!
No this is not "best practice". It is not even "good practice". It is arguably wrong. Certainly it would be wrong in a larger application.
Let's start with this class:
public class TileProperties {
private String length ;
private String width ;
public static TileProperties object; // I created a static object TileProperties
// which I use to pass the reference
public String getLength() {
return length;
}
public void setLength(String length) {
this.length = length;
}
}
In order of least important to most important, the problems are:
There are various style issues. The most important are that the indentation is incorrect and your choice of object for a variable name is bad. Variable names should convey relevant meaning to the reader.
Documentation. The comment // I created a static object ... should be a proper javadoc comment, that describes the purpose of this (public !) variable.
Public variables break encapsulation and encourage excessive coupling. They are not Object Oriented. They should be avoided.
Public static variables are worse because they also represent global state.
If you are going to implement a single shared "properties" object for the application, there are three ways to do it.
You can create a single instance of the class and pass it as a parameter to all of the parts of the application that need it. This can be clumsy if you have to pass the reference to lots of places.
You can use the Singleton design pattern. A simple example for your use-case would be:
public class TileProperties {
// state variables
private static TileProperties instance = new TileProperties();
private TileProperties() { } // This prevents creation of multiple
// instances of the "singleton"
public static TileProperties getInstance() {
return instance;
}
// getters and setters for state variables, etc.
}
// In main
TileProperties props = TileProperties.getInstance();
props.setLength(42);
There are other ways to implement singletons in Java; e.g. if the singleton needs to be initialized lazily.
Use Dependency Injection (DI).
Dependency injection is considered to be superior to Singleton classes in large-scale applications because singletons present problems for unit testing. However, DI requires a framework such as Spring to implement the injection. That is a whole new learning curve.

can subclass initialize superclass variable

i have an activity say A that is extended by many other activities , i have a variable in activity A which is used by all other sub activities(classes) extending it. I want to know if i can set a value for that variable from a sub-activity such that the change will reflect in all the other subclasses extending Activity A.
i know its a basic question ,i am new to this any help is appreciated.
eg:
Activity A has
public String global = "ABC"
Activity B extent A
display(global); ---> ABC
Activity C extent A
display(global); ---> ABC
Activity D extent A
display(global); ---> ABC
now how can i change global in Activity D such that Activity B and C should also be affected.
Seems like you want a variable whos value persists and remains same throughout.
But since you only want to your inherited classes to be able to update or read the variable, you can do something like this:
class A
{
private static int your_var = 0;
public int get()
{
return your_var;
}
public void set(int a)
{
your_var = a;
}
}
class B extends A
{
}
class C extends A
{
}
In your static void main:
new B().set(101);
new C().get() // this will return value 101.
Note: Here only one copy of variable your_var is created. And since it is private, only the non static getter setter methods will be able to read or modify it. Thus making it accessible only by either the containing class itself or the child class objects.
You need to create a static variable in Activity A.
A static variable is a variable of the class and not of the objects.
You can have a singleton class which can hold global data and when need you can fetch the data from the single commonly shared instance of the singleton class. But there is another better way.
You need a class which sits on top of your activities. In any app we usually do have one such class (may be some Initilizer or main or manager class ) which wires the entities and initiates our application.
In android we have Application class which can hold global data. For reference see Android global variable
try the following:
in class A
public static String global = "ABC";
in class B
public class B extends A {
public static void main(String[] args) {
B b = new B();
A a = new A();
System.out.println(b.global);
System.out.println(a.global);
System.out.println(global);
}
}
alternatively you could try to work with encapsulation: mark the string as private and make the "global" string available through getters and setters. This is often a more flexible solution then working with static variables
http://www.tutorialspoint.com/java/java_encapsulation.htm

Can I assign a static nested class to a variable?

I have a few different button layouts for some controllers mapped inside nested classes. Here's an example:
public class ControllerMap{
public static class Type1{
public static final int BUTTON_A = 1,
BUTTON_B = 2;
}
public static class Type2{
public static final int BUTTON_A = 2,
BUTTON_B = 1;
}
}
I want to make a variable to reference which one to use throughout my code. Something like layout = ControllerMap.Type1;. I'm pretty sure this isn't actually possible, but is there any other way I can do this?
If you want them to be used as layout templates, you could do something like this:
public class Template
{
public static final Template type1 = new Template(1, 2);
public static final Template type2 = new Template(2, 1);
public int buttonA;
public int buttonB;
public Template(int buttonA, int buttonB)
{
this.buttonA = buttonA;
this.buttonB = buttonB;
}
}
And then you can use the layout variable like this:
public static Template layout = Template.type1;
Yes you could refer it from anywhere since both your class are public and class variables are public too like:
int button = ControllerMap.Type1.BUTTON_A;//from anywhere and is resolved at compile time
But if you need it runtime, you could just inject appropriate instance and create getter/setter instead of exposing the field directly.
I think you are trying to use 'static' in an OO way which will never work. In this case you can use the Strategy Pattern to solve your issue, but you will have to adapt your code.
Make your class Type1 and Type2 implement a interface (iController). Then anywhere in your code you can can assign:
iController controller = new Type1();

Why does this method compile?

Why does this method compile?
private int test(){
return R.string.test;
}
R.string.test is defined this way in my android strings.xml file:
<resources>
<string name="test">Test</string>
</resources>
Everything I know about logic, the universe and life itself currently makes no sense. Please help a confused soul.
When you define your resources, android code generator reads the resources file and generate a java file R.java with all the resources id and thats why the code is compiled correctly.
R.string.teste get id of string as integer. So i didn't see any problems...
To get string you should write context.getResources().getString(R.string.teste)
In Android, all the resources located in the res folder are compiled in a class called R.java, there, you have an identifier of the resource created. For example, inside of the R.java class there is a sub class called string for the Strings, id for the ids and so on. In your example you will have:
public final class R {
// Other stuff
public static final class string {
public static final int test=0x7f05001c;
// More String resources
}
// Other stuff
}
So when you are doing return R.string.test; you are returning the id for that resource, in my example 0x7f05001c
If what you want is retrieve the string itself, instead of its id, you need to do what #Suvitruf told you: context.getResources().getString(R.string.test)
Try this :
private String test(){
String mess = getResources().getString(R.string.test);
return mess;
}

Inner class in Android R file

Is there any way to create an inner class in the auto-generated R file?
Right now R file looks like this:
public static final class id {
public static final int button1=0x7f020000;
public static final int button2=0x7f020001;
public static final int text1=0x7f020002;
}
And to access it, you should type
R.id.button1
What do I want to get it something like this:
public static final class id {
public static final class activity1 {
public static final int button1=0x7f020000;
}
public static final int button1=0x7f020001;
}
So I can access it with
R.id.activity1.button1
It is possible to manually edit the file, but that's not the way I'm looking for
Update: I need this because my current project consists of around 20 activities, with 5-30 widgets on each of them. I'm skipping a lot of ids(mostly for buttons and layout), but still it's not comfortable to type something like
AcEventListToolbarUserImageView
(AcEventList - name of activity, Toolbar - frame, UserImageView - user picture)
Update 2: partial solution is:
in activity layout xml
<TextView android:id="#+id_ActivityName/WidgetName" />
in the java code it will be:
R.id_ActivityName.WidgetName
Pros:
see all your activity list after typing "R.id_";
see all widget ids for the activity you need by typing "R.id_ActivityYouNeed."
The auto-generation of the R.java file is purely there as a mechanism to allow you to easily reference the contents of your res hierarchy from your code. As such, you cannot create sub-hierarchies.
The simple solution is to add context to your item names instead. For example, use #+id/Activity1_button1, and you can access this as R.id.Activity1_button1.
The R file is created automaticallly and it SHOULD NOT be edited...even if u try to do that manually when u run ur code a new R file will be created. can u give a reason why you need to do that ?
I dont know if this helps, but you could define your own hierarchical structure of Id containing classes that are defined in terms of your actual resources. You would still need to type the fully qualified name, but only once.
Like this:
public static final class MyResources {
public static final class activity1 {
public static final int button1=R.id.blahblah_button1;
}
public static final int button1=0x7f020001;
}
then refer to them as:
MyResources.activity1.button1;

Categories

Resources