As with many I am writing my first app. I am trying to use the three button toggle from here: http://androidasilearnit.wordpress.com/2011/03/05/custom-toggle-button/
The only problem I have at the moment is I have created the attrs.xml file and it is in the res/values folder. However, when I have created the TriToggleButton.java class I am getting errors on all three states that are declared in attrs.xml
//Get the attributes created in attrs.xml
private static final int[] STATE_ONE_SET =
{
R.attr.state_one
};
private static final int[] STATE_TWO_SET =
{
R.attr.state_two
};
private static final int[] STATE_THREE_SET =
{
R.attr.state_three
};
I have looked in R.java (as that was a suggested fix) and they are not in there. I can see all the other XML info in there but not the attr
Any ideas?
Edit:
Here is the attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomButtonState">
<!-- Use one for every state you want to have -->
<attr name="litres" format="boolean" />
<attr name="usgal" format="boolean" />
<attr name="impgal" format="boolean" />
</declare-styleable>
</resources>
Oh and the clean has really broken it. Now all my resources are not being found!! IN MainActivity.java I am now getting "R cannot be resolved to a variable"
For those in the future. Whenever I have this problem it is invariably an XML problem. For me, it is generally always the menu. As far as i can tell it is an eclipse problem because I can delete the whole XML and the R.java will update. I can post the whole XML back in unchanged and the program will compile and run without problem. It is tedious but I can work around it.
Related
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()
}
}
}
I'd like to implement MvxRecyclerView, but I get following exception during runtime in SetContentView():
System.NotSupportedException: Could not activate JNI Handle 0x32700041
(key_handle 0xb29d17e8) of Java type
'mvvmcross/droid/support/v7/recyclerview/MvxRecyclerView' as managed
type 'MvvmCross.Droid.Support.V7.RecyclerView.MvxRecyclerView'.
I use the latest NuGet packages of Xamarin.Android.Support.. (23.3.0) and MvvmCross (4.1.6 / 4.1.7).
Any idea what causes this exception?
More information now on the issue from Ken Kosmowski:
https://github.com/MvvmCross/MvvmCross-AndroidSupport/issues/252
Use the workaround by #kjeremy referenced there, till the issue got fixed:
"The workaround consists of adding Resources\values\attrs.xml file to your Droid project with the following content:"
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<declare-styleable name="MvxRecyclerView">
<attr name="MvxItemTemplateSelector" format="string" />
</declare-styleable>
</resources>
For completion purpose.
With MVVMCross 4.2.0
You should remove the attrs.xml and change all of your MvxItemTemplateSelector references to MvxTemplateSelector.
I'm trying to use this ViewPager extension. This plugin helps me using SwipeyTab. I succeed to run example as a single application. So I want to integrate extension in to my application.Then I coppied the java files and changed package names, everything is fine. But I've got some errors on these lines:
mTextColorCenter = a.getColor(R.styleable.ViewPagerExtensions_textColorSelected, mTextColorCenter);
mLineColorCenter = a.getColor(R.styleable.ViewPagerExtensions_lineColorSelected, mLineColorCenter);
mLineHeightSelected = a.getDimensionPixelSize(R.styleable.ViewPagerExtensions_lineHeightSelected, mLineHeightSelected);
Eclipse says: Styleable cannot be resolved or is not a field. Other lines which contains styleable also gives the same errors too. If I try to click solve this problem nothing changes.
When I have looked at extension's R.java file, I saw these lines:
public static final class styleable {
public static final int[] ViewPagerExtensions = {
0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003,
0x7f010004, 0x7f010005, 0x7f010006, 0x7f010007,
0x7f010008, 0x7f010009, 0x7f01000a
};
public static final int ViewPagerExtensions_dividerColor = 7;
// there is more
}
I know it's not possible to edit R.java. How could I define styleable in R.java for this extension? Any suggestions?
You should define, attributes that you gonna need, in a seperate xml file. I mean create a values.xml and use <declare-styleable name="ViewPagerExtensions"></declare-styleable> tags.
Let me give an example:
<declare-styleable name="ViewPagerExtensions">
<attr format="integer" name="dividerColor" />
</declare-styleable>
By the way, there is already attrs.xml in project, check it out:
I've searched on Google, but couldn't find any relevant results.
I also checked the official Android docs and this page (for all the available resources) was all I could find. The relevant links (to the res/values/ directory) I found on this page were:
string resources
style resources
more resources
These pages don't tell anything about the res/values/public.xml file.
Here is an example I found for this type of file.
Small snippet
<?xml version="1.0" encoding="utf-8"?>
<resources>
<public type="attr" name="commentTextColor" id="0xAA010007" />
<public type="drawable" name="add_icon_bl" id="0xAA020000" />
<public type="layout" name="act_date_picker" id="0xAA030001" />
<public type="anim" name="activity_slide_from_bottom" id="0xAA040000" />
<public type="xml" name="pref_menu" id="0xAA050000" />
<public type="raw" name="alert_bell_animation_bl" id="0xAA060000" />
<public type="array" name="taskRepeat" id="0xAA070000" />
<public type="color" name="theme_main_color_bl" id="0xAA080000" />
<public type="string" name="no_internet" id="0xAA0a0001" />
<public type="id" name="page1" id="0xAA0d0015" />
</resources>
As you can see from the type attribute, it contains pretty much all the standard resource types that you normally put in separate directories under the res directory...
Why would one want to misuse the directories that Android provides and use a single file to store all the values in? Can someone give more information about this?
The file res/values/public.xml is used to assign fixed resource IDs to Android resources.
Consider these set of string resources in res/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="string1">String 1</string>
<string name="string3">String 3</string>
</resources>
The Android Asset Packaging Tool (aapt) might assign the following resource IDs for these resources when the app is compiled:
public final class R {
// ...
public static final class string {
public static final int string1=0x7f040000;
public static final int string3=0x7f040001;
}
}
Now, change the set of string resources to
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="string1">String 1</string>
<string name="string2">String 2</string>
<string name="string3">String 3</string>
</resources>
and you'll notice that the resource ID for #string/string3 has changed:
public final class R {
// ...
public static final class string {
public static final int string1=0x7f040000;
public static final int string2=0x7f040001;
public static final int string3=0x7f040002; // New ID! Was 0x7f040001
}
}
To prevent this, you can use res/values/public.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<public type="string" name="string3" id="0x7f040001" />
</resources>
which will result in the resource IDs being assigned as follows:
public final class R {
// ...
public static final class string {
public static final int string1=0x7f040000;
public static final int string2=0x7f040002;
public static final int string3=0x7f040001; // Resource ID from public.xml
}
}
Applications rarely have any use for res/values/public.xml since the resource IDs assigned to resources does not matter. When they change, the entire application is rebuilt anyway so any references in Java code to resources by resource ID will be updated.
The most significant user of res/values/public.xml is the Android platform itself. Applications built against old versions of Android assumes that certain resource have a certain resource ID. For example, the Android resource #android:style/Theme must always have the resource ID 0x01030005 for the platform to be backwards compatible with apps built against old versions of the platform.
If you are curious about more details on how resource IDs are assigned, please refer to this answer: How does the mapping between android resources and resources ID work?
https://developer.android.com/studio/projects/android-library.html#PrivateResources
public.xml is useful for library projects in general. If you include a public.xml, it's assumed that the rest of your resources are meant to be private.
Although private resources will still be usable by other projects, the linter will warn about using them, and they won't be included in AndroidStudio's autocompletion.
Here's a gist for autogenerating public.xml
https://gist.github.com/HannahMitt/99922d4183bdb03356fd339413ba6303
Is it not a file just for the use authors of the OS code to define a mapping between symbolic names and system resource ids?
You'll find it in your SDK at YOUR_SDK_LOCATION\platforms\android-??\data\res\values.
It's headed
This file defines the base public resources exported by the platform,
which must always exist
and has the caveat:
IMPORTANT NOTE FOR ANYONE MODIFYING THIS FILE READ THIS BEFORE YOU
MAKE ANY CHANGES
This file defines the binary compatibility for resources. As such,
you must be very careful when making changes here, or you will
completely break backwards compatibility with old applications
It has entries such as
<public type="attr" name="smallScreens" id="0x01010284" />
<public type="attr" name="normalScreens" id="0x01010285" />
<public type="attr" name="largeScreens" id="0x01010286" />
in it - all system resurce ids, so anyone changing entries will break their code, insomuch as it won't run on a standard device.
I recently split my project and created a library project and a main project. Having a preferences screen that has custom attributes, i removed the preferences with custom attributes from my preferences.xml, put them into their own xml files, included them back into the preferences.xml file and redefined the individual files in the main project (the process is detailed in the answer to another question here.
The project build and run properly. However, I am getting a RuntimeException whenever i try to open the preferences screen. Removing the prefs with custom attrs fixes the problem, so i have traced it back to there. Unfortunately there is no useful information in the exception.
attrs.xml (exists in lib project)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="numberpickerPref">
<attr name="maxValue" format="integer" />
<attr name="minValue" format="integer" />
</declare-styleable>
</resources>
preferences.xml (also in lib project)
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="#string/pref_VibrationSettingsTitle">
<CheckBoxPreference android:key="#string/pref_vibrateFlagKey"
android:title="#string/pref_VibrateTitle"
android:summary="#string/pref_VibrateSummary"
android:defaultValue="false" />
<include layout="#layout/pref_vibrate_on" />
<include layout="#layout/pref_vibrate_off" />
</PreferenceCategory>
</PreferenceScreen>
pref_vibrate_off.xml (defined in both lib and main projects) (only diff is the my namespace, one points to the lib, the other the main project)
<?xml version="1.0" encoding="utf-8"?>
<!-- Stupid workaround because Android still has a bug where custom attributes in a library cause the executable project
problems when building:
https://stackoverflow.com/questions/4461407/help-with-a-custom-view-attributes-inside-a-android-library-project -->
<com.me.numberpicker.NumberPickerPreference
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:my="http://schemas.android.com/apk/res/com.me.myapp.lib"
android:key="#string/pref_vibrateOffPeriodKey"
android:title="#string/pref_VibrateOffTitle"
android:summary="#string/pref_VibrateOffSummary"
my:maxValue="#string/MaxVibratorOffPeriodInS"
my:minValue="#string/MinVibratorOffPeriodInS"
android:defaultValue="#string/DefaultVibratorOffPeriodInS" />
MyPreferencesActivity.java
public class MegalarmPreferencesActivity extends PreferenceActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
All the strings are properly defined in the lib project.
If i'm missing anything, let me know please. The preferences were working fine until i split up my project into a lib and main.
Many thanks!
Sean
PreferenceActivity.onCreate can throw RuntimeExceptions internally that the IDE might catch (if configured to do so), but they are also caught internally. For instance, a missing layout_width tag in the default theme seems to cause an exception.
If the RuntimeException is not percolating back to your code don't worry about it. If it is, could you update your question to include the exception message and stack trace?