How can I get PixlUI for Android custom fonts working? - android

I am trying to use PixlUI to implement custom fonts into my Android app using Xamarin. I've followed these steps:
Added a new Android Java Bindings Library to my main solution
Added pixlui-1-0-5.jar to the jars folder
Under properties for pixlui-1-0-5.jar i've set the "include in deploy" to true
Tested my new Android Java Bindings Library and it builds fine without errors
Under the main project i've added my font to the assets/fonts folder
Under references i've added the pixlUI binding library
In my main.axml i've placed this code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:pixlui="http://schemas.android.com/apk/com.neopixl.pixlui"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:screenOrientation="portrait">
<com.neopixl.pixlui.components.textview.TextView
android:id="#+id/textViewpixl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world"
pixlui:copyandpaste="false"
pixlui:clearclipboardcontent="true"
pixlui:typeface="Lato-Light.ttf"
android:layout_below="#id/btnRebate"
/>
</RelativeLayout>
When I build my project it fails with 10 errors all referencing "already contains a definition for..." with error cs0102 inside the pixlUI files.
Ex: .../pixlUI/obj/Debug/generated/src/Com.Neopixl.Pixlui.Components.Edittext.IEditTextBatchListener.cs(59,59): Error CS0102: The type Com.Neopixl.Pixlui.Components.Edittext.AddNewCharEventArgs' already contains a definition forp0' (CS0102) (pixlUI)
I've tried troubleshooting this but it appears to be either an issue with pixlUI or conflict with something already in my solution. Does anyone have an idea on how to solve this?

First of all, you should change the Build Action for the pixelui.jar to EmbeddedJar.
Then you need to add the following to your binding's Metadata.xml file:
<!-- Bindings added to rename event parameters -->
<attr path="/api/package[#name='com.neopixl.pixlui.components.edittext']/interface[#name='EditTextBatchListener']/method[#name='addNewChar']/parameter[#name='p0']" name="name">editText</attr>
<attr path="/api/package[#name='com.neopixl.pixlui.components.edittext']/interface[#name='EditTextBatchListener']/method[#name='deleteKeyboardButton']/parameter[#name='p0']" name="name">editText</attr>
<attr path="/api/package[#name='com.neopixl.pixlui.components.edittext']/interface[#name='EditTextBatchListener']/method[#name='deleteKeyboardButton']/parameter[#name='p1']" name="name">emptyText</attr>
<attr path="/api/package[#name='com.neopixl.pixlui.components.edittext']/interface[#name='EditTextFocusListener']/method[#name='loseFocus']/parameter[#name='p0']" name="name">editText</attr>
<attr path="/api/package[#name='com.neopixl.pixlui.components.edittext']/interface[#name='EditTextFocusListener']/method[#name='requestFocus']/parameter[#name='p0']" name="name">editText</attr>
Rebuild your bindings then you should be able to use it in your Android app.
Here's a screenshot from the sample project:

Related

Override layout files of a library in Android

So in my project, we are overriding a preferences layout file - preference_category_material.xml from androidx.preference:preference library.
Our new code of preference_category_material.xml looks something like this
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="UnusedResources"
android:id="#android:id/textView"
...
/>
The TextView is the root and the only element in the file.
While running ./gradlew lintRelease I am getting this error:
Error: Overriding #layout/preference_category_material which is marked as private in androidx.preference:preference:1.2.0. If deliberate, use tools:override="true", otherwise pick a different name. [PrivateResource]
I have seen a similar question, but that deals with color tags: Override resources in library android
Adding tools:override="true" to the TextView in our file does nothing.
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="UnusedResources"
tools:override="true"
android:id="#android:id/textView"
...
/>
This does not solve the problem.
Any help is appreciated. Thanks.

Android Runtime Resource Overlay with custom attributes

