how to use progressbar when loading image in picasso? - android-progressbar

I want onStart() method to load image from server using picasso and I want to show a progress bar until the photos are fully downloaded
Here is my code:
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Picasso.with(context).load(imageLoad)
.placeholder(R.id.progressBarDetails)
.error(R.drawable.friend_request).noFade().resize(200, 200)
.into(avatarImage, new Callback() {
#Override
public void onError() {
// TODO Auto-generated method stub
}
#Override
public void onSuccess() {
// TODO Auto-generated method stub
progressbar.setVisibility(View.GONE);
}
});
Picasso.with(this).load(imageLoad).into(target);
}
OnFinished a = new OnFinished() {
#Override
public void onSendFinished(IntentSender IntentSender, Intent intent,
int resultCode, String resultData, Bundle resultExtras) {
// TODO Auto-generated method stub
intent = new Intent(getApplicationContext(), Map.class);
}
};
private Target target = new Target() {
#Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
new Thread(new Runnable() {
#Override
public void run() {
File file = new File(Environment
.getExternalStorageDirectory().getPath()
+ "/actress_wallpaper.jpg");
try {
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(CompressFormat.JPEG, 75, ostream);
ostream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}

I haven't tested your code but even if that works, the file actress_wallpaper.jpg isn't loaded in the ImageView. In the docs, it says
Objects implementing this class must have a working implementation of Object.equals(Object) and Object.hashCode() for proper storage internally.
Try this:
File file = new File(pathToFile);
Picasso.with(context)
.load(file)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
progressbar.setVisibility(View.GONE);
}
});
be warned I haven't tested my code.
Update:
I have tried version 2.3.2 and 2.3.3, it seems like that there's an issue https://github.com/square/picasso/issues/539

It is an old question but may be this answer can help others as I also had issues in showing progress bar while loading image from server.
I am using Picasso 2.4.0. and I am using Picasso Target interface to load image in imageview. Here is the tested and working code:
First add the following lines:
ImageView ivPhoto = (ImageView) findViewById(R.id.iv_photo);
ProgressBar pbLoadingBar = (ProgressBar) findViewById(R.id.pb_loading_bar);
//get image url
String imageUrl = getImageUrl();
//ImageViewTarget is the implementation of Target interface.
//code for this ImageViewTarget is in the end
Target target = new ImageViewTarget(ivPhoto, pbLoadingBar);
Picasso.with(mContext)
.load(imageUrl)
.placeholder(R.drawable.place_holder)
.error(R.drawable.error_drawable)
.into(target);
Here is the implementation of Target interface used above
private static class ImageViewTarget implements Target {
private WeakReference<ImageView> mImageViewReference;
private WeakReference<ProgressBar> mProgressBarReference;
public ImageViewTarget(ImageView imageView, ProgressBar progressBar) {
this.mImageViewReference = new WeakReference<>(imageView);
this.mProgressBarReference = new WeakReference<>(progressBar);
}
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
//you can use this bitmap to load image in image view or save it in image file like the one in the above question.
ImageView imageView = mImageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
ProgressBar progressBar = mProgressBarReference.get();
if (progressBar != null) {
progressBar.setVisibility(View.GONE);
}
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
ImageView imageView = mImageViewReference.get();
if (imageView != null) {
imageView.setImageDrawable(errorDrawable);
}
ProgressBar progressBar = mProgressBarReference.get();
if (progressBar != null) {
progressBar.setVisibility(View.GONE);
}
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
ImageView imageView = mImageViewReference.get();
if (imageView != null) {
imageView.setImageDrawable(placeHolderDrawable);
}
ProgressBar progressBar = mProgressBarReference.get();
if (progressBar != null) {
progressBar.setVisibility(View.VISIBLE);
}
}
}
The above code works fine if used for loading image in activity. But if you want to load image in gridview/recyclerview or view pager etc. where same view holder is used, you might get an issue where onBitmapLoaded() is not called (as the view is recycled and Picasso only keeps a weak reference to the Target object). Here is a link to solve this problem.

change to this
Picasso.get()
.load(tImageUrl())
.into(holder.AnimImage, new Callback() {
#Override
public void onSuccess() {
holder.progressBar.setVisibility(View.GONE);
}
#Override
public void onError(Exception e) {
}
});

