Changing part of the screen in when button clicks in Blackberry - blackberry

I have three buttons in on screen,when i click each button it navigate to corresponding button contends.i need to change part of the screen without changing whole screen.Can anyone give an idea about this.
Thank You

Besides Ray's answer I think you should look to replace method:
vfm.replace(oldField, newField);
On a thread:
public void run() { //this is your Runnable for your Thread
//do stuff
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
vfm.replace(oldField, newField);
}
});}

Generally speaking if you modify a manager you should invalidate that manager which is the way to tell the device a repaint is required.
http://www.blackberry.com/developers/docs/4.0.2api/net/rim/device/api/ui/Manager.html#invalidate()
Edit: information about adding to/deleting from VerticalFieldManager
The documentation specific to a VerticalFieldManager is here:
http://www.blackberry.com/developers/docs/3.7api/net/rim/device/api/ui/container/VerticalFieldManager.html
The methods you should use to update its child fields are all inherited from the Manager class. You can also see a list of other subclasses here:
http://www.blackberry.com/developers/docs/3.7api/net/rim/device/api/ui/Manager.html
E.g. Check the methods for delete, deleteAll, deleteRange, insert, add.

Related

No ItemSelected call in my UICollectionView?

So I'm trying out Xamarin Forms, and I made a control that has a renderer that outputs a UICollectionView. The collection view in question was ported from an Objective C version. In the Objective C version, I implemented collectionView:didSelectItemAtIndexPath: and when I clicked on the item that method was called. But in the Xamarin version, this does not seem to be the case and the ItemSelected method is not called. I've tried using both the Delegate and WeakDelegate versions to no avail. I made sure AllowsSelection is true.
I tried adding a UIButton to the cell, and was able to get a log entry from its TouchUpInside handler, so I don't think it's a matter of another view on top stealing the touches. Pans and such work. And in Simulator I had it highlight the drawn layers and didn't notice anything fishy.
Anyone have any ideas of stuff to try? Thanks.
I don't know if this can help you, but i get the same problem using the GridView control of the Xamarin.Forms.Labs.
I see that in delegate, the method "ItemSelected" is not called, but is call the "ItemHighlighted" method. So I used this to make the GridView selectitem works.
I hope this can be helpfull. :)
Double check that you have assigned the UICollectionViewSource object to ColelctionView.Source and NOT ColelctionView.DataSource by mistake
I did eventually fix this. What was happening is that Xamarin.Forms adds a gesture recognizer to the root of the page which cancels touches in the page. This works well in general, but does not work well in the case of UICollectionViews where it interferes with the UICollectionView calling ItemSelected.
What I ended up doing was to create this custom renderer:
public class IosTapFixPageRenderer : PageRenderer {
public override void ViewDidLoad()
{
base.ViewDidLoad();
foreach (var g in View.GestureRecognizers) {
g.CancelsTouchesInView = false;
}
}
}
Then I assigned this as the renderer for problem pages containing UICollectionViews using the usual attribute method:
[assembly: ExportRenderer(typeof(CalendarPage), typeof(IosTapFixPageRenderer))]

Blackberry java, refreshing custom animated banner

I want to show a .gif banner in the top of my app. I'm using this code to show the animated field BB Animated GIF Field. The issue is that I want to refresh this banner every minute. I've tried so many things:
create a new object, but this doesn't change the banner.
create a new animated field and try to replace it....IllegalArgumentException. (I'm trying to change that from inside a Thread, using invokeLater()...I've used invokeAndWait() too)
remove this animated field and put a new one (from the invokeLater() or invokeAndWait() -> IllegalException)
setting a bitmap to this field. The first animate doesn't show and I can see an image from the other banner but it isn't animated.
Any ideas?
If you need to see some code, I will try to post it tomorrow.
If you're using a minimum BlackBerry OS of 6.0 (or above), the BitmapField class directly supports animated gifs.
If you need to support a lower OS version, then you just need to add a method to your AnimatedGIFField class to swap out the old image, and use a new one:
public void setImage(EncodedImage image) {
// Call BitmapField#setImage()
super.setImage(image);
// Store the image and its dimensions.
_image = image;
_width = image.getWidth();
_height = image.getHeight();
_currentFrame = 0;
// Stop the previous thread.
_animatorThread.stop();
// Start a new animation thread.
_animatorThread = new AnimatorThread(this);
_animatorThread.start();
}
Note that this is a UI operation. So, if you want to update the image from a background thread, make sure to wrap it with a call that puts it on the UI thread. For example:
final EncodedImage eImage = EncodedImage.getEncodedImageResource("img/banner.gif");
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
_animatedBanner.setImage(eImage);
}
});
Update: I also notice that the way the AnimatedGIFField class works is not really good multi-threading practice (for stopping the thread). If you really want to make the code better, you could implement this solution, or
use the technique I show in this answer.
Read more about this here.

Update UIImageView with new UIImage

