Auto Scroll Vertical Field Manager - user-interface

I have developed a BlackBerry Application with a simple chat feature. The chat messages appear inside a Vertical Field Manager (VFM) when the user clicks Send. The user can sent multiple messages. Every new message sent appears below the older message. This way, the size of the Vertical Field Manager keeps increasing. I have created a scroll-able VFM and so the user can view the latest message sent by scrolling down. Is it possible to auto-scroll to the bottom of the VFM when a message is sent so that the focus is set on the last message?
I have tried calling vfm.setVerticalScroll(int y); as well as LabelField chat1 = new LabelField( "Hi", Field.FIELD_LEFT|Field.FOCUSABLE); but this is not helping. Please guide.
vr2 = Vertical Field Manager
chat1 = Chat message added to the VFM
EDIT: I came across this link on StackOverFlow and applied changes in my code as follows:
vr2.setVerticalScroll(vr2.getVirtualHeight());
LabelField chat1 = new LabelField( "Hi", Field.FIELD_LEFT)
{
protected void applyTheme(Graphics g, boolean arg1)
{
g.setColor(Color.DEEPSKYBLUE);
super.applyTheme(g, arg1);
}
};
Font myFont = Font.getDefault().derive(Font.BOLD, 8, Ui.UNITS_pt);
chat1.setFont(myFont);
chat1.setBorder( leftBorder );
chat1.setMargin( 0, 0, -15, 0);
vr2.setBorder(bdr);
vr2.add(chat1);
Field f;
int i = vr2.getFieldCount();
f = vr2.getField(i-1); //getFieldCount, gets total number of fields
f.setFocus();
This has brought me very close to the solution I am looking for. The VFM is scrolling below fine. However, instead of positioning to the last message in the VFM, it scrolls to the second last message every time. Why is this so? It should scroll to the last message in the VFM; right at the bottom of VFM.

I finally managed to get this solved. I will share my answer in case there are others out there stuck with such an issue. While the edit in my question above helped me come closer to the solution, I figured out the mistake was in not calling vr2.setVerticalScroll(vr2.getVirtualHeight()); at the right place.
For details, please check this question on stackoverflow and this on blackberry support forums. The solution is as follows:
LabelField chat1 = new LabelField( "Hi", Field.FIELD_LEFT)
{
protected void applyTheme(Graphics g, boolean arg1)
{
g.setColor(Color.DEEPSKYBLUE);
super.applyTheme(g, arg1);
}
};
Font myFont = Font.getDefault().derive(Font.BOLD, 8, Ui.UNITS_pt);
chat1.setFont(myFont);
chat1.setBorder( leftBorder );
chat1.setMargin( 0, 0, -15, 0);
vr2.setBorder(bdr);
vr2.setVerticalScroll(vr2.getVirtualHeight()); //scrolls to the bottom of the vertical field manager
vr2.add(chat1);
Field f;
int i = vr2.getFieldCount();
f = vr2.getField(i-1); //getFieldCount, gets total number of fields
f.setFocus(); //sets focus on the newly added field

Related

How does location cache works?