Related

Handle multiple JavaFX application launches within a loop

My code currently reads my Gmail inbox via IMAP (imaps) and javamail, and once it finds an email with zip/xap attachment, it displays a stage (window) asking whether to download the file, yes or no.
I want the stage to close once I make a selection, and then return to the place within the loop from which the call came. My problem arises because you cannot launch an application more than once, so I read here that I should write Platform.setImplicitExit(false); in the start method, and then use primartyStage.hide() (?) and then something like Platform.runLater(() -> primaryStage.show()); when I need to display the stage again later.
The problem occuring now is that the flow of command begins in Mail.java's doit() method which loops through my inbox, and launch(args) occurs within a for loop within the method. This means launch(args) then calls start to set the scene, and show the stage. Since there is a Controller.java and fxml associated, the Controller class has an event handler for the stage's buttons which "intercept" the flow once start has shown the stage. Therefore when I click Yes or No it hides the stage but then just hangs there. As if it can't return to the start method to continue the loop from where launch(args) occurred. How do I properly hide/show the stage whenever necessary, allowing the loop to continue whether yes or no was clicked.
Here is the code for Mail.java and Controller.java. Thanks a lot!
Mail.java
[Other variables set here]
public static int launchCount = 0;#FXML public Text subjectHolder;
public static ReceiveMailImap obj = new ReceiveMailImap();
public static void main(String[] args) throws IOException, MessagingException {
ReceiveMailImap.doit();
}
#Override
public void start(Stage primaryStage) throws Exception {
loader = new FXMLLoader(getClass().getResource("prompts.fxml"));
root = loader.load();
controller = loader.getController();
controller.setPrimaryStage(primaryStage);
scene = new Scene(root, 450, 250);
controller.setPrimaryScene(scene);
scene.getStylesheets().add("styleMain.css");
Platform.setImplicitExit(false);
primaryStage.setTitle("Download this file?");
primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void doit() throws MessagingException, IOException {
Folder inbox = null;
Store store = null;
try {
Properties props = System.getProperties();
Session session = Session.getDefaultInstance(props, null);
store = session.getStore("imaps");
store.connect("imap.gmail.com", "myAccount#gmail.com", "Password");
inbox = store.getFolder("Inbox");
inbox.open(Folder.READ_WRITE);
Message[] messages = inbox.getMessages();
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(UIDFolder.FetchProfileItem.FLAGS);
fp.add(UIDFolder.FetchProfileItem.CONTENT_INFO);
fp.add("X-mailer");
inbox.fetch(messages, fp);
int doc = 0;
int maxDocs = 400;
for (int i = messages.length - 1; i >= 0; i--) {
Message message = messages[i];
if (doc < maxDocs) {
doc++;
message.getSubject();
if (!hasAttachments(message)) {
continue;
}
String from = "Sender Unknown";
if (message.getReplyTo().length >= 1) {
from = message.getReplyTo()[0].toString();
} else if (message.getFrom().length >= 1) {
from = message.getFrom()[0].toString();
}
subject = message.getSubject();
if (from.contains("myAccount#gmail.com")) {
saveAttachment(message.getContent());
message.setFlag(Flags.Flag.SEEN, true);
}
}
}
} finally {
if (inbox != null) {
inbox.close(true);
}
if (store != null) {
store.close();
}
}
}
public static boolean hasAttachments(Message msg) throws MessagingException, IOException {
if (msg.isMimeType("multipart/mixed")) {
Multipart mp = (Multipart) msg.getContent();
if (mp.getCount() > 1) return true;
}
return false;
}
public static void saveAttachment(Object content)
throws IOException, MessagingException {
out = null; in = null;
try {
if (content instanceof Multipart) {
Multipart multi = ((Multipart) content);
parts = multi.getCount();
for (int j = 0; j < parts; ++j) {
part = (MimeBodyPart) multi.getBodyPart(j);
if (part.getContent() instanceof Multipart) {
// part-within-a-part, do some recursion...
saveAttachment(part.getContent());
} else {
int allow = 0;
if (part.isMimeType("application/x-silverlight-app")) {
extension = "xap";
allow = 1;
} else {
extension = "zip";
allow = 1;
}
if (allow == 1) {
if (launchCount == 0) {
launch(args);
launchCount++;
} else {
Platform.runLater(() -> primaryStage.show());
}
} else {
continue;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if ( in != null) { in .close();
}
if (out != null) {
out.flush();
out.close();
}
}
}
public static File createFolder(String subject) {
JFileChooser fr = new JFileChooser();
FileSystemView myDocs = fr.getFileSystemView();
String myDocuments = myDocs.getDefaultDirectory().toString();
dir = new File(myDocuments + "\\" + subject);
savePathNoExtension = dir.toString();
dir.mkdir();
System.out.println("Just created: " + dir);
return dir;
}
}
Controller.java
public class Controller implements Initializable {
#FXML
private Text subjectHolder;
public Button yesButton, noButton;
public ReceiveMailImap subject;
#Override
public void initialize(URL url, ResourceBundle rb) {
subject= new ReceiveMailImap();
subjectHolder.setText(subject.returnSubject());
}
public Stage primaryStage;
public Scene scene;
#FXML
ComboBox<String> fieldCombo;
public void setPrimaryStage(Stage stage) {
this.primaryStage = stage;
}
public void setPrimaryScene(Scene scene) {
this.scene = scene;
}
public String buttonPressed(ActionEvent e) throws IOException, MessagingException {
Object source = e.getSource();
if(source==yesButton){
System.out.println("How to tell Mail.java that user clicked Yes?");
return "POSITIVE";}
else{subject.dlOrNot("no");
System.out.println("How to tell Mail.java that user clicked No?");
primaryStage.hide();
return "NEGATIVE";}
}
}
There are a lot of issues with the code you have posted, but let me just try to address the ones you ask about.
The reason the code hangs is that Application.launch(...)
does not return until the application has exited
In general, you've kind of misunderstood the entire lifecycle of a JavaFX application here. You should think of the start(...) method as the equivalent of the main(...) method in a "traditional" Java application. The only thing to be aware of is that start(...) is executed on the FX Application Thread, so if you need to execute any blocking code, you need to put it in a background thread.
The start(...) method is passed a Stage instance for convenience, as the most common thing to do is to create a scene graph and display it in a stage. You are under no obligation to use this stage though, you can ignore it and just create your own stages as and when you need.
I think you can basically structure your code as follows (though, to be honest, I have quite a lot of trouble understanding what you're doing):
public class Mail extends Application {
#Override
public void start(Stage ignored) throws Exception {
Platform.setImplicitExit(false);
Message[] messages = /* retrieve messages */ ;
for (Message message : messages) {
if ( /* need to display window */) {
showMessage(message);
}
}
}
private void showMessage(Message message) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("prompts.fxml"));
Parent root = loader.load();
Controller controller = loader.getController();
Scene scene = new Scene(root, 450, 250);
stage.setScene(scene);
stage.initStyle(StageStyle.UNDECORATED);
stage.setTitle(...);
// showAndWait will block execution until the window is hidden, so
// you can query which button was pressed afterwards:
stage.showAndWait();
if (controller.wasYesPressed()) {
// ...
}
}
// for IDEs that don't support directly launching a JavaFX Application:
public static void main(String[] args) {
launch(args);
}
}
Obviously your logic for decided whether to show a window is more complex, but this will give you the basic structure.
To check which button was pressed, use showAndWait as above and then in your controller do
public class Controller {
#FXML
private Button yesButton ;
private boolean yesButtonPressed = false ;
public boolean wasYesPressed() {
return yesButtonPressed ;
}
// use different handlers for different buttons:
#FXML
private void yesButtonPressed() {
yesButtonPressed = true ;
closeWindow();
}
#FXML
private void noButtonPressed() {
yesButtonPressed = false ; // not really needed, but makes things clearer
closeWindow();
}
private void closeWindow() {
// can use any #FXML-injected node here:
yesButton.getScene().getWindow().hide();
}
}

Image downloaded from server is blurred in ImageView

I am using Universal Imageloader and Volley to download an image from my server. Both result in a blurred image. It doesn't make a difference that the width and the height of the image is smaller or larger than the resolution of my screen. I tried uploading the image I am trying with in low and high resolution as well. The image is always displayed blurred.
Imageloader:
optionsImg = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.noimage)
.cacheOnDisc(true)
.imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
.cacheInMemory(true)
.bitmapConfig(Bitmap.Config.ARGB_8888)
.considerExifParams(true)
.displayer(new FadeInBitmapDisplayer(1555))
.build();
imageLoader.displayImage("http://www.mywebsite.com/Images/image.png", iv_bucket, optionsImg, new SimpleImageLoadingListener() {
boolean cacheFound;
#Override
public void onLoadingStarted(String url, View view) {
List<String> memCache = MemoryCacheUtil.findCacheKeysForImageUri(url, ImageLoader.getInstance().getMemoryCache());
cacheFound = !memCache.isEmpty();
if (!cacheFound) {
File discCache = DiscCacheUtil.findInCache(url, ImageLoader.getInstance().getDiscCache());
if (discCache != null) {
cacheFound = discCache.exists();
}
}
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {}
#Override
public void onLoadingComplete(String imageUri, final View view, Bitmap loadedImage) {
if (cacheFound) { ImageLoader.getInstance().displayImage(imageUri, (ImageView) view, optionsImg);
}
}
});
Volley:
com.android.volley.toolbox.ImageLoader nil = AppController.getInstance().getImageLoader();
nil.get("http://www.mywebsite.com/Images/image.png", new ImageListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("IMG", "Image Load Error: " + error.getMessage());
}
#Override
public void onResponse(ImageContainer response, boolean arg1) {
if (response.getBitmap() != null) {
Log.e("IMG_BG", "Image Load Success");
iv_bucket.setImageBitmap(response.getBitmap());
}
}
});
I'm so lame. My phone cached the low quality images so even if I increased the quality it displayed the cached photos

read a text file dynamically in javafx

I need to read aad text file and show the content in text area but the problem is that my text file is updating with every second . IS that possible to show the content of text file in text area dynamically i.e., with every second new data is added into text file and i need to show the new data also
this is my code in the controller
public void initialize(URL url, ResourceBundle rb) {
try {
Scanner s = new Scanner(new File("E:\\work\\programming\\NetBeansProjects\\FinalProject\\src\\logs\\diskCheck.txt")).useDelimiter("\\s+");
while (s.hasNext()) {
if (s.hasNextInt()) { // check if next token is an int
diskchecktextarea.appendText(s.nextInt() + " "); // display the found integer
} else {
diskchecktextarea.appendText(s.next() + " "); // else read the next token
}
}
} catch (FileNotFoundException ex) {
System.err.println(ex);
}
}
I've wanted to test the watch feature for a while now, so I took the chance with your question and made you an example. Please adapt the watchPath to your needs. The file doesn't have to exist initially. It'll be found once you create it.
/**
* Documentation: https://blogs.oracle.com/thejavatutorials/entry/watching_a_directory_for_changes
*/
public class WatchFileChanges extends Application {
Path watchPath = Paths.get("c:/temp/watch.txt");
TextArea textArea;
#Override
public void start(Stage primaryStage) throws IOException {
BorderPane root = new BorderPane();
textArea = new TextArea();
root.setCenter(textArea);
Scene scene = new Scene(root, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
// load file initally
if (Files.exists(watchPath)) {
loadFile();
}
// watch file
WatchThread watchThread = new WatchThread(watchPath);
watchThread.setDaemon( true);
watchThread.start();
}
private void loadFile() {
try {
String stringFromFile = Files.lines(watchPath).collect(Collectors.joining("\n"));
textArea.setText(stringFromFile);
} catch (Exception e) {
e.printStackTrace();
}
}
private class WatchThread extends Thread {
Path watchPath;
public WatchThread(Path watchPath) {
this.watchPath = watchPath;
}
public void run() {
try {
WatchService watcher = FileSystems.getDefault().newWatchService();
WatchKey key = watchPath.getParent().register(watcher, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY);
while (true) {
// wait for key to be signaled
try {
key = watcher.take();
} catch (InterruptedException x) {
return;
}
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (kind == StandardWatchEventKinds.OVERFLOW) {
continue;
}
WatchEvent<Path> ev = (WatchEvent<Path>) event;
Path path = ev.context();
if (!path.getFileName().equals(watchPath.getFileName())) {
continue;
}
// process file
Platform.runLater(() -> {
loadFile();
});
}
boolean valid = key.reset();
if (!valid) {
break;
}
}
} catch (IOException x) {
System.err.println(x);
}
}
}
public static void main(String[] args) {
launch(args);
}
}

Javafx - Bind the background task with Scene

My application having the two Screens.
Screen-1:
It's having two buttons and one Label
1) Download:
If we click on this, then we will start the downloading process but we still in screen1 and allow you to access the "Navigate" control.
2) Navigate: If we click on this, Then we will redirect to the screen-2.
Screen-2:
1)Back: If we click on this, then we will back to the Screen-1.
While downloading process, I want to allow the user to access the other controls as well. If we started the download process and navigates to some other screen and redirects to the download screen, then we will show the current downloading progress instead of opening it as fresh. For this, I implemented like following. I created one class for implementing this download process but I am unable to update the UI of the screen from that class. Please help me on this.
Screen-1
public class MainsceneController implements Initializable {
#FXML
Button Download, Navigate;
#FXML
Label percentage;
#FXML
HBox progTag;
SyncService service = new SyncService(MainsceneController.this);
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
void DownlaodManager() {
service.downloadProjectFiles();
}
#FXML
void Naviagtion() {
URL location = SecondSceneController.class.getResource("SecondScene.fxml");
ViewManager.getInstance().setView(location);
}
}
Screen-2:
public class SecondSceneController implements Initializable {
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
#FXML
void goBack() {
URL location = MainsceneController.class.getResource("mainscene.fxml");
ViewManager.getInstance().setView(location);
}
}
Background downloading task
public class SyncService {
long currentDownload, totalFileSize;
MainsceneController controller;
DownloadingFilesTask downloadingFilesTask;
public SyncService(MainsceneController controller) {
this.controller = controller;
downloadingFilesTask = new DownloadingFilesTask();
}
public void downloadProjectFiles() throws IOException {
DownloadingFilesTask downloadingFilesTask = new DownloadingFilesTask();
downloadingFilesTask.progressProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> ov, Number oldProgress, Number newProgress) {
System.out.println("Progress changed");
controller.percentage.setText("Progress changed:" + currentDownload);
}
});
downloadingFilesTask.stateProperty().addListener(new ChangeListener<Worker.State>() {
#Override
public void changed(ObservableValue<? extends Worker.State> source, Worker.State oldState, Worker.State newState) {
if (newState.equals(Worker.State.SUCCEEDED)) {
System.err.println("Completed downloading files");
controller.percentage.setText("Progress changed:" + currentDownload);
}
}
});
//progress listeners.
ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(downloadingFilesTask.progressProperty());
bar.visibleProperty().bind(downloadingFilesTask.runningProperty());
controller.progTag.getChildren().clear();
controller.progTag.getChildren().add(bar);
new Thread(downloadingFilesTask).start();
}
class DownloadingFilesTask extends Task<Void> {
#Override
protected Void call() throws Exception {
try {
String fullUrl = "http://s3-us-west-2.amazonaws.com/absprod/media/25/manuals/53454a73d9eda$$53454a73d9f571397049971.mp4";
String destLocation = "C:\\Users\\naresh.repalle\\Desktop\\ABS Test\\53454a73d9eda$$53454a73d9f571397049971.mp4";
File destFile = new File(destLocation);
URL downloadingUrl = new URL(fullUrl);
RandomAccessFile file = null;
InputStream stream = null;
int downloaded = 0;
int size = -1;
try {
// Open connection to URL.
HttpURLConnection connection = (HttpURLConnection) downloadingUrl.openConnection();
// Specify what portion of file to download.
connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
connection.setConnectTimeout(10 * 1000);
connection.setReadTimeout(10 * 1000);
// Connect to server.
connection.connect();
// Make sure response code is in the 200 range.
if (connection.getResponseCode() / 100 != 2) {
System.err.println("Wrong response code while downloading file." + connection.getResponseCode());
}
// Check for valid content length.
int contentLength = connection.getContentLength();
if (contentLength < 1) {
System.err.println("Wrong file size while downloading file." + contentLength);
}
/*
* Set the size for this download if it hasn't been already set.
*/
if (size == -1) {
size = contentLength;
}
totalFileSize = size;
// Open file and seek to the end of it.
file = new RandomAccessFile(destFile, "rw");
file.seek(downloaded);
stream = connection.getInputStream();
int MAX_BUFFER_SIZE = 1024;
while (true) {
/*
* Size buffer according to how much of the file is left to download.
*/
byte buffer[];
if (size - downloaded > MAX_BUFFER_SIZE) {
buffer = new byte[MAX_BUFFER_SIZE];
} else {
buffer = new byte[size - downloaded];
}
// Read from server into buffer.
int read = stream.read(buffer);
if (read == -1) {
System.out.println("read: " + read);
break;
}
// Write buffer to file.
file.write(buffer, 0, read);
downloaded += read;
currentDownload = downloaded;
stateChanged();
}
} catch (Exception e) {
System.err.println("Exception in Downloading file: " + e.toString());
} finally {
/*
* Change status to complete if this point was reached because downloading
* has finished.
*/
// Close file.
if (file != null) {
try {
file.close();
} catch (Exception e) {
}
}
// Close connection to server.
if (stream != null) {
try {
stream.close();
} catch (Exception e) {
System.err.println("exception in downloading: " + e.toString());
}
}
}
} catch (Exception ex) {
System.err.println("Unable to download file: " + ex);
}
return null;
}
private void stateChanged() {
updateProgress(currentDownload, totalFileSize);
}
}
}
Your SyncService doesn't need to reload the FXML; it just needs to communicate with the existing controller. A simple way to do this would be to just pass a reference to SyncService's constructor:
public class SyncService {
MainSceneController controller ;
public SyncService(MainSceneController controller) {
this.controller = controller ;
}
// ...
public void downloadProjectFiles() throws IOException {
DownloadingFilesTask downloadingFilesTask = new DownloadingFilesTask();
// Remove the following:
// URL location = MainsceneController.class.getResource("mainscene.fxml");
// FXMLLoader fxmlLoader = new FXMLLoader();
// fxmlLoader.setLocation(location);
// fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
// final AnchorPane root = (AnchorPane) fxmlLoader.load(location.openStream());
//get the controller
// final MainsceneController controller = (MainsceneController) fxmlLoader.getController();
// Then code as before
// ...
}
}
I think I would actually do it differently: I don't like the strong coupling between the SyncService and the MainSceneController. I would initialize the progress bar in the MainSceneController, expose the progress as a property in the SyncService and bind to it in the controller. But you should be able to use the simpler approach to get it working.

