I am designing a page in flex and I have a one image. Specific text should be shown when user hovers mouse to the image. Here is my actionScript code that I wrote but it is not working (it is not showing text on mouseOver event:(
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="100" minHeight="100">
<fx:Script>
private var helpText:String = "Some Text."
private function helpIconEvent(e:MouseEvent):void{
if(e.type == "mouseOver"){
e.currentTarget.helpText.visible = true;
}
}
private function addEventToHelpIcon():void {
helpIcon.addEventListener(MouseEvent.MOUSE_OVER, helpIconEvent);
}
</fx:Script>
<mx:Image id="helpIcon" x="270" y="187" width="50" height="50" mouseOver="addEventToHelpIcon"
source="source_path"/>
Any help/insight will be highly appreciated.
Thanks.
There are several issues:
You are not adding the mouse over listener correctly. You are actually adding two event listeners, one in MXML and then when that event happens you add the second one. Just use the MXML listener (see below).
In function that runs when the mouse over happens, you are trying to set the visible property on a String object. A String by itself will not display anything. You can display the String with a Label object, in a tool-tip, or some other GUI object. You need to figure out the right GUI object to use and pass the text to that object.
Here's a very simple example:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="100" minHeight="100">
<fx:Script>
private function onMouseOver():void {
helpLabel.visible=true;
}
private function onMouseOut():void {
helpLabel.visible=false;
}
</fx:Script>
<s:Image id="helpIcon" x="270" y="187"
width="50" height="50"
mouseOver="onMouseOver()" mouseOut="onMouseOut()"
source="source_path"/>
<!-- note the mouse event handlers are so simple in this case, you can also do them in line -->
<s:Image id="alternateMethod" mouseOver="helpLabel.visible=true;"
mouseOut="helpLabel.visible=false;" />
<s:Label id="helpLabel" x="100" y="100" visible="false" text="Some Text."/>
</s:Application>
It think your code should be more like this, but I'm not used to flex so bear with me if I'm wrong.
private function foo(e:MouseEvent):void {
if(e.type == MouseEvent.ROLL_OVER)
//Do stuff...
}
Related
In C# Xamarin Android projects, I am trying to create a custom compound component to select a month. This extends LinearLayout.
I expect to re-use it (and keep my main project more tidy), so I have 2 projects - my main/parent project, containing my Activity and multiple Fragments; and a simple Android project for my component.
When I run the component project directly using its own Activity, it works as expected, but when I reference it from my main project, my FindViewById return null.
I can see that this and context are from the main project - and I would like to understand what I've done wrong or what I need to add so that it finds the component's layout and controls to inflate?
Main view (Ui.DateScrollPicker.Droid is my component's namespace and ScrollMonthPicker my class):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:paddingRight="10dp">
.......
<ui.datescrollpicker.droid.ScrollMonthPicker
android:id="#+id/my_scroll_month_picker"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Referenced from a Android.Support.V4.App.Fragment in the override View OnCreateView method:
scrollMonthPicker = view.FindViewById<ScrollMonthPicker>(Resource.Id.scroll_month_picker);
scrollMonthPicker.DateChanged += DatePicker_Changed;
By extending LinearLayout, I am implementing 2 constructors, including, ScrollMonthPicker(Context context, IAttributeSet attrs) : base(context, attrs, 0) which is called, and goes off to inflate my component's layout.
Component view (scroll_month_layout.axml):
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/month_current_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Month" />
<TextView
android:id="#+id/year_current_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Year" />
<android.support.v7.widget.RecyclerView
android:id="#+id/month_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</merge>
ScrollMonthPicker constructor:
public ScrollMonthPicker(Context context, IAttributeSet attrs)
: base(context, attrs, 0)
{
InflateLayout(context, attrs);
}
ScrollMonthPicker inflating view:
private void InflateLayout(Context context, IAttributeSet attrs)
{
var inflater = LayoutInflater.FromContext(this.Context);
inflater.Inflate(Resource.Layout.scroll_month_layout, this);
monthCurrentText = FindViewById<TextView>(Resource.Id.month_current_text);
yearCurrentText = FindViewById<TextView>(Resource.Id.year_current_text);
monthRecyclerView = FindViewById<RecyclerView>(Resource.Id.month_recycler_view);
monthRecyclerView.HasFixedSize = true;
......
}
The component works fine when called from 'its own' Activity, but all FindViewById are null (monthCurrentText, yearCurrentText and monthRecyclerView) when referenced by the fragment in the main project.
If I wait for the exception to be thrown in the main fragment from monthRecyclerView.HasFixedSize, I do not get a null reference exception, but this one:
Unhandled Exception:
System.NotSupportedException: Could not activate JNI Handle 0x7fff30d40b00 (key_handle 0x8f4c53e) of Java type 'md53fd9f663a5e8ddcd0a5da1b57d05fd99/ScrollMonthPicker' as managed type 'Ui.DateScrollPicker.Droid.ScrollMonthPicker'.
How do I make it populate as expected by referencing from a separate project??
Many thanks.
It seems your both projects are the android project. You could not use another android project code in one project. I think you need to create your CustomComponent project as a library.
I am working on creating a new Custom Component and unable to bind a controller's property to the SelectedItem annotation property of my custom component. My idea is that any one who passes my Custom component SelectedItem annotation, I should be able to retrieve it in my component and assign it myself to the ListBox's SelectedItem property. This will give flexibility to the users of my component to not worry about the internals and the component will be re-usable.
Problem is that I am not able to get/set the Controller value in my custom component. I get NULL. Can someone please help me resolve this issue or point me to the right direction? Here is the code:
<bandbox id="filterDropdownBandBox" instant="true" readonly="false">
<bandpopup id="filterDropdownBandPopup" style="max-height:250px;overflow-x:hidden">
<listbox id="listBox" hflex="1" rows="0" >
<template name="model">
<listitem>
<listcell label="${each.label}" />
</listitem>
</template>
</listbox>
</bandpopup>
public class FilterDropdown extends Div implements IdSpace {
#Wire
private Listbox listBox;
#Wire
private Bandpopup filterDropdownBandPopup;
#Wire
private Bandbox filterDropdownBandBox;
private ListModelList<GenericNameValuePair> lbModel;
public FilterDropdown() {
Executions.createComponents("/filterDropdown.zul", this, null);
Selectors.wireComponents(this, this, false);
Selectors.wireEventListeners(this, this);
}
public void setSelectedItem(Listitem l) // getting NULL here
{
l.setParent(listBox);
listBox.setSelectedItem(l);
}
public void saveSelection() {
listBox.getSelectedItem();
}
public Listitem getSelectedItem() {
return listBox.getSelectedItem();
}
}
This is how I added this component to lang-addon.xml file
<component>
<component-name>filter-dropdown</component-name>
<extends>div</extends>
<component-class>com.components.FilterDropdown</component-class>
<annotation>
<annotation-name>DDBIND</annotation-name>
<property-name>selectedItem</property-name>
<attribute>
<attribute-name>ACCESS</attribute-name>
<attribute-value>both</attribute-value>
</attribute>
</annotation>
</component>
And this is how I am using my custom component in other ZUL files
<filter-dropdown id="filterProjDropdown" selectedItem="#DDBIND{XYZCtrl.bean.propbean.actualProp}"/>
First of all, keep to the normal annotation like #load(), #save() or #bind()`.
Now, mine first suggestion is to throw your zul away.
Implement the AfterCompose interface in your component and add all the items there with a renderer.
It makes it easier for anyone to change that component and it will be more performent.
Secondly, use the correct annotation in your class :
#ComponentAnnotation({"selectedItem:#ZKBIND(ACCESS=both,SAVE_EVENT=onSelect)"})
Like this your lang-addon.xml should look like :
<component>
<component-name>filter-dropdown</component-name>
<extends>div</extends>
<component-class>com.components.FilterDropdown</component-class>
</component>
And as last :
You need to inform the binder that there was a change in the selectedItems :
Events.postEvent("onSelect", FilterDropdown.this, selectedItems);
You should handle this in an eventlistener attached to the bandbox.
If you want an advanced working component code including in how to export it to a separate jar, please check out mine github project.
I am writing an app with Xamarin.Android and MvvmCross. I am using fragments and have a "content container" design where I show the fragments in my content_frame view:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
</FrameLayout>
Everything works, and I can navigate through my app by showing/closing the fragments in my content_frame, but when I close the last fragment, instead of closing the app, it shows a blank screen instead. I reckon I can fix this in my MvxAppCompatViewPresenter class but I don't know how? I currently don't have anything in my view presenter:
public class ViewPresenter : MvxAppCompatViewPresenter
{
public ViewPresenter(IEnumerable<Assembly> androidViewAssemblies) : base(androidViewAssemblies)
{
}
public override void Show(MvxViewModelRequest request)
{
base.Show(request);
}
public override void Close(IMvxViewModel viewModel)
{
base.Close(viewModel);
}
}
Here is the first fragment:
[MvxFragmentPresentation(typeof(LoginViewModel), Resource.Id.content_frame, true)]
[Register("myapp.droid.fragments.LoginSelectionFragment")]
public class LoginSelectionFragment : BaseFragment<LoginSelectionViewModel>
{
protected override int FragmentId => Resource.Layout.fragment_login_selection;
}
One of the approaches you can use, is to not add the fragments that are starting fragments to the backstack by setting the MvxFragmentPresentation property AddToBackStack to false (false is also the default if no parameter is passed).
The idea there is that for the first fragment you would rely on the activity being added to the backstack. Essentially, the first fragment and the activity could then be considered the same with respect to the backstack, eliminating the blank screen.
However, this would only work if the starting fragments do not need to be added to the backstack, with in the same activity context, later in the navigational flow. In future versions of MvvmCross you would easily be able to overcome this limitation via the updated IMvxOverridePresentationAttribute.
I have a list of the following class:
public class Set {
public string IconUrl { get; set; }
}
This list is bound to a ListView:
<ListView ItemsSource="{Binding Sets}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Image Source="{Binding IconUrl}" />
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When the view loads and the user starts scrolling, the cells are reused and the Image briefly shows the previous image before the new image is downloaded and rendered.
Is there a way to prevent this kind of behavior without disabling RecycleElement?
I haven't tried this but on ViewCell you have Disappearing and Appearing events that you can hook into.
You may want to look at releasing the image source on the Disappearing event handler, but sometimes this can occur sometime later I think from recollection, so you may also want to try releasing the image on the Appearing event handler that hopefully will be executed prior to the display on the screen?
We have solved this by manually setting the Image source to null to force the render of the new images. we achieve this by using OnBindingContextChanged Event of the ListView. Hope this helps.
Edited (Added code below):
We have something like this:
public class PeopleCell : ViewCell
{...
Image profileImage;
public PeopleCell()
{
profileImage = new Image
{
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
BackgroundColor = Color.FromHex("f5f5f5"),
Source = ImageSource.FromFile("profile_blankimage"),
};...
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
people = BindingContext as CustomerViewModel;
if(people.Customer.Avatar != null)
profileImage.Source = ImageSource.FromUri(new Uri(people.Customer.Avatar.Url));
Is it possible to add a layout to the MvxSplashScreenActivity? I have overiden the OnViewModelSet like in all the other activities and placed the following code:
protected override void OnViewModelSet()
{
base.OnViewModelSet ();
SetContentView (Resource.Layout.SplashScreen);
}
The layout I am trying to load is:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:minWidth="25px"
android:minHeight="25px">
<ImageView
android:src="#drawable/applogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView1"
android:layout_centerInParent="true" /></RelativeLayout>
and I am getting the following exception:
Cirrious.CrossCore.Exceptions.MvxException: Failed to resolve type
Cirrious.MvvmCross.Binding.BindingContext.IMvxBindingContextStack`1[[Cirrious.MvvmCross.Binding.Droid.BindingContext.IMvxAndroidBindingContext,
Cirrious.MvvmCross.Binding.Droid, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null]]
I cant seem to find anything online regarding the mvvmcross splash screen..
Ahy Ideas?
You can't use a databound layout within the splashscreen - the splashscreen is displayed before mvvmcross is fully started.
However, for a simple layout, you do pass a resource Id down to the base class constructor:
public class SplashScreen : MvxSplashScreenActivity
{
public SplashScreen()
: base(Resource.Layout.SplashScreen)
{
}
}
Further - to avoid black start screens - most people use a theme to specify a whole screen image in their splashscreen - see the 'standard' splash screen supplied by nuget - https://github.com/slodge/MvvmCross/blob/v3/nuspec/DroidContent/SplashScreen.cs.pp
Ensure Initialize Setup before calling OnCreate.
protected override void OnCreate(Bundle bundle)
{
var setupSingleton = MvxAndroidSetupSingleton.EnsureSingletonAvailable(this);
setupSingleton.EnsureInitialized();
base.OnCreate(bundle);
}