I am trying to convert the DragnDrop listview from here https://github.com/commonsguy/cwac-touchlist to C# with Mono for Android.
Part of this custom View requires the use of some custom attributes that are declared as the following inside the file Resources/values/attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TouchListView">
<attr name="normal_height" format="dimension" />
<attr name="expanded_height" format="dimension" />
<attr name="grabber" format="reference" />
<attr name="dragndrop_background" format="color" />
<attr name="remove_mode">
<enum name="none" value="-1" />
<enum name="fling" value="0" />
<enum name="slide" value="1" />
<enum name="slideRight" value="1" />
<enum name="slideLeft" value="2" />
</attr>
</declare-styleable>
</resources>
I then try to use them inside my layout file like this:
<app.monodroid.TouchListView xmlns:tlv="http://schemas.android.com/apk/res/app.monodroid"
android:id="#+id/lstExercises"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/lExerciseActions"
android:drawSelectorOnTop="false"
tlv:normal_height="64dip"
tlv:grabber="#+id/icon"
tlv:remove_mode="slideRight"
/>
But when I try to build my project I get the following error message:
/Library/Frameworks/Mono.framework/External/xbuild/Novell/Novell.MonoDroid.Common.targets: Error: Tool exited with code: 1. Output: /Users/path_to_project/App.MonoDroid/obj/Debug/res/layout/add_session.axml:1: error: No resource identifier found for attribute 'normal_height' in package 'com.app.monodroid'
/Users/path_to_project/App.MonoDroid/obj/Debug/res/layout/add_session.axml:1: error: No resource identifier found for attribute 'grabber' in package 'com.app.monodroid'
/Users/path_to_project/App.MonoDroid/obj/Debug/res/layout/add_session.axml:1: error: No resource identifier found for attribute 'remove_mode' in package 'com.app.monodroid'
(App.MonoDroid)
The name of my project is App.MonoDroid.
How can I use these attributes inside my layout file?
These errors should go away if you declare a package name for your app. In the project properties, go to the Android Manifest tab, and you'll see a text field for Package Name:
... and then make sure you use this package name for your assembly and namespace:
and use it in your xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/**app.monodroid**"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<**app.monodroid**.FICalendarView
android:id="#+id/FICalendar"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
custom:dayStyle="1">
</**app.monodroid**.FICalendarView>
<Button
android:id="#+id/MyButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/Hello"/>
</LinearLayout>
where FICaldendarView is a custom view defined as:
namespace app.monodroid
{
public class FICalendarView : View
{
//private FICalenderView() {}
public FICalendarView(Context context)
: base(context)
{
}
public FICalendarView(Context context, Android.Util.IAttributeSet attribute)
: base(context, attribute)
{
Android.Content.Res.TypedArray a = context.Theme.ObtainStyledAttributes(attribute, Resource.Styleable.FICalendarView, 0, 0);
//Android.Util.TypedValue typedValue = null;
int dayStyle = a.GetInteger(Resource.Styleable.FICalendarView_dayStyle,0);
}
public FICalendarView(Context context, Android.Util.IAttributeSet attribute, int x)
: base(context, attribute,x)
{
}
}
}
Related
We currently have a .net MAUI project with a BlazorWebView:
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiApp1"
x:Class="MauiApp1.MainPage">
<VerticalStackLayout Spacing="20" Padding="20" Background="#25a6fb">
<Label Text="Communicate between MAUI (C#) and BlazorWebView (JS)" TextColor="White" FontSize="20"
FontAttributes="Bold" HorizontalTextAlignment="Center" HorizontalOptions="Center" />
<VerticalStackLayout BackgroundColor="#25a6fb" Padding="10" Spacing="10">
<Frame Padding="10, 5">
<Entry x:Name="MauiEntry" Placeholder="Entry from MAUI" PlaceholderColor="Gray" TextColor="Gray" />
</Frame>
<HorizontalStackLayout HorizontalOptions="Center" Spacing="20">
<Button Text="MAUI to WebView" Clicked="MauiToWebView" />
</HorizontalStackLayout>
</VerticalStackLayout>
<BlazorWebView x:Name="BlazorWebView" HostPage="wwwroot/dist/index.html" WidthRequest="375" HeightRequest="400">
<BlazorWebView.RootComponents>
<RootComponent Selector="app" ComponentType="{x:Type local:Main}" />
</BlazorWebView.RootComponents>
</BlazorWebView>
<VerticalStackLayout>
</VerticalStackLayout>
</VerticalStackLayout>
</ContentPage>
And also just a basic Vue3 Project with nothing special.
We build the Vue3 project and then with a SymbolicLink show the dist/build folder in the .net MAUI project. And reference its index.html in the BlazorWebView.
We would like to call information back and forth between both projects.
We tried using JSInterop in the Main.razor file, but this didn't work.
#inject IJSRuntime Js
<Router AppAssembly="#typeof(Main).Assembly">
<Found Context="routeData">
<RouteView RouteData="#routeData"/>
<FocusOnNavigate RouteData="#routeData" Selector="h1"/>
</Found>
<NotFound>
<LayoutView>
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
<br><br>
<code #ref="_codeBlock"></code>
#code
{
private ElementReference _codeBlock;
public async Task PrintDotNetObject()
{
var obj = new {
FistName = "Jon",
LastName = "Doe",
Age = 27,
BirthDate = DateTime.Now.AddYears(-27),
LikesDotNet = true
};
await Js.InvokeVoidAsync("dotNetMauiApp.getMessage", _codeBlock, obj);
}
}
PrintDotNetObject gets called when we click the button in the xaml file.
And this is what we had in the Vue3 Project:
<script>
export default {
name: "MauiCommunication",
mounted() {
window.dotNetMauiApp = {
getMessage: function(node, objectFromDotNet)
{
node.textContent = JSON.stringify(objectFromDotNet);
return window.alert("Called From MAUI " + node.textContent)
}
};
}
}
</script>
But we got a null reference for JSRuntime when using this. So is there a way to fix this? Or is there another (better) way to do this?
getting that extra node "" while writing a node in XML with xmlsluper.
Got the thread response to use xmlparser.
But we do have a constraint to use xmlxlurper, how can we fix it (or remove it) with xmlslurper ?
Our groovy code snippet
def xmlFromFile = new File(xxx.xml)
def envelopeNode = new XmlSlurper( false, false ).parseText(xmlFromFile.getText())
def newNode = new XmlSlurper().parseText(SomeStringWithProperXMLChildNode)
envelopeNode.rows.appendNode(newNode)
XmlUtil xmlUtil = new XmlUtil()
xmlUtil.serialize(envelopeNode, new FileWriter(xmlFromFile))
How I can remove ""
Or can stop serialize/XmlSlurper from adding that extra encoding info.
XML Snippet :
<SomeThing xmlns="http://xmlns.oracle.com/something" name="something">
<description />
<columns>
<column name="name" />
<column name="Type" />
<column name="Identifier" />
</columns>
<rows>
<row>
<cell>111</cell>
<cell>222</cell>
<cell>333</cell>
</row>
<row>
<cell>444</cell>
<cell>555</cell>
<cell>666</cell>
</row>
</rows>
</SomeThing>
Thanks
I have created a design with the following source axml:
when the listview output is shown getting data from the sqllite database the listview will overlap the test textview,edittext as below:
Required Output Result Listview should be below as shown below:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#ffffff"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:text="#string/test"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="87.5dp"
android:layout_height="wrap_content"
android:id="#+id/test"
android:textColor="#android:color/black" />
<EditText
android:id="#+id/test_input"
android:layout_height="wrap_content"
android:layout_width="152.0dp"
android:inputType="text"
android:layout_toRightOf="#+id/test" />
<Button
android:id="#+id/MyButton"
android:layout_width="128.5dp"
android:layout_height="wrap_content"
android:text="#string/ButtonClick"
android:layout_toRightOf="#+id/test_input" />
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listtable"
android:layout_alignBottom="#+id/MyButton" />
</RelativeLayout>
Assuming you are using the Appcompat Library i would do the following changes to your layout :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#ffffff"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:orientation="horizontal"
android:id="#+id/LinearContent"
android:layout_alignParentTop="true"
android:layout_height="wrap_content">
<TextView
android:text="Test"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="87.5dp"
android:layout_height="wrap_content"
android:id="#+id/test"
android:textColor="#android:color/black" />
<EditText
android:id="#+id/test_input"
android:layout_height="wrap_content"
android:layout_width="152.0dp"
android:inputType="text"
android:layout_toRightOf="#+id/test" />
<Button
android:id="#+id/MyButton"
android:layout_width="128.5dp"
android:layout_height="wrap_content"
android:text="Search"
android:layout_toRightOf="#+id/test_input" />
</android.support.v7.widget.LinearLayoutCompat>
<android.support.v7.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_below="#id/LinearContent"
android:layout_height="wrap_content">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listtable"
/>
</android.support.v7.widget.LinearLayoutCompat>
Revert in case it doesn't work
Solved.
Change the properties of list view with the following:
android:layout_alignBottom to
android:layout_below
Creating a XulRunner application for Windows I found that if binding B extends binding A. And B is being removed, then only destructor of B is called, not followed by a call of A's destructor.
Is there something wrong with my code, or this is a XulRunner bug (I haven't find matching bug in bugzilla)?
Here is an example that I tested on XulRunner 23 and 35:
main.xul:
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="main" title="My App" width="500" height="300" sizemode="normal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script><![CDATA[
function print(aString) {
document.getElementById("log_msg").value += aString + "\n";
}
function removeElementById(aId) {
document.getElementById(aId).remove();
};
function callF(aId) {
document.getElementById(aId).f();
}
]]></script>
<vbox flex="1">
<label onclick="removeElementById('A')">remove A</label>
<label onclick="removeElementById('B')">remove B</label>
<label onclick="callF('A')">Call A.f()</label>
<label onclick="callF('B')">Call B.f()</label>
<!--<binding-a id="A" style="-moz-binding: url('binding.xml#binding-a')"/>-->
<binding-b id="B" style="-moz-binding: url('binding.xml#binding-b')"/>
<textbox id="log_msg" label="Text" placeholder="placeholder" multiline="true" rows="6"/>
</vbox>
</window>
binding.xml:
<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="binding-a">
<content>
<xul:label anonid="label" value="Binding A"/>
</content>
<implementation>
<constructor><![CDATA[
var label = document.getAnonymousElementByAttribute(this, "anonid", "label");
label.value = label.value + " A.constructor";
window.print("A.constructor");
]]></constructor>
<destructor><![CDATA[
window.print("A.destructor");
]]></destructor>
<method name="f">
<body><![CDATA[
window.print("A.f");
]]></body>
</method>
</implementation>
</binding>
<binding id="binding-b" extends="#binding-a">
<content>
<xul:label anonid="label" value="Binding B"/>
</content>
<implementation>
<constructor><![CDATA[
window.print("B.constructor");
]]></constructor>
<destructor><![CDATA[
window.print("B.destructor");
]]></destructor>
</implementation>
</binding>
</bindings>
here is the solution for your problem:
bindings.xml:
<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="binding-a">
<content>
<xul:label anonid="label" value="Binding A"/>
</content>
<implementation>
<constructor><![CDATA[
var label = document.getAnonymousElementByAttribute(this, "anonid", "label");
label.value = label.value + " A.constructor";
window.print("A.constructor");
]]></constructor>
<destructor><![CDATA[
this.destruct();
]]></destructor>
<method name="f">
<body><![CDATA[
window.print("A.f");
]]></body>
</method>
<method name="destruct">
<body><![CDATA[
window.print("A.destructor");
]]></body>
</method>
</implementation>
</binding>
<binding id="binding-b" extends="#binding-a">
<content>
<xul:label anonid="label" value="Binding B"/>
</content>
<implementation>
<constructor><![CDATA[
window.print("B.constructor");
]]></constructor>
<destructor><![CDATA[
this.destruct();
]]></destructor>
<method name="destruct">
<body><![CDATA[
this.__proto__.__proto__.destruct.call(this);
window.print("B.destructor");
]]></body>
</method>
</implementation>
</binding>
</bindings>
bindings.css:
#namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
binding-a { -moz-binding: url("bindings.xml#binding-a"); }
binding-b { -moz-binding: url("bindings.xml#binding-b"); }
main.xul:
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="bindings.css" type="text/css"?>
<window id="main" title="My App" width="500" height="300" sizemode="normal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script><![CDATA[
function print(aString) {
document.getElementById("log_msg").value += aString + "\n";
}
function removeElementById(aId) {
document.getElementById(aId).remove();
};
function callF(aId) {
document.getElementById(aId).f();
}
]]></script>
<vbox flex="1">
<label onclick="removeElementById('A')">remove A</label>
<label onclick="removeElementById('B')">remove B</label>
<label onclick="callF('A')">Call A.f()</label>
<label onclick="callF('B')">Call B.f()</label>
<binding-a id="A"/>
<binding-b id="B"/>
<textbox id="log_msg" label="Text" placeholder="placeholder" multiline="true" rows="6"/>
</vbox>
</window>
I know that it is a hack in fact but it works.
I have a WebView inside a HubSection in a Hub control:
<HubSection x:Name="details_section" ...>
<!-- ... -->
<DataTemplate>
<WebView x:Name="webView" VerticalAlignment="Stretch" Margin="0" Height="300" />
</DataTemplate>
</HubSection>
The problem is that, when I make it navigate to an HTML string, it does not render the content.
// I adjusted and simplified the code
WebView wv = elem.FindName("webView") as WebView;
if (wv != null) {
wv.NavigateToString(detailTemplate);
}
Of course I debugged to see that the method actually gets called. Moreover, the LoadCompleted event gets called as well.
The problem is not due to bad HTML code as I tested with plain "<html><body>hello</body></html>".
I solved this issue by using the following extension: https://github.com/timheuer/callisto/blob/master/src/Callisto/Extensions/WebViewExtension.cs
Use:
<ns:MyPage
xmlns:ns="using:mylib"
xmlns:ext="using:WSLibrary.Extensions" ...>
<!-- ... -->
<HubSection x:Name="details_section" ...>
<!-- ... -->
<DataTemplate>
<WebView ext:WebViewExtensions.HtmlSource="{Binding MyHtmlString}" ... />
</DataTemplate>
</HubSection>
<!-- ... -->
</ns:MyPage>
Set HorizontalContentAlignment and VerticalContentAlignment of HubSection to Stretch.
<HubSection x:Name="details_section"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">