I'm trying to use the Runtime Resource Overlay (RRO) mechanism to overlay an xml resource, which is using custom attributes and custom namespace. When building the overlay APK the aapt2 (link) throws an attribute not found error.
How do I make known the custom attribute from the main application to the overlay?
Is it even possible to use custom attributes in an overlay?
Details:
The overlay contains of two files:
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.test.simpleappoverlay">
<overlay
android:targetPackage="de.test.simpleapp"
android:targetName="Test"/>
</manifest>
and the xml file res/xml/my_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<MyConfig xmlns:app="http://schemas.android.com/apk/res/de.test.simpleapp"
app:text="hello">
</MyConfig>
<!-- I also tried: xmlns:app="http://schemas.android.com/apk/res-auto" -->
The main application defines the attribute text in res/values/attrs.xml:
...
<declare-styleable name="MyConfig">
<attr name="text" format="string" />
</declare-styleable>
Furthermore it defines the overlayable tag in res/values/overlayable.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<overlayable name="Test">
<policy type="public">
<item type="xml" name="my_config"/>
</policy>
</overlayable>
</resources>
To build the overlay I do this:
aapt2 compile -v --dir app/src/main/res/ -o SimpleAppOverlay.flata
and
aapt2 link -v --no-resource-removal
-I ~/Library/Android/sdk/platforms/android-29/android.jar
--manifest app/src/main/AndroidManifest.xml
-o sao.apk SimpleAppOverlay.flata
Which leads to the following output:
note: including /Users/bernd/Library/Android/sdk/platforms/android-29/android.jar
aapt2 W 09-01 14:33:06 20083 694697 ApkAssets.cpp:138] resources.arsc in APK '/Users/bernd/Library/Android/sdk/platforms/android-29/android.jar' is
compressed
note: linking package 'de.test.simpleappoverlay' using package ID 7f note: merging archive SimpleAppOverlay.flata
note: merging 'xml/my_config' from compiled file app/src/main/res/xml/my_config.xml
note: enabling pre-O feature split ID rewriting AndroidManifest.xml:
note: writing to archive (keep_raw_values=false)
note: writing AndroidManifest.xml to archive
note: linking app/src/main/res/xml/my_config.xml (de.test.simpleappoverlay:xml/my_config)
app/src/main/res/xml/my_config.xml:2: error: attribute text (aka
de.test.simpleappoverlay:text) not found
error: failed linking file resources.
I had a similar problem to this where I was trying to overlay an app with custom attributes in Android 10 and have a solution. There are two changes that are needed:
Part 1
It looks like your app name is de.test.simpleapp so your my_config.xml file should look like:
<?xml version="1.0" encoding="utf-8"?>
<MyConfig xmlns:app="http://schemas.android.com/apk/prv/res/de.test.simpleapp"
app:text="hello">
</MyConfig>
The important piece is specifying the 'prv/res/app.packagename' so it uses the namespace of the base app for the private attributes. If you used 'apk/res-auto' that would not work as it resolves to the name of your app (which in this case is the overlay app de.test.simpleappoverlay) which does not contain the definition of the private attributes.
Part 2
Since you now have a dependency on the main app when linking, you have to include it in the link command with a -I simpleapp.apk (or whatever the APK name is of the base app). Right now you are just including android.jar in the aapt2 link step which only contains the 'android' namespace and attributes. Therefore, you now need to add your base app in the include step so it can link properly against its namespace and attributes.
Like some of the other answers said though, this problem goes away in Android 11, but if you're stuck on Android 10 like I am hopefully this helps.
I don't think including new ids is supported in the current implementation of the RROs (at least in Android Q).
Regarding your error, aapt uses the android.jar to generate the apk for your overlay. Since it cannot find your new attribute, it throws an error. For this to work I believe you would need to use a modified android.jar including your attribute. One way of doing this is by modifying the Android SDK in the AOSP and creating your own version that you would then use for the aapt command.
Some time ago I switched my AOSP environment from Android 10 to 11. Google made quite a few changes to the Overlay mechanism. To my big surprise these changes fixed the problems I had when trying to "overlay" custom attributes.
With the Android 10 environment I observed while debugging that the Android XML parser returns "null" when trying to read the mentioned attributes. With idmap I was able to confirm that the attributes were present in the overlay and the target app, and that they were properly mapped.
Also all the linker errors were gone.

CoordinatorLayout element isn't declared

