Let's say that I created a custom view called MyView and want to use it in the xml and the view is located in com.example package. I need to do something like this:
<com.example.MyView
......
/>
I need to write the package name every time I use the view. What if I have a long package name?
<what.a.long.long.long.loooooong.packagename.MyView
......
/>
That just looks ugly. Is it possible to shorten the package name? Do I need to do something in the AndroidManifest.xml file?
Define your own namespace:
<Layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:x="what.a.long.long.long.loooooong.packagename."
>
<x:MyView>
</x:MyView>
</Layout>
xmlns:x spefifies that all tags that start with <x: should be looked up in package that is defined in the namespace definition (what.a.long.long.long.loooooong.packagename. in this case).
You can even use the namespace within the tag itself:
<x:MyView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:x="what.a.long.long.long.loooooong.packagename."
/>
You can use my library XmlTag. It lets you use short name of every View that you annotate with #XmlTag.
Related
I have an activity that is displaying to user. On the activity I have a button. Every time when user pushes the button, the app will load an xml file from a remote server. The xml file is actually a layout designed for the application. Right after the new xml file is loaded and stored in the newLayout variable, I would like to set the xml file to replace the current layout that is showing to user.
String newLayoutStr = "";
onClickButton() {
newLayoutStr = loadNewLayoutFromRemoteServer();
}
// set the layout contained in newLayoutStr as new layout of the current activity
Any comments?
This will not be possible with what your asking. Android relies on Resource identifiers using a class call R which is automatically generated. The file contains public static final int references for various class values in your application. The classes referenced here can be found at http://developer.android.com/reference/android/R.html
This class is than used to reference the various resources in your application, one of which is layout. So the system expects all layouts defined in xml to be included in this generated R class.
So in one sentence: you will not be able to accomplish this the way you want.
What i would do is have a json response and convert it to dynamically generated layout.
for XML you download test.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<TextView android:id="#+id/textViewTest"
android:layout_centerInParent="true"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
</RelativeLayout>
If you want to have this layout created in your app create a json response:
{
"layout_parent":"RelativeLayout",
"layout_height": "match_parent",
"layout_width": "match_parent",
"layout_children": [
{
"layout_child":"TextView",
"layout_child_id":"textViewTest",
"layout_height":"wrap_content",
"layout_width":"match_parent",
"layout_gravity":"center",
"layout_centerInParent":"true"
}
]
}
i would then parse this to a model object and use that model object to build your layouts dynamically. In order to add the fields though you will need to have some layout you defined in xml to be able to add more fields to in your app.
As far as I know its currently not possible to load Layout dynamically at runtime that were not available at compile time. This is because the LayoutInflater needs a resource ID(from the R class) and this is determined at compile time. An alternative will be to implement a custom LayoutInflater(by borrowing some ideas from the LayoutInflater class) that can do this though this will be very slow as a lot of optimization is done at compile time
I'm not sure this can be done at runtime from memory. You may be able to marshall the XML and save it to the SD card, then load it as a resource using the AssetManager
From there you can inflate the XML using getLayoutInflater().inflate(YourResourceID, TheRootView)
I'm trying to implement a .java splash screen in my Monodroid app in Visual Studio, anyway I want the splash screen to get it's content view from a resouces layout. I'm trying to get it like this:
setContentView(R.layout.AppSplash);
Also tried with:
setContentView(Resource.layout.AppSplash);
And also:
setContentView("#layout/AppSplash");
And I get error messages like this:
package R does not exist
Where R changes for Resources or:
cannot find symbol
symbol : method setContentView(java.lang.String)
location: class SwimmerTimesCalc.SplashActivity
setContentView("#layout/AppSplash");
When I try the #layout/AppSplash option
How can I access the Monodroid resources to set the layout of my Splash Screen?
This should help you get started.
If you were wanting to use a layout specifically for creating your own splash screen and then using that resource to display it in your activity then you can use something like this.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/SplashScreenLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#+id/SplashDefault"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:scaleType="centerCrop" />
</RelativeLayout>
Then in your activity you can just set the content view.
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.SplashLayout);
}
I figured out how to access the resources, since the debugger couldnt access the resources I went to the generated resources file that is in the project folder under \obj[This can be debug or release]\android\src and it's called R. While browsing that file I found the layout I was trying to use like this:
public static final int appsplash1=0x7f030002;
I took the resource value from there that is 0x7f030002 and used it like this:
setContentView(0x7f030002);
Anyway as the resources file is autogenerated, adding another layout that goes alphabetically before this may require to do this proccess again.
Having the same problem here. One can find the id of the resource in runtime by it's name and folder like this:
int iconResourceId = context.getResources().getIdentifier("icon", "drawable", context.getPackageName());
So, in the Java files one can use such lookups instead of R.drawable.icon and it will work.
This however is slower (because the lookup is implemented inefficiently on Android) and one would still hard-code the names of resources as strings. If one moves or renames resources in the Mono project, the Java files won't know about this.
Also, one has to type all resource names in lower case, cuz Mono converts the name from .NET-style like "Icon.png" to Android style "icon.png".
I've read the documentation about Fragments in the Android Developer Guide and I've seen that sometimes they specify the class to instantiate with the Fragment tag attribute android:name and sometime they use the class: attribute:
<fragment
android:name="com.example.news.ArticleReaderFragment"
android:id="#+id/viewer"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment
class="com.example.android.apis.app.FragmentLayout$TitlesFragment"
android:id="#+id/titles"
android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent" />
Are android:name and class: interchangeable? If I use the autocompletion function in Eclipse, they both show the same documentation tip (i.e. the attribute provides the class name to be instantiated). Maybe you must use the second one when the class to be instantiated has a name which is different from the java file name, like TitlesFragment which is in the FragmentLayout.java file? Or can I use the syntax package.fileDOTjava$Class also with the android:name attribute?
I'd like to have some documentation for XML tags and attributes as for Android Java Classes (I've asked about it in another question).
As Activity.onCreateView source says:
String fname = attrs.getAttributeValue(null, "class");
TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Fragment);
if (fname == null) {
fname = a.getString(com.android.internal.R.styleable.Fragment_name);
}
That seemingly means that program looks "class" attribute first. And on fail looks "name" attribute.
So as far as it's true using "class" if more efficient.
Are android:name and class: interchangeable?
Presumably, yes. I have only used class, and that seems to be what most of Google's examples use, but I do see where they use android:name in some samples. Unfortunately, there is no formal and complete documentation for <fragment>.
Sorry all experts are here, I may be wrong but as per my knowledge android:name attribute of fragment is used to find fragment, when we use getFragmentByTag() method of fragmentManager class.
also android:class attribute is used to find fragment class which we generally include for static fragment.
Hope this will help..
thanks
I know how the switch statement works but I don't know what this means (R.id.webbutton). Can anyone please explain what it is and also what is TAG?
Is there any guide for the beginners? I mean absolute beginners.
IDs and Tags
IDs
Views may have an integer id associated with them. These ids are
typically assigned in the layout XML files, and are used to find
specific views within the view tree. A common pattern is to:
Define a Button in the layout file and assign it a unique ID.
<Button
android:id="#+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/my_button_text"/>
From the onCreate method of an Activity, find the Button
Button myButton = (Button) findViewById(R.id.my_button);
View IDs need not be unique throughout the tree, but it is good
practice to ensure that they are at least unique within the part of
the tree you are searching.
Tags
Unlike IDs, tags are not used to identify views. Tags are essentially
an extra piece of information that can be associated with a view. They
are most often used as a convenience to store data related to views in
the views themselves rather than by putting them in a separate
structure.
Tags may be specified with character sequence values in layout XML as either a single tag using the android:tag attribute or multiple tags using the child element:
<View ...
android:tag="#string/mytag_value" />
<View ...>
<tag android:id="#+id/mytag"
android:value="#string/mytag_value" />
</View>
Tags may also be specified with arbitrary objects from code using setTag(Object) or setTag(int, Object).
Id is id of your xml's components [may be views like textview,edittext... or viewgroup like linearlayout ,relativelayout... or anything else] in xml simply you can get reference to them in java code by saying
(R.id."id of your view in xml")
but firstly you should use setContentView(R.layout."name of xml file in layout/res in your project")
this xml file which you want to use it's components .
TAG i use it when i want to show message in logcat [tool in eclipse you can watch your app messages when it is running] by saying String TAG= yourclassname.class.getsimpleName();
and use it in Log.d(TAG,"any string here"+some variable in my class i want to know it's value in a particular time when app running );
i hope that i made it clear to you .
Start with the tutorials. (If you are so absolutely a beginner that you don't have a development environment set up yet, then start with Installing the SDK.)
When you use the console log facility in Android, the first argument to the logging methods is a tag, which can be used to filter logcat output. A typical programming style is:
public class Something {
private static final String TAG = "Something";
public void aMethod() {
Log.i(TAG, "Entered aMethod");
}
. . .
}
That's what TAG is.
Resource IDs are explained in the tutorial. When you define a resource in XML, Android generates a class called R with nested classes for different kinds of resources (R.id, R.string, R.layout, etc.). Each of those nested classes has a constant for each resource of that type. R.id.webbutton might be generated from a layout file that has a button with attribute android:id="#+id/webbutton". This is all explained in the tutorials.
What is the diffirence between the #id/ and #+id/?
In #+id/ the plus symbol + instructs to create a new resource name and add in to the R.java file but what about #id/? From the documentation of ID: when referencing an Android resource ID, you do not need the plus symbol, but must add the android package namespace, like so:
android:id="#android:id/list"
But in the image below Eclipse doesn't suggest any kind of #android:id/.
Are #id/ and #android:id/ the same?
you refer to Android resources , which are already defined in Android system, with #android:id/.. while to access resources that you have defined/created in your project, you use #id/..
More Info
As per your clarifications in the chat, you said you have a problem like this :
If we use android:id="#id/layout_item_id" it doesn't work. Instead #+id/ works so what's the difference here? And that was my original question.
Well, it depends on the context, when you're using the XML attribute of android:id, then you're specifying a new id, and are instructing the parser (or call it the builder) to create a new entry in R.java, thus you have to include a + sign.
While in the other case, like android:layout_below="#id/myTextView" , you're referring to an id that has already been created, so parser links this to the already created id in R.java.
More Info Again
As you said in your chat, note that android:layout_below="#id/myTextView" won't recognize an element with id myTextViewif it is written after the element you're using it in.
the + sign is a short cut to add the id to your list of resource ids. Otherwise you need to have them in a xml file like this
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="my_logo" type="id"/>
</resources>
In Short
android:id="#+id/my_button"
+id Plus sign tells android to add or create a new id in Resources.
while
android:layout_below="#id/my_button"
it just help to refer the already generated id..
Its very simple:
"#+..." - create new
"#..." - link on existing
Source: https://developer.android.com/guide/topics/resources/layout-resource.html#idvalue
The plus sign (+) before the resource type is needed only when you're defining a resource ID for the first time. When you compile the app, the SDK tools use the ID name to create a new resource ID in your project's R.java file that refers to the EditText element. With the resource ID declared once this way, other references to the ID do not need the plus sign. Using the plus sign is necessary only when specifying a new resource ID and not needed for concrete resources such as strings or layouts. See the sidebox for more information about resource objects.
From: https://developer.android.com/training/basics/firstapp/building-ui.html
From the Developer Guide:
android:id="#+id/my_button"
The at-symbol (#) at the beginning of the string indicates that the XML parser should parse and expand the rest of the ID string and identify it as an ID resource. The plus-symbol (+) means that this is a new resource name that must be created and added to our resources (in the R.java file). There are a number of other ID resources that are offered by the Android framework. When referencing an Android resource ID, you do not need the plus-symbol, but must add the android package namespace, like so:
android:id="#android:id/empty"
There's a bug with Eclipse where sometimes if you just created a new #+id/.., it won't be added immediately to the R.java file, even after clean-building the project. The solution is to restart Eclipse.
This I think should be solved as soon as possible, because it may (and from experience, will) confuse some developers into thinking that there's something wrong with their syntax, and try to debug it even if there's really nothing to debug.
Android uses some files called resources where values are stored for the XML files.
Now when you use #id/ for an XML object, It is trying to refer to an id which is already registered in the values files. On the other hand, when you use #+id/ it registers a new id in the values files as implied by the '+' symbol.
Hope this helps :).
#id/ and #android:id/ is not the same.
#id/ referencing ID in your application, #android:id/ referencing an item in Android platform.
Eclipse is wrong.
Difference between #+id and #id is:
#+id is used to create an id for a view in R.java file.
#id is used to refer the id created for the view in R.java file.
We use #+id with android:id="", but what if the id is not created and we are referring it before getting created(Forward Referencing).
In that case, we have use #+id to create id and while defining the view we have to refer it.
Please refer the below code:
<RelativeLayout>
<TextView
android:id="#+id/dates"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/spinner" />
<Spinner
android:id="#id/spinner"
android:layout_width="96dp"
android:layout_height="wrap_content"
android:layout_below="#id/dates"
android:layout_alignParentRight="true" />
</RelativeLayout>
In the above code,id for Spinner #+id/spinner is created in other view and while defining the spinner we are referring the id created above.
So, we have to create the id if we are using the view before the view has been created.
If the view item performs the same operation, you can use the #+id for each entry in any layout because during the compilation of multiple #+id/foo the R.java file only creates one enumeration. So for example, if I have a save button on each page that performs the same operation, I use android:id="#+id/button_save" in each layout. The R.java file only has one entry for the button_save.
Difference between “#+id/” and “#id/” in Android
The first one is used for to create the ID of the particular ui component and the another one is used for to refer the particular component