FragmentDialog loose reference to activity

I am using the support library to create dialogs using fragments.
And i Have the following code to show and dismiss the dialogs:
#Override
public void onCreate(Bundle savedInstanceState) {
Log.d("Create", "Create");
setContentView(R.layout.activity_report);
init();
addListeners();
addhandlerListener();
super.onCreate(savedInstanceState);
}
private void showDialog(final Class<?> classs) {
if (classs.equals(AddressValidateProgress.class)) {
addressValidateProgress = AddressValidateProgress.newInstance();
addressValidateProgress.show(getSupportFragmentManager(), null);
Log.d("counter", "+1");
}
if (classs.equals(GPSSearchProgress.class)) {
showDialog(gpsSearchloadId);
}
}
private void dismissDialog(final Class<?> classs) {
if (classs.equals(AddressValidateProgress.class)) {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.remove(addressValidateProgress).commitAllowingStateLoss();
addressValidateProgress = null;
Log.d("super", addressValidateProgressId + ":dismissed");
}
if (classs.equals(AddressChooseDialog.class)) {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.remove(addressChooseDialog).commitAllowingStateLoss();
addressChooseDialog = null;
}
if (classs.equals(GPSSearchProgress.class)) {
dismissDialog(gpsSearchloadId);
Log.d("super", gpsSearchloadId + ":dismissed");
}
}
If i start the application in portrait mode i can use the dialogs normally, i can even rotate the screen and the dialogs are reconstructed.
The problem is that if i start the application rotate the screen and click the button that open the dialogs i get an exception:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
Solution found.
It was caused by a static Handler declared

Resources