Activity Layout: Fragment class: vs android:name attributes - android

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

Related

How does BottomSheetBehavior_Layout_behavior_hideable get translated to app:behavior_hideable?

In the Android documentation for BottomSheetBehavior, it says I can use the following attribute in XML:
BottomSheetBehavior_Layout_behavior_hideable
I tried this:
android:BottomSheetBehavior_Layout_behavior_hideable="true"
But that gave me the following error:
Unknown attribute android:BottomSheetBehavior_Layout_behavior_hideable
That error is discussed at Unknown attribute android:layout_width, layout_height, id, gravity, layout_gravity, padding but none of those solutions worked for me because they were about syncing project files. Mine are synced. Nobody questioned the validity of the attribute name, which is what I think is my problem here.
Then I tried this:
app:BottomSheetBehavior_Layout_behavior_hideable="true"
But that gave me the following error:
Unexpected namespace prefix "app" found for tag
That error is discussed at Unexpected namespace prefix "app" found for tag RelativeLayout - Android? but none of those solutions worked for me, and--more central to my question--there the attribute seems to be written like this:
app:behavior_hideable="true"
Is app:behavior_hideable the correct way to write BottomSheetBehavior_Layout_behavior_hideable? What is the name of the mechanism that performs this translation? Where is its documentation?
There are a couple of components to the answer.
In the constructor for a BottomSheetBehavior, xml attributes are read out as follows Source:
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BottomSheetBehavior_Layout);
setHideable(a.getBoolean(R.styleable.BottomSheetBehavior_Layout_behavior_hideable, false));
These attributes are typically defined in an attrs.xml file. Here's the attrs.xml for the BottomSheetBehavior.
So what's happening here is a LayoutInflater is calling the constructor, and xml attributes are accessed via R.styleable.[name_of_style]_[name_of_attribute]. When you want to apply the style in xml, you simply use the name of the attribute. In the case, the name of the style is "BottomSheetBehavior_Layout", and the name of the attribute is "behavior_hideable". Similarly, you could also use "behavior_skipCollapsed" and "behavior_fitToContents".
For more information on styling, the official docs are here: https://developer.android.com/training/custom-views/create-view#customattr

Custom attributes with class reference

I'm trying to create a custom attribute that behaves like tools:context, that is with
Android Studio auto complete functionallity
Project classname reference
Support for auto refactory in case I change my class directory
This is my resources.xml
<declare-styleable name="RecyclerView">
<attr name="adapter" format="string"></attr>
</declare-styleable>
This is the usage
<example.com.br.appname.RecyclerView
android:id="#+id/accounts"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
app:adapter="example.com.br.appname.AccountAdapter" >
</example.com.br.appname.RecyclerView>
I've tried to use the format reference but it didn't compile as well.
Error:(17, 22) String types not allowed (at 'adapter' with value 'example.com.br.appname.AccountAdapter').
I don’t think this is possible currently. Other similar custom attrs I can think of, for instance app:layout_behavior from the design library, or simply app:layoutManager from RecyclerView all require the full classname, with none of your requirements.
It might be better to store these in a strings resource file, and remember to check it when refactoring class names.
You can consider filing a feature request, since Android Studio has this functionality in special cases (tools:context, class in <view> and <fragment> tags, classes in Manifest...), but I doubt they would add a new attribute format just for this.
so...
apparently, YOU CAN!
Google does this too.
Android Studio understands that the class is being referenced from XML
i.e.
Refactor > Rename works
Find Usages works
and so on...
don't specify a format attribute in .../src/main/res/values/attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCustomView">
....
<attr name="give_me_a_class"/>
....
</declare-styleable>
</resources>
use it in some layout file .../src/main/res/layout/activity__main_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<SomeLayout
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- make sure to use $ dollar signs for nested classes -->
<MyCustomView
app:give_me_a_class="class.type.name.Outer$Nested/>
<MyCustomView
app:give_me_a_class="class.type.name.AnotherClass/>
</SomeLayout>
parse the class in your view initialization code .../src/main/java/.../MyCustomView.kt
class MyCustomView(
context:Context,
attrs:AttributeSet)
:View(context,attrs)
{
// parse XML attributes
....
private val giveMeAClass:SomeCustomInterface
init
{
context.theme.obtainStyledAttributes(attrs,R.styleable.ColorPreference,0,0).apply()
{
try
{
// very important to use the class loader from the passed-in context
giveMeAClass = context::class.java.classLoader!!
.loadClass(getString(R.styleable.MyCustomView_give_me_a_class))
.newInstance() // instantiate using 0-args constructor
.let {it as SomeCustomInterface}
}
finally
{
recycle()
}
}
}

Is it possible to shorten custom view names?

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.

No resource identifier found for

When I try to refactor an app, I get hundreds of "No resource identifier found for (...)" Errors "in package com.app"
How can I solve this Problem?
I already tried to replace the values to the new package Name but the error remains the same.
The Errors happen at such code parts:
<com.example.app
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:latin="http://schemas.android.com/apk/res/com.fa.ime"
android:id="#+id/LatinkeyboardBaseView"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/keyboard_bottom_padding"
android:background="#drawable/keyboard_dark_background"
android:textStyle="bold"
latin:keyBackground="#drawable/btn_keyboard_key_gingerbread"
latin:keyTextStyle="bold"
/>
R class, used to access resources in android, linked to use package name from Android.manifest. Replace in all imports of R class old package name for new package name. Unfortunately you only can use standard text search in this case.
As far as i know, only this class uses package name from manifest, so other imports should be fine.
I don't use Android support package, but if you using it, in every layout associated with activity, there can be parameter named tools:context which include reference to activity. If you changed package name of app, this also could be a source of your problems.

What are "tag" and "id" on Layouts?

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.

Categories

Resources