I'm a bit new to programming so bear with me. I'm trying to create a FAB menu by following ResoCoder's tutorial on youtube, but there's an issue with the CoordinatorLayout element being declared.
It throws this warning:
The 'android.support.design.widget.CoordinatorLayout' is not declared.
Here's the AXML file.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Hello FAB menu!"
android:textSize="24sp"/>
<View
android:id="#+id/bg_fab_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#48000000"
android:alpha="0"
android:visibility="gone"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_airballoon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/standard_23"
android:visibility="gone"
android:rotation="90"
app:fabSize="mini"
app:srcCompat="#drawable/ic_airballoon"/>
</android.support.design.widget.CoordinatorLayout>
And here is an image of the warning.
Warning
edit:
This is now showing on the 'Designer' tab
Error on designer tab
Short Answer :
It's just a warning and not an error, you could compile your project without any problem.
Long Answer :
The problem is that the Intellisense could not pick the attributes you type although those attributes did exists in android SDK. So the Visual Studio shows that :
The 'android.support.design.widget.CoordinatorLayout' is not declared.
To solve this problem, you should enable Intellisense in Android .axml files. But a little difference with the document, you could download android-layout-xml.xsd and schemas.android.com.apk.res.android.xsd file from the following link :
https://github.com/atsushieno/monodroid-schema-gen/blob/master/android-layout-xml.xsd
https://github.com/atsushieno/monodroid-schema-gen/blob/master/schemas.android.com.apk.res.android.xsd
Download the file and edit the android-layout-xml.xsd and add the ConstraintLayout element. Then move these file manually to :
C:\Program Files (x86)\Microsoft Visual Studio 14.0\XML\Schemas\1033
Or simply just add these schemas within Visual Studio. Restart your VS, this warning will be gone
Suggestion :
It is recommend that ignoring the warning, you could compile your project without any problem.
Update :
Otherwise, after compiling I get errors like: 'Error: No resource found that matches the given name (at 'layout_margin' with value '#dimen/standard_23').' Which I assume are because of the CoordinatorLayout not being declared.
The dimen attribute need you create on yourself, make sure you copied the dimens.xml file too. You need create the dimens.xml in Resource\values\dimens.xml, define the standard_23 size in this file. Then the compile could find the standard_23 size.
dimen.xml :
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<dimen name="action_button_min_width">56dp</dimen>
<dimen name="indeterminate_progress_size">32dp</dimen>
<dimen name="standard_23">23dp</dimen>
</resources>

Issues when referencing android library project with user defined attributes

The issue is:
I have a project A. It runs well.
Then I config A as a library project. And new a project B to use it.
Then the issue comes like followings:
\res\layout\taskslist.xml:18: error: No resource identifier found for attribute 'content' in package 'com.XXX'
The attribute named 'content' is defined in XML used by MultiDirectionSlidingDrawer in project A:
<resources>
<declare-styleable name="MultiDirectionSlidingDrawer">
<attr name="content" format="reference" />
</declare-styleable>
</resources>
And the taskslist.xml looks like:
<com.XXX.util.MultiDirectionSlidingDrawer
xmlns:my="http://schemas.android.com/apk/res/com.XXX"
...
my:content="#id/content">
<include
android:id="#+id/content"
layout="#layout/menuwithll" />
<ImageView
android:id="#+id/handle"
... />
</com.XXX.util.MultiDirectionSlidingDrawer>
Actually I look into R.java in project A. There is an attr named "content" likes:
public static final class attr {
public static int content=0x7f010002;
}
Anyone know this issue? Thanks in advance!!!
BTW. I have tried clean project. And config project B both in "Android" and "Java build path".
For later one's who also has this issue. It's really simple to resolve by add following code in you layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:my="http://schemas.android.com/apk/res-auto"

jar-Binding of ActionBarSherlock for Mono for Android