I have an application that gets the GPS location of the devices every time the user fills-up the form. My problem is capturing the GPS location takes too long. It takes about 40 seconds to 60 seconds before the GPS has been captured. I am using jamesmontemagno's Geolocator plugin.
GPS Parameters:
Accuracy: 100 meters
Timeout: 1 minute
Here is my code that I am using right now:
var defaultgpsaccuracy = Convert.ToDouble(Preferences.Get("gpsaccuracy", String.Empty, "private_prefs"));
var defaultgpstimeout = Convert.ToDouble(Preferences.Get("gpstimeout", String.Empty, "private_prefs"));
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = defaultgpsaccuracy;
position = await locator.GetLastKnownLocationAsync();
if (position != null)
{
string location = position.Latitude + "," + position.Longitude;
lblStartLocation.Text = location;
}
else
{
position = await locator.GetPositionAsync(TimeSpan.FromMinutes(defaultgpstimeout), null, false);
string location = position.Latitude + "," + position.Longitude;
lblStartLocation.Text = location;
}
These are my questions:
I used locator.GetLastKnownLocationAsync(); how long before the location cache refreshes?
And does the last known location refreshes when there is a change of location
And does the location refreshes when the devices is outside the accuracy range for example the accuracy is 100 meters does the location cache refresh when the device is outside the 100 meters range of the last know location?
I would highly recommend looking through the documentation for that particular plugin, James Montemagno is a well known and respected developer employed my Microsoft working on the Xamarin framework, so his plugins, extensions and toolkits tend to be pretty highly optimised for use in cross-platform applications.
Looking at the documentation it's clear that trying to get the last 'known' location looks at an internally cached location data set and is not necessarily optimized for near real-time queries. However it can be used to reduce the number of actual location queries you have to do within your app.
The full snippet from the linked documentation is as follows:
public async Task<Position> GetCurrentLocation()
{
public static async Task<Position> GetCurrentPosition()
{
Position position = null;
try
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 100;
position = await locator.GetLastKnownLocationAsync();
if (position != null)
{
//got a cahched position, so let's use it.
return position;
}
if (!locator.IsGeolocationAvailable || !locator.IsGeolocationEnabled)
{
//not available or enabled
return null;
}
position = await locator.GetPositionAsync(TimeSpan.FromSeconds(20), null, true);
}
catch (Exception ex)
{
Debug.WriteLine("Unable to get location: " + ex);
}
if (position == null)
return null;
var output = string.Format("Time: {0} \nLat: {1} \nLong: {2} \nAltitude: {3} \nAltitude Accuracy: {4} \nAccuracy: {5} \nHeading: {6} \nSpeed: {7}",
position.Timestamp, position.Latitude, position.Longitude,
position.Altitude, position.AltitudeAccuracy, position.Accuracy, position.Heading, position.Speed);
Debug.WriteLine(output);
return position;
}
}
This method is designed to follow a hierarchical patter of location retrieval, it starts with the last 'known' position and queries if necessary, you could also take this a step further and add in a timeout to checking for a cached location if you wanted to.
In regards to how often this data is refreshed, I'd refer you to the documentation section titled 'Background Updates'
James talks about a driving app as an example of how this works. The refresh is handled differently across Android and iOS but here's the snippet regarding Android:
For this you will want to integrate a foreground service that
subscribes to location changes and the user interface binds to. Please
read through the Xamarin.Android Services documentation
In the code example he uses he shows you how to create a 'listener' that will check for changes to location periodically. This might be a better fit for what you're trying to do depending on the purpose of your application.

Can someone explain what are iTextEvents in ItextSharp?