*UPDATE***
My first description (now deleted) was'nt the real situation. It is a simplified version of the problem.
The Complete situation:
I want to change the UIImage within a UIImageView with a picture which I select from the iphone photo gallery.
For this I used a MediaPicker (part of the Xamarin library).
When I click a button, the Mediapicker will be created. Then I call a function to take a picture from the photo gallery. This methods expects 2 arguments. The Mediapicker and a callback function. --> PictureFromGallery(mediaPicker, CallbackPhotoMade);
This callback function will be trigger after a user selected a picture in the photo library to upload.
Within this callback function I want to change the UIImage of the UIImageView.
void CallbackPhotoMade(MediaFile obj)
{
imageviewPhoto1.Image = UIImage.FromFile("Images/image2.PNG");
//To test I just use a file from a folder in my project
}
When I breakpoint the above function (CallbackPhotoMade) and I put my mouse at the text ".Image =", the following message apears:
MonoTouch.UIKit.UIKitThreadAccessException: UIKit Consistency error: you are calling an UIKit method that can only be invoked from the UI thread
I think this is the problem why the UIImage within the UIImageView doesn't change.
Does anyone knows how to solve this?
*UPDATE2***
I read in another topic that this could be solved by setting CheckForIllegalCrossThreadCalls to false like:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
UIApplication.CheckForIllegalCrossThreadCalls = false;
}
Unfortunately the image still doesn't change.
Although, the specific error dissapeared.
Try this one:
void CallbackPhotoMade(MediaFile obj)
{
InvokeOnMainThread(() => {
imageviewPhoto1.Image = UIImage.FromFile("Images/image2.PNG");
});
//To test I just use a file from a folder in my project
}
The setting you made, just disables checking, but does not prevent the exception.
The callback is done on another thread (async). And you can/should only update the user interface on/from the main thread. InvokeOnMainThread() makes your code execute on the main thread, which is just what you need.
Ideally the code should run.
Check whether imageviewPhoto1 is nill or not in changeImage method.
If nill then your object is probably released.
If not nill then try writing [self.view setNeedsDisplay]; after setting image , just to see redrawing view can update it or not. Or try whether view is present by setting imageviewPhoto1's background color to something else.

What's the difference between Screen.invalidate() and Screen.invalidateLayout()

void invalidate()
Invalidates the entire screen.
void invalidateLayout()
Invalidates this screen's layout (including all controlled fields).
The javadoc doesn't help much. Could you tell me why do we need invalidateLayout()?
Depending on how you build your UI, you may be interested in invalidating, or updating layout, when you want the display to change.
If you have a UI that's composed of standard Field objects, like TextField, or ButtonField, or BrowserField, without much customization, then the work of defining how the UI looks is mostly in how those fields are laid out. Layout refers to setting the size of fields, and their position.
Sometimes, you'll have a UI where you need to deal at a lower level. For example, you may do some custom painting, which involves drawing lines, filling areas, drawing gradients, etc. This work is normally done in a Field object's paint() method. Sometimes, you also have drawing code in other places like drawFocus() or paintBackground().
If you want to trigger repainting, which calls your custom paint() method, then you want to use invalidate() to make that happen.
If you want to trigger a new layout, which arranges child fields with certain sizes, or positions, then invalidateLayout() can be used for that.
However, I will note that invalidateLayout() is a method in the Screen class. If you use a RIM Screen subclass, like MainScreen or FullScreen, then they come with their own top level delegate Manager objects. I believe that calling Screen.invalidateLayout() will trigger the sublayout() method on that built-in Manager to be called. That may not be what you really want.
Unless you implement your own Screen subclass like this:
public class MyScreen extends Screen {
public MyScreen() {
super(new MyCustomManager());
}
}
you probably aren't implementing the code (including sublayout()) for that delegate manager yourself.
I have found that when I want to force sublayout() to be called again, I trigger that with the updateLayout() method, not invalidateLayout(). Also, as opposed to invalidateLayout(), which is a method of the Screen, updateLayout is available for all Manager and Field classes, so you can choose just the specific part of the UI element tree that you want to refresh. But, that's just my experience.
Here's some comments on the BlackBerry forums on this topic

How do you manage the pushing of screens in your BlackBerry app?

I was wondering how the people who develop for here BlackBerry go about managing the screens in their app. The most common practice (and the one I'm using) seems to be just to instantiate and push the new screen from the current one. The other option I've seen is using actions in the Main Application class to do the transitions. How do you guys manage?
We have a ScreenManager class manages the display of screens. It contains a Hashmap which has Screen name -> MainScreen pairs,public methods for adding and showing a screen.
When our application starts up all the screens required are created and added to the ScreenManager class.
In the showScreen() method we get the reference to the appropriate MainScreen class. Then we use UiApplication.getUiApplication().popScreen(screen) to hide the current screen. If the screen has already been shown we simply use popScreen() to remove screens until we reach the screen we want. Otherwise we just pushScreen() to move the screen to the top of the pile.
Calls to using the UiApplication are contained within a synchronized(UiApplication.getEventLock()) block
This approach does the job for us. We can create all the screens once at the application startup so it does not need to be done over and over again during the course of the application.
I also just use the above method of pushing to the screen-stack however an addition to this I also pass references of screens within my stack as parameter to new screens added.
If you have any public methods (which might for example update the contents of the screen etc) these can be called from other screens within your stack using this kind of reference. E.g.
Screen 1
public class MyScreen1 extends MainScreen
{
private LabelField content;
public MyScreen1(){
content = new LabelField(“this is the original content”);
add(content);
}
public void UpdateScreen(String newContent){
content.setText(newContent);
}
private void PushScreen{
MyScreen2 screen = new MyScreen2( (MyScreen1)UiApplication.getUiApplication().getActiveScreen());
UiApplication.getUiApplication().pushScreen(screen);
}
}
Screen 2
public class MyScreen2 extends MainScreen
{
private MyScreen1 originalScreen
public MyScreen2(MyScreen1 originalScreen){
this.originalScreen = originalScreen
public MyScreen1 () {
LabelField content = new LabelField(“Screen1 will now be changed.”);
add(content);
UpdateScreen1();
}
private void UpdateScreen1(){
originalScreen.UpdateScreen(“This is new content”);
}
}
In this example, once MyScreen2 has been popped, the content of MyScreen1 will have changed. This is useful if you have a scenario where you display details of an object then push an edit screen for the object which would pop back to an older version of the object.

Resources