I'like to bind the jar-library of ActionBarSherlock in my Mono For Android project. I am reverencing to this documentation: http://docs.xamarin.com/android/tutorials/Binding_a_Java_Library_(.jar)
I have successfully bound android-support-v4.jar which is needed by ActionBarSherlock. But when I try to compile actionbarsherlock.jar, it gives me the following error message:
Target ResolveLibraryProjects:
Skipping target "ResolveLibraryProjects" because it has no inputs.
Target _ResolveMonoAndroidSdks:
MonoAndroid Tools: C:\Program Files (x86)\MSBuild\Novell\
MonoAndroid Framework: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v2.2\;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v1.0\
Android SDK: C:\Program Files (x86)\Android\android-sdk\
Java SDK: C:\Program Files (x86)\Java\jdk1.6.0_31\
Target ExportJarToXml:
SourceJars:
Jars\actionbarsherlock.jar
ReferenceJars:
Jars\android-support-v4.jar
C:\Program Files (x86)\Java\jdk1.6.0_31\bin\java.exe -jar "C:\Program Files (x86)\MSBuild\Novell\jar2xml.jar" --jar=C:\Users\assrock\Documents\JavaBind\JavaBind\Jars\actionbarsherlock.jar --ref="C:\Program Files (x86)\Android\android-sdk\platforms\android-8\android.jar" --out=C:\Users\assrock\Documents\JavaBind\JavaBind\obj\Release\api.xml --ref=C:\Users\assrock\Documents\JavaBind\JavaBind\Jars\android-support-v4.jar
Couldn't load class com/actionbarsherlock/internal/ActionBarSherlockNative$ActionModeCallbackWrapper
Couldn't load class com/actionbarsherlock/internal/app/ActionBarWrapper$TabWrapper
Couldn't load class com/actionbarsherlock/internal/app/ActionBarWrapper
Couldn't load class com/actionbarsherlock/internal/view/ActionProviderWrapper
Couldn't load class com/actionbarsherlock/internal/view/menu/MenuItemWrapper$1
Exception in thread "main" java.lang.NoClassDefFoundError: com/actionbarsherlock/R
at java.lang.Class.getDeclaringClass(Native Method)
at jar2xml.JavaClass.getConstructorParameterOffset(JavaClass.java:149)
at jar2xml.JavaClass.appendCtor(JavaClass.java:138)
at jar2xml.JavaClass.appendToDocument(JavaClass.java:462)
at jar2xml.JavaPackage.appendToDocument(JavaPackage.java:66)
at jar2xml.Start.main(Start.java:157)
Caused by: java.lang.ClassNotFoundException: com.actionbarsherlock.R
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 6 more
C:\Program Files (x86)\MSBuild\Novell\Xamarin.Android.Bindings.targets(170,5): error MSB6006: "java.exe" exited with code 1.
Task "JarToXml" execution -- FAILED
Done building target "ExportJarToXml" in project "C:\Users\assrock\Documents\JavaBind\JavaBind\JavaBind.csproj".-- FAILED
Done building project "C:\Users\assrock\Documents\JavaBind\JavaBind\JavaBind.csproj".-- FAILED
Build FAILED.
Warnings:
C:\Program Files (x86)\MSBuild\Novell\Xamarin.Android.Bindings.targets(40,11): warning MSB4011: There is a circular reference involving the import of file "c:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.Targets". This file may have been imported more than once, or you may have attempted to import the main project file. All except the first instance of this file will be ignored.
Errors:
C:\Users\assrock\Documents\JavaBind\JavaBind\JavaBind.csproj (Build) ->
C:\Program Files (x86)\MSBuild\Novell\Xamarin.Android.Bindings.targets (ExportJarToXml target) ->
C:\Program Files (x86)\MSBuild\Novell\Xamarin.Android.Bindings.targets(170,5): error MSB6006: "java.exe" exited with code 1.
1 Warning(s)
1 Error(s)
Time Elapsed 00:00:00.4730270
--------------------- Fertig ---------------------
Build: 1 Fehler, 0 Warnungen
For the android-support-v4.jar I found these xml-files and put them in the Transforms directory:
EnumFields.xml
<enum-field-mappings>
<mapping jni-class="android/support/v4/app/FragmentActivity$FragmentTag" clr-enum-type="Android.Support.V4.App.FragmentTagType">
<field jni-name="Fragment_id" clr-name="Id" value="1" />
<field jni-name="Fragment_name" clr-name="Name" value="0" />
<field jni-name="Fragment_tag" clr-name="Tag" value="2" />
</mapping>
</enum-field-mappings>
EnumMethods.xml
<enum-method-mappings>
<mapping jni-class="android/support/v4/app/Fragment$SavedState">
<method jni-name="writeToParcel" parameter="p1" clr-enum-type="Android.OS.ParcelableWriteFlags" />
<method jni-name="writeToParcel" parameter="flags" clr-enum-type="Android.OS.ParcelableWriteFlags" />
</mapping>
</enum-method-mappings>
Metadata.xml
<metadata>
<remove-node path="/api/package[#name='android.support.v4.app']/class[#name='BackStackState']" />
<remove-node path="/api/package[#name='android.support.v4.app']/class[#name='FragmentState']" />
<remove-node path="/api/package[#name='android.support.v4.app']/class[#name='FragmentManagerState']" />
<remove-node path="/api/package[#name='android.support.v4.widget']/class[#name='CursorAdapter']/implements[#name='android.support.v4.widget.CursorFilter.CursorFilterClient']" />
<remove-node path="/api/package[#name='android.support.v4.widget']/class[#name='CursorAdapter']/field[#name='mCursorFilter']" />
<remove-node path="/api/package[#name='android.support.v4.content']/class[#name='AsyncTaskLoader.LoadTask']" />
<!-- FIXME:
This method is an override of another method in the base types.
The base method expects JLO, but this method returns Cursor.
So we somehow have to fill the gap between them.
-->
<remove-node path="/api/package[#name='android.support.v4.content']/class[#name='CursorLoader']/method[#name='loadInBackground']" />
<remove-node path="/api/package[#name='android.support.v4.view.accessibility']/class[#name='AccessibilityNodeInfoCompat.AccessibilityNodeInfoIcsImpl']" />
<remove-node path="/api/package[#name='android.support.v4.widget']/class[#name='CursorAdapter.ChangeObserver']" />
<remove-node path="/api/package[#name='android.support.v4.view.accessibility']/class[#name='AccessibilityNodeInfoCompat.AccessibilityNodeInfoIcsImpl']" />
<remove-node path="/api/package[#name='android.support.v4.view.accessibility']/class[#name='AccessibilityNodeInfoCompat.AccessibilityNodeInfoStubImpl']" />
<remove-node path="/api/package[#name='android.support.v4.view']/interface[#name='ViewPager.OnAdapterChangeListener']" />
<attr path="/api/package[#name='android.support.v4.app']/class[#name='LoaderManager']/method[#name='initLoader']/parameter[#name='p2']" name="type">android.support.v4.app.LoaderManager.LoaderCallbacks</attr>
<attr path="/api/package[#name='android.support.v4.app']/class[#name='LoaderManager']/method[#name='initLoader']/parameter[#name='callback']" name="type">android.support.v4.app.LoaderManager.LoaderCallbacks</attr>
<attr path="/api/package[#name='android.support.v4.app']/class[#name='LoaderManager']/method[#name='initLoader']" name="return">android.support.v4.content.Loader</attr>
<attr path="/api/package[#name='android.support.v4.app']/class[#name='LoaderManager']/method[#name='restartLoader']/parameter[#name='p2']" name="type">android.support.v4.app.LoaderManager.LoaderCallbacks</attr>
<attr path="/api/package[#name='android.support.v4.app']/class[#name='LoaderManager']/method[#name='restartLoader']/parameter[#name='callback']" name="type">android.support.v4.app.LoaderManager.LoaderCallbacks</attr>
<attr path="/api/package[#name='android.support.v4.app']/class[#name='LoaderManager']/method[#name='restartLoader']" name="return">android.support.v4.content.Loader</attr>
</metadata>
ActionBarSherlock includes UI elements, styles, and other things that can't be compiled into a JAR file. There is a note about this on the ActionBarSherlock FAQ.
Q: Why is ActionBarSherlock a library project whereas the original compatibility library is only a .jar?
A: The custom action bar implementation within ActionBarSherlock relies on styles, themes, layouts, and drawables in order to display properly. Due to the limitations of Android and .jar files, this currently can not be accomplished any other way.
Edit: There is some additional information about trying to share resources across library projects in Mono for Android at this link: http://mono-for-android.1047100.n5.nabble.com/Resources-from-a-Library-Project-td4657828.html. Short answer is it doesn't look possible at the moment.
I believe I have successfully bound ActionBarSherlock in Mono for Android.
You need to package the java files as a JAR file but without the resources and without the R java class files. Before you package the files make sure that you check the box in Android settings that says "Is Library" so that the resource IDs are not created as constants and inlined in your compiled java classes.
Once you have done this you can use the latest version of Mono for Android to bind the JAR file.
Resources need to be copied separately from the JAR file and placed directly in the main android application project. Unfortunately, at the present time there is no way to isolate the resources in a separate library project when using Mono for Android, but I expect that will change soon.
Finally, you need to edit your C-Sharp project file so that it automatically creates a new version of the com.actionbarsherlock.R java class file each time you rebuild. This is required to keep all your resource IDs in sync.
I may have missed a step or two but those are the most important ones.
Please see my blog post for more information and a download link with source code:
http://www.craigsprogramming.com/2012/07/actionbarsherlock-with-mono-for-android.html
This may seem like a sledgehammer approach, but will likely solve your problem...
I would suggest building using Maven, which handles these dependencies much better. You will be able to reference the ActionBarSherlock project in your POM, and MVN will manage the dependancies for you.
I can confirm the original answer as correct as well - there is a limitation to including JAR files that contain layout resources.
Looks like Xamarin solved ActionBarSherlock bound issue
https://bugzilla.xamarin.com/show_bug.cgi?id=6186
This fix has included in 4.2.5 which is available on alpha channel now.

Categories

Resources