Can someone explain what are iTextEvents in ItextSharp..
I have found a bunch of codes with its use but i dont get how they works..
Im asking you if anyone can explain me these:
OnOpenDocument
OnEndPage
OnCloseDocument
If you are looking to start using iText, then your question is obsolete. You are referring to a concept that was used in versions 5 and earlier of iText for .NET (we abandoned the name iTextSharp a long time ago). If you want to start using iText for .NET, you should start with version 7, not with iText 5 or earlier, because we stopped development on those versions. Any release we make now is nothing more than a maintenance release (maintenance releases don't contain new functionality, they have bug fixes that are meant for paying users who can't migrate to iText 7 immediately).
The name page events was misleading because those events were initially used to allow developers to execute code when a new page was created or finalized, but as the code grew organically, we also started to use the page event functionality for other things, such as: to add special behavior of a Chunk (OnGenericTag()) or to execute code before or after adding a Paragraph. That was an example of bad design.
We fixed this bad design in iText 7, where we introduced renderers and event handlers. See chapter 3 of the jump-start tutorial, entitled Using renderers and event handlers.
In iText 7, we can create an event handler such as:
protected internal class MyEventHandler : IEventHandler {
public virtual void HandleEvent(Event #event) {
PdfDocumentEvent docEvent = (PdfDocumentEvent)#event;
PdfDocument pdfDoc = docEvent.GetDocument();
PdfPage page = docEvent.GetPage();
int pageNumber = pdfDoc.GetPageNumber(page);
Rectangle pageSize = page.GetPageSize();
PdfCanvas pdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdfDoc);
//Set background
Color limeColor = new DeviceCmyk(0.208f, 0, 0.584f, 0);
Color blueColor = new DeviceCmyk(0.445f, 0.0546f, 0, 0.0667f);
pdfCanvas.SaveState()
.SetFillColor(pageNumber % 2 == 1 ? limeColor : blueColor)
.Rectangle(pageSize.GetLeft(), pageSize.GetBottom(), pageSize.GetWidth(), pageSize.GetHeight())
.Fill()
.RestoreState();
//Add header and footer
pdfCanvas.BeginText()
.SetFontAndSize(C03E03_UFO.helvetica, 9)
.MoveText(pageSize.GetWidth() / 2 - 60, pageSize.GetTop() - 20)
.ShowText("THE TRUTH IS OUT THERE")
.MoveText(60, -pageSize.GetTop() + 30)
.ShowText(pageNumber.ToString())
.EndText();
//Add watermark
iText.Layout.Canvas canvas = new iText.Layout.Canvas(pdfCanvas, pdfDoc, page.GetPageSize());
canvas.SetProperty(Property.FONT_COLOR, Color.WHITE);
canvas.SetProperty(Property.FONT_SIZE, 60);
canvas.SetProperty(Property.FONT, C03E03_UFO.helveticaBold);
canvas.ShowTextAligned(new Paragraph("CONFIDENTIAL"), 298, 421, pdfDoc.GetPageNumber(page), TextAlignment.
CENTER, VerticalAlignment.MIDDLE, 45);
pdfCanvas.Release();
}
}
The event handler is introduced in the code like this:
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
pdf.AddEventHandler(PdfDocumentEvent.END_PAGE, new C03E03_UFO.MyEventHandler(this));
// Initialize document
Document document = new Document(pdf);
Paragraph p = new Paragraph("List of reported UFO sightings in 20th century").SetTextAlignment(TextAlignment
.CENTER).SetFont(helveticaBold).SetFontSize(14);
document.Add(p);
Table table = new Table(new float[] { 3, 5, 7, 4 });
table.SetWidth(UnitValue.CreatePercentValue(100));
StreamReader sr = File.OpenText(DATA);
String line = sr.ReadLine();
Process(table, line, helveticaBold, true);
while ((line = sr.ReadLine()) != null) {
Process(table, line, helvetica, false);
}
sr.Close();
document.Add(table);
document.Close();
This code adds a background, a watermark, a header, and a footer, as is shown in this figure:
Page events in "iTextSharp" had a similar purpose, but you shouldn't use them anymore. They are outdated. You should use iText 7 instead.
If you posted your question out of historical curiosity, you should search old questions on Stack Overflow, such as:
How can I add an image to all pages of my PDF?
itextsharp: How to generate a report with dynamic header in PDF using itextsharp?
Change the color of pdf pages alternatively using iText pdf in java
How to introduce multiple PdfPageEventHelper instances?
...

New Tile with special start of application in WP7

