Android pager-adapter timer gets confused on user touch - multithreading

i have a problem with my Pager adapter timer , when user touches to adapter,and if user slides the image ,its working fine. but ,if he doesn't slide the image , my timer is getting faster and sometimes goes to next image.
here is my pager adapter which i am using in the activity
pagerAdapter.setTimer(myPager, 7, pagerAdapter.getCount(), pagerAdapter.currentPage);
myPager.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN://starts with down
//Log.e("TOUCH", "DOWN");
break;
case MotionEvent.ACTION_MOVE://moves finger
//todo check ifts working
if(pagerAdapter.timerworking){
Log.d("ACTION_MOVE", "currentPage"+pagerAdapter.currentPage);
pagerAdapter.stopTimer();
}
//Log.e("TOUCH", "MOVE");
break;
case MotionEvent.ACTION_UP://ends with up
//current +1 e kayitli oldugu icin bir onceki olmali
Log.d("ACTION_UP", "currentPage"+pagerAdapter.currentPage);
pagerAdapter.setTimer(myPager, 7, pagerAdapter.getCount(), pagerAdapter.currentPage);
//Log.e("TOUCH", "UP");
break;
case MotionEvent.ACTION_CANCEL:
//Log.e("TOUCH", "CANCEL");
break;
default:
break;
}
return false;
}
});
here is timer functions of my pager adapter(ImagePager)
/**
* this function swipes pages left to right for every 7 seconds
* #param myPager
* #param time
* #param numPages we recommend that it should be as much as much objects.size()
* #param curPage we recommend that it should start from 0
*
*/
public void setTimer(final ViewPager myPager, int time, final int numPages, final int curPage){
currentPage = curPage;
final Runnable Update = new Runnable() {
int NUM_PAGES =numPages;
public void run() {
if(timerworking){
Log.d("PagerTimer", "currentPage"+currentPage);
myPager.setCurrentItem(currentPage, true);
currentPage=(currentPage+1)%NUM_PAGES;
}
}
};
swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
}, 1000, time*1000);//1000 =1 saniyede gecis suresi , 7000 kac saniyede bir degisecek
timerworking=true;
Log.d("PagerTimer", "timerRUN");
}
/**
* its kills runnable
*/
public void stopTimer(){
//handler.removeCallbacks(null);
swipeTimer.cancel();
timerworking=false;
Log.d("PagerTimer", "timerSTOP");
/*
clearTimer();
swipeTimer=null;
handler.removeCallbacksAndMessages(null);
handler.removeCallbacks(null);
*/
}
my intent to make this slider automatically slide for every 7 seconds, if user touches to screen, i want it to stop the counter and when user release touch and goes back to automatically slide (countdown of 7 seconds starts again ).
my problem is when user touches and doesn't slide , it goes to next slide, and its counter gets faster.
EDIT: i have realized that , my timer is controlling 3 threads which changes my adapter quickly.i guess i am creating more threads every time user interrupt

