I'm having some trouble finding documentation on CLOSING a blackberry map.
My map opens, albeit with some odd marker behavior, but when you close the map it displays a clear screen.
The invoke code is quite simple, as the map request calls a new controller and within the constructor is this:
String document = "<location-document>... etc";
Invoke.invokeApplication(Invoke.APP_TYPE_MAPS, new MapsArguments( MapsArguments.ARG_LOCATION_DOCUMENT, document));
I tried to add a close line
public boolean onClose() {
UiApplication.getUiApplication().popScreen(this);
return true;
}
but this is not being applied to the map itself, but the page the map opened into. That's logical, I guess.
Maybe I'm going about this all wrong. I don't know of how to open a map another way, or if there is a way to have the close button close the map AND the containing screen.
Any help is appreciated.
I solved this with a simple one line function that fixed this problem.
public void onExposed()
{
UiApplication.getUiApplication().popScreen(this);
}
Adding that to the map controller closes the map application when the user clicks the back button. Simple as that.
Related
I am new to Titanium and in the process of making my first iOS app using Titanium but I've hit a wall with a use case.
I am trying to open an annotation on the map by clicking on a particular row on a table view. I haven't had much success with this and was unable to find any help online. Is this impossible to do or am I just doing something wrong? The following is my code:
table.addEventListener('click', function (event) {
Ti.API.info("Index of row that is clicked: "+event.index);
globals.annos[event.index].fireEvent('click');
});
'table' is my TableView with a bunch of rows and global.annos[] is my array of annotations.
My objective is to open the annotation corresponding to the index of the table row that I have clicked.
The above code doesn't achieve anything. I thought firing the 'click' event of the annotation would open the annotation but clearly I was mistaken.
Could someone help me out here? Any help would be much appreciated.
If you are using Android the click event for annotations is not supported. A more cross platform approach is to fire the click event on the MapView itself.
But if you are using iOS, your click event is not set correctly, you have to define what part of the annotation your clicking, according to the documentation :
On iOS, if the user clicks on the pin or annotation, the clicksource is one of: pin, annotation, leftButton, rightButton, leftView, rightView, title, or subtitle. If the user deselects the annotation by clicking elsewhere in the map view, clicksource is null.
And you didnt pass an event object that defines the properties of the synthesized event. Try this inside your table event listener:
var event = {
source : table,
type : 'click',
clicksource : 'pin'
};
globals.annos[event.index].fireEvent('click', event);
SOLVED! Lack of reading the docs more thoroughly!
mapview.selectAnnotation(globals.annos[event.index]);
This opens the corresponding annotation.
I have a bing map with this clip:
<my:Map.Clip>
<RectangleGeometry RadiusX="15" RadiusY="15" Rect="0,0,450,250" />
</my:Map.Clip>
The map is in a ScrollViewer somewhere at the bottom and only half of it is visible.
The problem is that when I scroll up to reveal the entire map, the part of the map that was not visible is now black.
This problem doesn't occur when I don't have a clip on my map. It's rendered correctly.
So is this a bug in the control or am I doing something wrong?
Anyone had this issue before?
Update: I have made a small sample project to demonstrate this: link. Also, while doing this I also noticed that the problem only occurs when the map control is inside a grid. If I place it straight in the ScrollViewer it works just fine.
Update: Setting a fixed height for the grid row doesn't help. Also, putting the grid + map inside a stackpanel and then inside a scrollviewer doesn't work. Any of you found anything to fix this?
You should not include a Bing Map control within a ScrollViewer or Pivot, Panorama or any other control that captures pan / scroll gestures. This will lead to a very poor user-experience because the user will not know whether the gesture is going to be captured by the map or the hosting control. What I think is happening is that when you scroll, you are not scrolling the ScrollViewer, rather, you are panning the map.
On looking at your code, this has nothing to do with the map capturing the gestures rather than the ScrollViewer, the map maintains its original clip regardless of where the user initiates their scroll.
The reason for this behaviour is that the Map Silverlight control (and the WebBrowser control too) include a native rendering component. For example the WebBrowser has a TileHost as described in this article. For this reason, various Silverlight framework effects cannot be applied to the map, for example RenderTransforms.
To solve you issue you are going to have to force the map to re-render itself when the user scrolls. To do this, I locate the ScrollViewer vertical ScrollBar using Linq-to-VisualTree, then as the user scrolls apply a very very small zoom to the map. This will cause it to re-render:
using System.Linq;
using System.Windows;
using System.Windows.Controls.Primitives;
using LinqToVisualTree;
using Microsoft.Phone.Controls;
namespace BingMapClipIssueDemo
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(ContentPanel_Loaded);
}
void ContentPanel_Loaded(object sender, RoutedEventArgs e)
{
ScrollBar verticalScroll = ContentPanel.Descendants<ScrollBar>()
.Cast<ScrollBar>()
.Where(sb => sb.Orientation == System.Windows.Controls.Orientation.Vertical)
.Single();
verticalScroll.ValueChanged += (s, e2) =>
{
map.ZoomLevel = map.ZoomLevel + 0.00001;
};
}
}
}
Just drop the code above into your example and it should work.
Try using the Static Bing Maps API instead of the Bing Map control if you don't want the user to interact with the Map
http://msdn.microsoft.com/en-us/library/ff701724.aspx
I am having a bit of a problem with an app I'm developing for BlackBerry.
I have a series of Item objects on the screen, each with a DefaultCommand tied to it. Example
below:
...
cmdBrowse = new Command(temp.id,Command.ITEM,0);
mainList.setDefaultCommand(cmdBrowse);
mainList.setItemCommandListener(icl);
...
Previously just clicking on the item with the confirm button would run the proper command. No problem there.
Then I added the handleKeyReleased method to capture the BlackBerry's back button as follows:
protected boolean handleKeyReleased(int keyCode, int gameAction) {
if(keyCode==1769472) {
/*code to deal with back button*/
return true;
} else {
return false;
}
}
Now when I click on the mainList Item with the confirm button, it brings up the list of commands first and I have to click again to actually run the command. Two clicks where it used to be one.
So, is there a way to either:
A. Keep the single click behaviour while still being able to capture the back button with handleKeyReleased
or
B. Capture the back button in a different way ?
I ended up overlooking one very simple thing. All I had to do was call the superclass's handleKeyReleased method and everything worked perfectly.
My Query is How to access Fields on the stacked screen using Screen Object ?
The exact problem is as follows:
I have one screen which has one text field (ClientName) when user clicks on that field , application will then push a new screen and it will allow the user to search in remote database using MyWebSerivces. and when user selects the one client from the search result ,i want to set the text Field on the previous screen with the text that user has selected on the current screen..
i have tried the pushScreen( new screen("text) ) and that might be the result if i want to do this operation only once but this is not the option for me since there is two more such field which will go to other screen to fetch the data from webservices . and if i every time i push new screen then after every pushscreen operation i will only get one field set with the desired text
This not a blackberry (or any specific programming language) related question. This is a question of application architecture and common sense. If one screen should change a Field of another screen, then just pass a reference of the Field to the screen that will change it.
hi i once had same problem and i did like this:
Screen1
------------------
Client Name | text field |
------------------
When user clicks on this text field or any button you push Screen2
In screen 2 when user selects a particular value then u do this.
1) take a static variable in main class say clientName.
2) set value of this variable.
3) pop active screen
UiApplication.getUiApplication().getActiveScreen();
when this code is called then u come back to Screen1
Now in screen1 a method is called
public void onExposed()
{
//here u can set the text in textfield using the static variable
invalidate(); // for repainting
}
i have found the answer to my question. the solution was there lying in my question but at first i was not able to find it.
solution was very simple
when i wrote i want to use
UiApplication.getUiApplication().getActiveScreen()
that was almost the right way and i was proceeding in right direction but the thing that i was missing was " I was not casting the screen (that i have just retrieved form the stack top ) to its type
only thing i should have done is "should have casted screen to its type.like this
UiApplication.getUiApplication().posScreen(this)
(MyScreen1) UiApplication.getUiApplication().getActiveScreen()
now i am able to access all the fields on the retrieved screen (MyScreen1)
things to keep in mind
make sure u cast the screen to its type only otherwise bb will give u resource not found error
Benifits of using screen on Stack
u can use already created screen from the stack no need to create new one
if u will create new screen it will be stacked in memory and will consume more and more memory even if its of no use ( make habit to pop the screen if it is of no use instead of leaving it on stack))
no need to create any static variable since u will be able to set all the field right away from other screen
Is there a way of doing this without using a QItemDelegate? I've been having a lot of trouble with it. For example, if I use a Delegate:
Won't have a native dialog.
I'll have to implement my own image preview,
For some reason I can't resize the window cause setGeometry doesn't work, etc etc.
QWidget *createEditor(
QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index
) const {
Q_UNUSED(option);
Q_UNUSED(index);
QFileDialog* editor = new QFileDialog(parent);
editor->setFilter("*.png");
editor->setDirectory(mResources);
editor->setGeometry(0,0,1000,500);
editor->exec() // <--- big file dialog;
return editor; // <--- tiny file dialog;
};
In practice, everything that changes the geometry of your widget goes to updateEditorGeometry function. Override it to avoid trying the original one to put your dialog within the cell of the table.
OK so the editor->setGeometry method has to go in the overridden method setEditorData of the QItemDelegate.
Does anyone know of an example code where the setItemDelegate is used to paint the thumbnail preview of the images in the QFileDialog?