I've got question. I have application which is a phone book. I would like to create Tile (in Windows Phone main screen) which'll call that number after I click Tile on main screen.
Is that possible? What should I do to make something like that? I can create custom Tile or maybe I should create some method after my application start?
Create the live tile with something like the following code:
string number = "000 - 000 000";
ShellTile tile = ShellTile.ActiveTiles.FirstOrDefault(t => t.NavigationUri.ToString().Contains("phone=" + number));
if (tile == null)
{
StandardTileData tileData = new StandardTileData();
tileData.Title = "Call " + number;
ShellTile.Create(new Uri("/MainPage.xaml?phone=" + number, UriKind.Relative), tileData);
}
And then override the OnNavigatedTo in MainPage.xaml, and add the following code:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (NavigationContext.QueryString.ContainsKey("phone"))
{
string number = NavigationContext.QueryString["phone"];
PhoneCallTask task = new PhoneCallTask();
task.PhoneNumber = number;
task.Show();
}
base.OnNavigatedTo(e);
}
If you have not done it yet, you also need to add the "ID_CAP_PHONEDIALER" capability in the WMAppManifest.xml file, or you will get an exception when calling task.Show(); above.
Now you got a live tile that when clicked will launch the application and call the number (The user must still confirm it in a dialog though, and that is something you can't disable)
Have you tried a flip tile and the using something like this:
http://blog.ecofic.com/?p=406
Write the number to isolated storage then when they click the tile you read the isolated storage and call the number.
You can also use the Mangopollo library from CodePlex to create a secondary live tile: http://mangopollo.codeplex.com/

Custom live tile rendering issue on Windows Phone (7/8)

In my Windows Phone app's main page, users can click a button to do some stuff and that will trigger the live tile to update.
The problem I am having is, if the user clicks the button and then hit the phone's Back button really quickly, the live tile sometimes will not render properly. This issue rarely happens, but it does happen and when it happens it just looks bad...
The way I implement the live tile is, create a user control that looks exactly the same as the live tile and then save it to isolated storage. Then retrieve it and store it in a FliptileData object. Finally I call the Update method on the ShellTile. Please see the following piece of code to demonstrate the process.
// the function that saves the user control to isolated storage
public Uri SaveJpegToIsolatedStorage(FrameworkElement tile, string suffix, int tileWidth = 336, int tileHeight = 336)
{
var bmp = new WriteableBitmap(tileWidth, tileHeight);
// Force the content to layout itself properly
tile.Measure(new Size(tileWidth, tileHeight));
tile.Arrange(new Rect(0, 0, tileWidth, tileHeight));
bmp.Render(tile, null);
bmp.Invalidate();
// Obtain the virtual store for the application
IsolatedStorageFile myStore = IsolatedStorageFile.GetUserStoreForApplication();
using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(IsolatedStorageFileName + suffix, FileMode.Create, myStore))
{
try
{
bmp.SaveJpeg(fileStream, tileWidth, tileHeight, 0, 100);
}
catch (Exception)
{
return null;
}
}
return new Uri("isostore:/" + IsolatedStorageFileName + suffix, UriKind.Absolute);
}
// save the user control to isolated storage and prepare the FlipTileData object
wideFrontTileImage = SaveJpegToIsolatedStorage((UserControl)this.WideFrontTile, "_wide_front", 691);
var flipTileData = new FlipTileData();
flipTileData.WideBackgroundImage = wideFrontTileImage;
return flipTileData;
// update the live tile
var shellTile = ShellTile.ActiveTiles.FirstOrDefault();
shellTile.Update(customTile.GetFlipTileData(data.UndoneMemosCount == "0" && data.TotalMemosCount == "0"));
I think the reason that's causing all this is, when the user clicks the Back button too quickly, the OS terminates all the processes running within the app and the rendering wasn't done at that time. I'm thinking if there's a way to know when the rendering is finished, so I can cancel the Back button and wait until it's finished then manually exit the app. But I simply dunno how...
Any help on this one will be greatly appreciated!
I have ran into similar issue in my WP8 app. The problem was that I was updating my Tile in ApplicationDeactivated event handler. The thing is you should not update your tiles there, but rather in your MainPage.OnNavigatedFrom override. Once I changed this, it works just fine.

windows phone c# check for valid url and replace foreach item in list

I am getting a list of objects in Windows Phone, and show them in a listbox with databinding.
some image urls are not valid, so after every object is added in the list, i run the following code to check and replace, if not valid
private void CheckLinkUrl(Person p)
{
Uri filePath = new Uri(p.img_url);
string correct = p.img_url;
HttpWebRequest fileRequest = HttpWebRequest.CreateHttp(filePath);
fileRequest.Method = "HEAD";
fileRequest.BeginGetResponse(result =>
{
HttpWebRequest resultInfo = (HttpWebRequest)result.AsyncState;
HttpWebResponse response;
try
{
response = (HttpWebResponse)resultInfo.EndGetResponse(result);
}
catch (Exception e)
{
p.img_url = "http://somethingelse.com/image.jpg";
}
}, fileRequest);
}
the problem is that it is very slow, it takes sometimes 2 minutes+ to load every image (although the UI remains responsive, and everything else is displayed immediately in the listbox, apart from the images)
am I doing something wrong? can i get it to run faster?
EDIT:
I tried using the imagefailed event and replace the link, no improvement at the speed of loading the pics
What I have done to avoid this problem in my application is, I have loaded the items with a default Image, The image source is binded to a property in my result item of type ImageSource. By default it returns the default image. After processing or download completion the imagesource value changes to the new Image triggering the NotifyPropertyChanged event and hence it is automatically reflected on the UI. I hope it helps you.

Resources