by changing
pagerAdapter.setTimer(myPager, 7, pagerAdapter.getCount(), pagerAdapter.currentPage);
in the case MotionEvent.ACTION_UP to this
if(!pagerAdapter.timerworking){
pagerAdapter.setTimer(myPager, 7, pagerAdapter.getCount(), pagerAdapter.currentPage);
}
i have prevented multiple threads
and also added function below to do image pager to get the current item to stay on it.
public void setOnPageChangeListener(ViewPager myPager){
myPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
//new page is selected , by the user or automatically
nextPage=(arg0)%NUM_PAGES;
Log.d("OnPageChange", "Selected Page is "+arg0);
Log.d("OnPageChange", "currentPage "+currentPage);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
and calling line below , before the myPager.setOnTouchListener , in th activity
pagerAdapter.setOnPageChangeListener(myPager);

Related

Using Thread.sleep to get waiting effect in JavaFX [duplicate]

This question already has answers here:
JavaFX periodic background task
(6 answers)
Closed 5 years ago.
I want to achieve something like this: user press the login button and then label shows:
"Connecting."
0.5 sec time interval
"Connecting.."
0.5 sec time interval
"Connecting..."
etc
Just a visual effect that indicates something is actually going on "under the hood".
All I managed to get wasn't quite what I was expecting. I click the button, wait 1.5 sec and then I got "Connecting...", missing 2 previous steps.
First, my Status class
public class Status {
private static StringProperty status = new SimpleStringProperty();
public static void setStatus(String newStatus) {
status.setValue(newStatus);
}
public static String getStatus() {
return status.getValue();
}
public static StringProperty get() {
return status;
}
}
and my LoginView class
public class LoginView extends Application {
private Button loginButton = new Button("Log in");
private Label statusLabel;
private void createLabels() {
statusLabel = new Label(Status.getStatus());
statusLabel.textProperty().bind(Status.get());
}
}
private void createButtons() {
loginButton.setOnAction(e -> {
try {
Status.setStatus("Connecting.");
Thread.sleep(500);
Status.setStatus("Connecting..");
Thread.sleep(500);
Status.setStatus("Connecting...");
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
});
}
Run a Task from a different thread. Task allows you to update it's message property on the JavaFX application thread that should be used to update the GUI and must not be blocked by long-running tasks, since it's responsible for rendering:
Task<Void> task = new Task<Void>() {
#Override
protected Void call() throws InterruptedException {
updateMessage("Connecting.");
Thread.sleep(500);
updateMessage("Connecting..");
Thread.sleep(500);
updateMessage("Connecting...");
Thread.sleep(500);
return null;
}
};
// bind status to task's message
Status.get().bind(task.messageProperty());
// run task on different thread
new Thread(task).start();
You should do animations with the Timeline API. Have a look here:
https://docs.oracle.com/javase/8/javafx/api/javafx/animation/Timeline.html
Basically you just define KeyFrames at 0.5 seconds distance and set the value of the text to add a another dot. You can also make it repeat indefinitely until the connection is established to get cyclic animation.
Another way is to make a SequentialTransition which will have two PauseTransitions of 0.5 seconds.
BTW in your code you pause the main UI thread and that is why you can’t see the animation.

Observer won't run update in JavaFX GUI

I read much about the JavaFX GUI Model, Plattform->RunLater and Threads, but I still do not figure out how to get this right. I had a JavaFX GUI which on a button click executed a process and updated a Progress Bar and Label. This was running well with Threading and Platform, but I had to Change this to an Observer Model.
I invoke a Progress Tracker in a Singleton Model, which gets updated by the class executing the process and is Observable. I implemented an Observer as well which should update the two UI Elements.
GUI Controller with Button Event
private void createKeyPressed(ActionEvent event) {
// Make Progressbar visible
pbKeyProgress.visibleProperty().set(true);
if (!Check.keyFileExistant() || cbKeyOverwrite.selectedProperty().get()) {
ProgressTracker.getTracker().addObserver(new ProgressObserver(pbKeyProgress, lblKeyProgress));
Creator.createKey(cbKeyLength.getValue());
} else {
}
}
Progress Observer
public class ProgressObserver implements Observer {
private final ProgressBar progressBar;
private final Label statusLabel;
public ProgressObserver(ProgressBar progressBar, Label statusLabel) {
this.progressBar = progressBar;
this.statusLabel = statusLabel;
}
#Override
public void update(Observable o, Object o1) {
Platform.runLater(() -> {
System.out.println("Tracker set to "+ProgressTracker.getProgress() + " " + ProgressTracker.getStatus());
progressBar.setProgress(ProgressTracker.getProgress());
statusLabel.setText(ProgressTracker.getStatus());
});
}
}
Progress Tracker
public synchronized void setTracker(int currentStep, String currentStatus) {
checkInstance();
instance.step = currentStep;
instance.status = currentStatus;
instance.notifyObservers();
System.out.println(instance.countObservers());
}
Creator
public static void createKey(String length) {
Task<Void> task;
task = new Task<Void>() {
#Override
public Void call() throws Exception {
initTracker(0,"Start");
doStuff();
ProgressTracker.getTracker().setTracker(1,"First");
doStuff();
ProgressTracker.getTracker().setTracker(2,"Second");
// and so on
return null;
}
};
new Thread(task)
.start();
}
The Print within the ProgressTracker gets executed. However, if I add a print within the update of the Observer nothing will be printed. If I check within the Progresstracker, the Observer Count is 1.
Why does the Observer not get notified or execute anything, even if the Notify is called? Did I get the Threading and Execution Modell wrong?
The Progress Bar and the Label will also stay on their initial values.
Don't reinvent the wheel. The JavaFX Properties Pattern is a ready-made implementation of the Observable pattern: there is no need to implement it yourself. Additionally, Task already defines methods for updating various properties, which can be called from any thread but will schedule the actual updates on the FX Application Thread. See updateProgress() and updateMessage(), for example.
So you can do, for example:
public static Task<Void> createKey(String length) {
Task<Void> task;
task = new Task<Void>() {
final int totalSteps = ... ;
#Override
public Void call() throws Exception {
updateProgress(0, totalSteps);
updateMessage("Start");
doStuff();
updateProgress(1, totalSteps);
updateMessage("First");
doStuff();
updateProgress(2, totalSteps);
updateMessage("Second");
// and so on
return null;
}
};
new Thread(task)
.start();
return task ;
}
and
private void createKeyPressed(ActionEvent event) {
// Make Progressbar visible
pbKeyProgress.visibleProperty().set(true);
if (!Check.keyFileExistant() || cbKeyOverwrite.selectedProperty().get()) {
Task<Void> task = Creator.createKey(cbKeyLength.getValue());
pbKeyProgress.progressProperty().bind(task.progressProperty());
lblKeyProgress.textProperty().bind(task.messageProperty());
} else {
}
}

new Thread, application still running after Stage-close

So I followed this tutorial: https://www.youtube.com/watch?v=gyyj57O0FVI
and I made exactly the same code in javafx8.
public class CountdownController implements Initializable{
#FXML
private Label labTime;
#Override
public void initialize(URL location, ResourceBundle resources) {
new Thread(){
public void run(){
while(true){
Calendar calendar = new GregorianCalendar();
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
String time = hour + ":" + minute + ":" + second;
labTime.setText(time);
}
}
}.start();
}
After I close the Window, application/thread is still running in the system. My guess its because the infinite loop, but shouldnt the thread be terminated with application closing?
Second thing is that when I try to set the text for Label I get the error:
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:204)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:364)
at javafx.scene.Parent$2.onProposedChange(Parent.java:364)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:575)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(LabeledSkinBase.java:204)
at com.sun.javafx.scene.control.skin.LabelSkin.handleControlPropertyChanged(LabelSkin.java:49)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$60(BehaviorSkinBase.java:197)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$$Lambda$144/1099655841.call(Unknown Source)
at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)
at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:143)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
at javafx.beans.property.StringProperty.setValue(StringProperty.java:65)
at javafx.scene.control.Labeled.setText(Labeled.java:146)
at application.CountdownController$1.run(CountdownController.java:29)
...yes, I am going to read more about threads, but I would like to know the answer to these questions.
Part I
A thread, when created, runs independent of other threads. You have a new thread which has an infinite loop, which implies, it will keep running forever, even after the stage has been closed.
Normally, using a infinite loop is not advised, because breaking out of it is very difficult.
You are advised to use :
TimerTask
ScheduledExecutorService
You can then call either one of them (based on whatever you are using)
TimerTask.cancel()
ScheduledExecutorService.shutdownNow()
when your stage is closed. You can use something like :
stage.setOnCloseRequest(closeEvent -> {
timertask.cancel();
});
JavaFX API's (thanks to James_D comment's)
These do not need to be explicitly canceled as ScheduledService uses daemon threads and AnimationTimer runs on the JavaFX thread.
ScheduledService
AnimationTimer
Part II
Your second part of the question has been answered time and again in the forum.
You need to be on the JavaFX Application thread to use scene graph elements.
Since you have created a new thread and trying to update label, which is a JavaFX node, it throws the exception. For more information, please visit:
JavaFX error when trying to remove shape
Why am I getting java.lang.IllegalStateException "Not on FX application thread" on JavaFX?
Javafx Not on fx application thread when using timer
With ScheduledExecutorService as far as I am concerned You cant easly set it as deamon and I don't want to play with stage.setOnCloseRequest(closeEvent -> {});
With AnimationTimer I cant do something like Thread.sleep(100) beetween iteration like you suggested because "AnimationTimer runs on the JavaFX thread."
ScheduledService is just quite difficult for me to understand right now...
so, as I was reading and reading about it I came to conclusion that maybe this simple option will be the best:
public class CountdownController implements Initializable{
#FXML
private Label labTime;
#FXML
private Button buttSTOP;
#Override
public void initialize(URL location, ResourceBundle resources) {
Timer timer = new Timer(true); //set it as a deamon
timer.schedule(new MyTimer(), 0, 1000);
}
public class MyTimer extends TimerTask{
#Override
public void run() {
Calendar calendar = new GregorianCalendar();
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
String time = hour + ":" + minute + ":" + second;
Platform.runLater(() -> {
labTime.setText(time);
});
}
}
Thanks James_D and ItachiUchiha. It works, let me know if I'am something missing!
EDIT:
I also include code for Counting down the time, as it was my initial aim, maybe someone will find it usefull as well:
public class CountdownController implements Initializable{
#FXML
private Label labTime;
#FXML
private Button buttSTOP;
private Timer timer = new Timer(true); //set it as a deamon
private int iHours = 0,
iMinutes = 1,
iSeconds = 10;
public void initCountdownController(int iHours, int iMinutes, int iSeconds){
this.iHours = iHours;
this.iMinutes = iMinutes;
this.iSeconds = iSeconds;
}
#Override
public void initialize(URL location, ResourceBundle resources) {
buttSTOP.setOnAction(e -> {
buttSTOPAction(e);
});
timer.schedule(new MyTimer(), 0, 1000);
}
private void buttSTOPAction(ActionEvent e) {
timer.cancel();
}
public class MyTimer extends TimerTask{
#Override
public void run() {
String time = iHours + ":" + iMinutes + ":" + iSeconds;
Platform.runLater(() -> {
labTime.setText(time);
});
if(iSeconds < 1)
if(iMinutes < 1)
if(iHours < 1)
this.cancel();
else{
iHours--;
iMinutes = 59;
iSeconds = 59;
}
else{
iMinutes--;
iSeconds = 59;
}
else
iSeconds--;
}
}

Android: Updating the UI from an adapter inside a While Loop

I'm using a GridView to display a list of words in a 4-column table. The getView method of my custom adapter checks the width of the word and shrinks it if it doesn't fit. It does this using a recursive check that keeps scaling the text down until it fits.
private void shrinkText(final TextView wv, final String word) {
wv.setTextSize(defaultTextSize);
new Thread(new Runnable() {
#Override
public void run() {
while (wv.getWidth()>0 && wv.getPaint().measureText(word) > wv.getWidth()) {
Logg.d("word too big. Shrink from " + wv.getTextSize()/density + " to " + (wv.getTextSize()/density-1.0f));
wv.setTextSize(wv.getTextSize() / density - 1.0f);
}
}
}).start();
}
Because I'm using a while loop, I am using a new thread to protect against ANR in the unlikely event of an infinite loop. Here's the weird thing: sometimes it works great. And then sometimes I get the following error:
09-26 14:25:31.389 6427-7765/com.myapp.debug E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-7789
Process: com.myapp.debug, PID: 6427
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
I tried putting the setTextSize inside a runOnUiThread statement, but I can't get it to work inside the adapter. Ultimately I just want this to work. I think my options are:
Keep the while loop in the UI thread and somehow safeguard it (how?)
Move the setTextSize call to the UI thread (how?)
Something else?
Thanks for your help!
UPDATE: based on Rustam's answer, I used wv.post to write to the UI. However the need to use the while loop meant that setTextSize had to be done in the same thread as the while condition itself. I switched from evaluating the TextView.getTextSize to the Paint.getTextSize, since I could set the Paint's text size without impacting the UI, and therefore inside the offshoot thread. Jerry-rigged, but it seems to work.
private void shrinkText(final TextView wv, final String word) {
wv.setTextSize(defaultTextSize);
final Paint mPaint = new Paint(wv.getPaint());
new Thread(new Runnable() {
#Override
public void run() {
while (wv.getWidth()>0 && mPaint.measureText(word) > wv.getWidth()) {
Logg.d("word too big. Shrink from " + mPaint.getTextSize()/density + " to " + (mPaint.getTextSize()/density-1.0f));
mPaint.setTextSize(mPaint.getTextSize() - 1.0f);
}
if (wv.getWidth()>0 && wv.getPaint().measureText(word) > wv.getWidth()) {
wv.post(new Runnable() {
#Override
public void run() {
Logg.d(word + " final size=" + mPaint.getTextSize() / density);
wv.setTextSize(mPaint.getTextSize() / density);
}
});
}
}
}).start();
}
try to update like this:
private void shrinkText(final TextView wv, final String word) {
wv.setTextSize(defaultTextSize);
new Thread(new Runnable() {
#Override
public void run() {
while (wv.getWidth()>0 && wv.getPaint().measureText(word) > wv.getWidth()) {
Logg.d("word too big. Shrink from " + wv.getTextSize()/density + " to " + (wv.getTextSize()/density-1.0f));
wv.post(new Runnable() {
public void run() {
wv.setTextSize(wv.getTextSize() / density - 1.0f);
}
});
}
}).start();
}

How do I set up a listener?

I think I need a listener, but can’t set it up.
In the code below, both the time dialog and date dialog work. The little dialog w/ rollers comes up, I select a date/time, then select and I have my date. But I cannot get the text input to work.
I have tried several iterations of this code from a sample program which had:
bnBodyEntered = true;
bodyDialog = new TextInputDialog(this);
bodyDialog.setText("body");
This code showed the text dialog w/ alphabet roller, but the program ran past it and when I entered a few letters and selected nothing happened. That makes since as I did not set up a listener. So I added (as noted)
bodyDialog.setOnDismissListener(textSetListener);
using several "setOn----Listener" values and It either still runs past, or I get various compile errors.
This is for my WIMMOne watch, so version 7 and no virtual keyboard. It needs to be a dialog.
(Note: I deleted gobs of commented code before posting - possibly something more, so if it doesn't make since - sorry. )
Thanks, Clark
/******************************
* Wimm imports
******************************/
import com.wimm.framework.app.Dialog;
import com.wimm.framework.app.DatePickerDialog;
import com.wimm.framework.app.DatePickerDialog.OnDateSelectedListener;
import com.wimm.framework.app.LauncherActivity;
import com.wimm.framework.app.TextInputDialog;
import com.wimm.framework.app.TimePickerDialog;
import com.wimm.framework.app.TimePickerDialog.OnTimeSelectedListener;
# Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.d("RemindEA","01S onCrt");
setContentView(R.layout.reminder_edit_activity);
. . .
. . .
mBodyText = (EditText)findViewById(R.id.body);
mTimeButton = (Button)findViewById(R.id.reminder_time);
mDateButton = (Button)findViewById(R.id.reminder_date);
mConfirmButton = (Button)findViewById(R.id.confirm);
Log.d("RemindEA","10S onCrtV df");
//------------- TEXT INPUT
mBodyText.setOnClickListener( new View.OnClickListener()
{
public void onClick(View v)
{
Log.d("RemindEA","21> onClkV:Body");
showDialog(BODY_DIALOG_ID);
Log.d("RemindEA","22< onClkV:Body:" + strBody);
mBodyText.setText(bodyDialog.getText());
return;
}
} );
//-------------------------- TIME INPUT
mTimeButton.setOnClickListener( new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Log.d("RemindEA","25> onClkV:Time");
showDialog(TIME_DIALOG_ID);
Log.d("RemindEA","26< onClkV:Time");
}
} );
//-------------------------- DATE INPUT
mDateButton.setOnClickListener( new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Log.d("RemindEA","30> onClkV:Time");
showDialog(DATE_DIALOG_ID);
Log.d("RemindEA","31< onClkV:Time");
}
} );
protected Dialog onCreateDialog(int id)
{
Log.d("RemindEA","70S Dialog:" + id);
switch (id)
{
// if we want a time dialog--------------
case TIME_DIALOG_ID:
Log.d("RemindEA","71S TIME_DIALOG_ID");
timeDialog = new TimePickerDialog(this);
timeDialog.setTimeSelectedListener(timeSetListener);
timeDialog.setTime(mCalendar.get(Calendar.HOUR_OF_DAY),
mCalendar.get(Calendar.MINUTE));
Log.d("RemindEA","73S TIME_D:" + timeDialog);
return timeDialog;
// if we want a date dialog ---------------
case DATE_DIALOG_ID:
Log.d("RemindEA","75S DATE_DIALOG_ID-26");
mCalendar = Calendar.getInstance();
Log.d("RemindEA","76S DATE_DIALOG_ID-27");
dateDialog = new DatePickerDialog(this);
dateDialog.setDateSelectedListener(dateSetListener);
dateDialog.setDate(mCalendar.get(Calendar.DAY_OF_MONTH),
mCalendar.get(Calendar.MONTH ));
Log.d("RemindEA","77S DATE_D:" + dateDialog);
return dateDialog;
// if we want text input dialog ---------------------
case BODY_DIALOG_ID:
Log.d("RemindEA","80S BODY_DIALOG_ID");
bnBodyEntered = true;
Log.d("RemindEA","81S TITLE");
bodyDialog = new TextInputDialog(this);
//---> ADDED LINE BELOW TO CREATE A LISTENER: GET ERROR <-----
// ERROR BELOW: setOnDismissListener cannot be resolved to a type
bodyDialog.setOnDismissListener(textSetListener);
//------------------------------------------
//ALSO //.setOnKeyListener(onKeyListener) - others
Log.d("RemindEA","82S New");
bodyDialog.setText("body");
Log.d("RemindEA","83X:" + bodyDialog);
return bodyDialog;
}
return null;
}
private OnTimeSelectedListener timeSetListener = new OnTimeSelectedListener()
{
public void onTimeSelected(int arg0, int arg1)
{
Log.d("RemindEA","90S onTimeSelected");
intHH = arg0;
intMN = arg1;
Log.d("RemindEA","91S schedule:" + intHH + ":" + intMN);
//updateDisplay();
}
};
private OnDateSelectedListener dateSetListener = new OnDateSelectedListener()
{
public void onDateSelected(int arg0, int arg1)
{
Log.d("RemindEA","92S onTimeSelected");
intDD = arg0;
intMM = arg1;
Log.d("RemindEA","93S schedule:" + intDD + ":" + intMM);
//updateDisplay();
}
};
//------------------------------------
// -----> ERROR: setOnDismissListener cannot be resolved to a type
private setOnDismissListener textSetListener = new setOnDismissListener
//------------------------------------
{
private void textSetListener() // bodySetListener ()
{
Log.d("RemindEA","100S BodyLisner"); //<- does not get here on <done>
return;
}
};
After many hours of guess and error, this worked.
I don't think the "Return bodyDialog" does anything; I ended up updating the EditText field directly from the listener. "arg0" has a long name of the dialog - nothing usefull. But you have it have it to prevent compile errors.
This probably is unique to the WIMMOne where there is no virtual keyboard and you need to use their text input dialog.
protected Dialog onCreateDialog(int id)
{
switch (id)
. . . .
case BODY_DIALOG_ID:
bodyDialog = new TextInputDialog(this);
bodyDialog.setOnDismissListener(textSetListener);
return bodyDialog;
private OnDismissListener textSetListener = new OnDismissListener()
{
#Override
public void onDismiss(DialogInterface arg0)
{
Log.d("RemindEA","101S BodyLisner" + arg0);
String strxx = bodyDialog.getText();
mBodyText.setText(strxx);
}
};

Resources