Handaling single and double taps android kotlin - java

I want to display some toast when my button is clicked once and other toast when my button is clicked twice. Is there any built in library or do I need to implement custom logic?

You can Gesture Detector for detecting double taps.
final GestureDetector mDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener {
#Override
public boolean onDown(MotionEvent e) {
return true;
}
#Override
public boolean onDoubleTap(MotionEvent e) {
return true;
}
});
For more details you can check this documentation.

Answer given by #TaranmeetSingh is absolutely right but there is a better solution. You can use this library to do it.
How to implement
Add this library -> implementation 'com.github.pedromassango:doubleClick:CURRENT-VERSION'(Version is given above).
Instead of using an onClickListenerObject for onClickListener, you can use DoubleClickListener Check the example below
Button btn = new Button(this);
btn.setOnClickListener( new DoubleClick(new DoubleClickListener() {
#Override
public void onSingleClick(View view) {
// Single tap here.
}
#Override
public void onDoubleClick(View view) {
// Double tap here.
}
});

Related

Dynamic UI Progress Updates using Interface + ExecutorService Issue

So I have a music application. I am trying to update the UI with the progress of the media player (like current time, current song, album cover) everytime the song changes. I found that using interfaces was a awesome magical way of communication between activity and fragments so I implemented an interface in my MusicManger class. My code will show what and how did it.
Two problems
1) Commented look below, ExecutorService seems to stop after one loop. No Errors in catch block (this is why I tagged with java)
2) Commented please look, All the System.out methods print but the UI doesn't update. I do believe I called the method from mainThread so it should update.
I'll show code in logical order will add titles in bold before code segment to tell you basic idea of code.
Passing UI references from fragment to MusicManager class, code below in Fragment class
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_item_songlist, container, false);
// Set the adapter
TextView musicManagerSongName, musicManagerCurrent, musicManagerTotal;
ProgressBar musicManagerProgress;
ImageView musicManagerImageView;
mListView = (AbsListView) view.findViewById(R.id.slist);
musicManagerSongName = (TextView)view.findViewById(R.id.textView12);
musicManagerCurrent = (TextView)view.findViewById(R.id.textView10);
musicManagerTotal = (TextView)view.findViewById(R.id.textView11);
musicManagerProgress = (ProgressBar)view.findViewById(R.id.progressBar);
musicManagerImageView = (ImageView)view.findViewById(R.id.imageView2);
MainActivity.mediaPlayer.passUIReferences(musicManagerSongName, musicManagerCurrent, musicManagerTotal, musicManagerProgress, musicManagerImageView, view);
// line above is a method within MusicManager that takes the references will show code next!
ImageButton playbutton = (ImageButton)view.findViewById(R.id.playbuttonbar);
ImageButton nextButton = (ImageButton)view.findViewById(R.id.nextbuttonbar);
ImageButton backButton = (ImageButton)view.findViewById(R.id.backbuttonbar);
ImageButton toggleButton = (ImageButton)view.findViewById(R.id.shufflebuttonbar);
ImageButton pausebutton = (ImageButton)view.findViewById(R.id.pausebuttonbar);
playbutton.setBackgroundResource(R.drawable.playbuttonbar);
playbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
MainActivity.mediaPlayer.stateChange(1);
}catch(Exception e) {
}
}
});
backButton.setBackgroundResource(R.drawable.backbutton1);
nextButton.setBackgroundResource(R.drawable.nextbutton1);
toggleButton.setBackgroundResource(R.drawable.shufflebuttonselected);
pausebutton.setBackgroundResource(R.drawable.pausebutton1);
pausebutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
MainActivity.mediaPlayer.stateChange(0);
} catch (Exception e){
}
}
});
mListView.setAdapter(mAdapter);
((MainActivity) mListener).restoreActionBar();
return view;
}
As Commended above the code that is located in MusicManager class that takes references and stores them. Also shows interface implementation with MusicManager class. And the Executor service
public void passUIReferences(View... views) {
this.uiElements = views;
}
private ExecutorService executorService = Executors.newSingleThreadExecutor();
private MediaplayerUpdateInterface uiUpdateInterface;
public MediaPlayerManager(MediaplayerUpdateInterface inter) {
this.player = new MediaPlayer();
this.uiUpdateInterface = inter;
// The below line starts the single thread while loop for excutorservice and only loops and prints "this" once after I start one song then it never loops again
executorService.submit(new Runnable() {
#Override
public void run() {
while(true) {
if (player.isPlaying() && uiElements != null) {
System.out.println("this");
uiUpdateInterface.updateUI(uiElements, 0);
}
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
public interface MediaplayerUpdateInterface {
public void updateUI(View[] views, int type);
}
Finally some code from MainActivity class that actually is suppose to update the UI note that both println's work as expected but only once as stated above because of the executorservice issue
public static MediaPlayerManager mediaPlayer = new MediaPlayerManager(new MediaPlayerManager.MediaplayerUpdateInterface() {
#Override
public void updateUI(View[] views, int type) {
System.out.println("check1 " + type);
updateMediaplayerViews(views, type);
}
});
private static void updateMediaplayerViews(View[] views, int type)
{
switch(type) {
case 0:
System.out.println("that?");
((TextView)views[0]).setText(mediaPlayer.getCurrentSongInfo().getName().length() > 22? mediaPlayer.getCurrentSongInfo().getName().substring(0, 19)+"..." : mediaPlayer.getCurrentSongInfo().getName());
break;
}
views[views.length - 1].invalidate();
}
The view array is shown perviously! Also the last view in the array is shown as the main view for songlist fragment.
I am sorry for all the code I've tried to debug it as you can see from my println's there is just something I am unaware of going on here.
Ok so there was an error that I needed to catch to see within the following code:
private static void updateMediaplayerViews(View[] views, int type)
{
switch(type) {
case 0:
System.out.println("that?");
((TextView)views[0]).setText(mediaPlayer.getCurrentSongInfo().getName().length() > 22? mediaPlayer.getCurrentSongInfo().getName().substring(0, 19)+"..." : mediaPlayer.getCurrentSongInfo().getName());
break;
}
views[views.length - 1].invalidate();
}
The issue is I was trying to change the view from a different thread then the one which created it. Solving it was pretty long and painful but basically I made it nonstactic used more interfaces then used the famous
Mainactivity.runOnUiThread(new Runnable(....));

Jface Dialog, How to retrieve correctly what button pressed the user?

I'm having troubles with a custom Dialog in Eclipse.
in the first place, I created a Class that extend Dialog.
public class ModificarGrupoBCDialog extends Dialog {
private static final int CANCELAR = 999;
private static final int MODIFICAR = 1;
...
somewhere I create the buttons...
protected void createButtonsForButtonBar(Composite parent) {
this.createButton(parent, MODIFICAR, "Modificar", true);
this.getButton(MODIFICAR).setEnabled(puedeAltaGrupoBC());
this.bt_ok = this.getButton(MODIFICAR);
this.createButton(parent, CANCELAR, "Cancelar", false);
Display display = window.getShell().getDisplay();
Image image = new Image(display, ModificarGrupoBCDialog.class.getResourceAsStream("/icons/modificar.png"));
this.getButton(MODIFICAR).setImage(image);
image = new Image(display, ModificarGrupoBCDialog.class.getResourceAsStream("/icons/cancelar.png"));
this.getButton(CANCELAR).setImage(image);
}
and when the user clicks...
protected void buttonPressed(int buttonId) {
switch (buttonId) {
case MODIFICAR:
// Some Code, for Change Button
break;
case CANCELAR:
setReturnCode(CANCELAR);
close();
break;
}
Finally, this is how I open and get the returnCode, in the caller object.
...
ModificarGrupoBCDialog modificarGrupoBC = new ModificarGrupoBCDialog(window.getShell(), window, gr_bc);
if (modificarGrupoBC.getReturnCode() == Window.OK) {
//... Some code on OK
} else {
//another code when cancel pressed.
}
;
as you can see, after trying a while, I have to write setReturnCode() in CANCELAR switch block, is that OK ?
I spect that Dialog class automatically asign the correct return code.
May be someone could point me to a good sample.
I'm reading Vogela's blog, and may be the solution is to override okPressed() method ?
Best Regards.
The standard dialog sets the return code in two places:
protected void okPressed() {
setReturnCode(OK);
close();
}
protected void cancelPressed() {
setReturnCode(CANCEL);
close();
}
so your code doing:
setReturnCode(xxxx);
close();
should be fine as long as the button id you are using does not match the Cancel or OK button ids.
You could also use the approach used by MessageDialog which simply does this:
protected void buttonPressed(int buttonId) {
setReturnCode(buttonId);
close();
}

Android - toggleButton delay with own OnClickListener

I have problem with unwanted delay after click on toggleButton using own OnClickListener.
I make my listener by this advice on stackoverflow, like below:
public class ToggleButtonOnClickListener implements OnClickListener{
private String _name;
public ToggleButtonOnClickListener(String name) {
_name = name;
}
#Override
public void onClick(View v) {
Log.i("toggle button clicked",_name);
}
}
and using this:
toggle.setOnClickListener(new ToggleButtonOnClickListener(device.GetName()));
But it not fire onClick method after first click, but the next one.
And because I have group of toggleButtons is this very unhappy, when I click on first, and onClick method fire after click again or even after click to second (or any) from the group.
The OnCheckChangeListener behaves the same.
Please refer developer's example.
You can implement something like below:
public void onToggleClicked(View view) {
// Is the toggle on?
boolean on = ((ToggleButton) view).isChecked();
if (on) {
// Enable vibrate
} else {
// Disable vibrate
}
}
After looking for errors and testing other options, I found that delay caused not Listener, but the log statement.
So, the code above working well except for
Log.i("toggle button clicked",_name);
and an alternative without needs have own class(parametrs) using OnCheckedChangeListener is:
toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Toast.makeText(buttonView.getContext(), "test", Toast.LENGTH_LONG).show();
}
});
I don't know why this Log do, but I used them only for debug, so problem solved!

How to get click, double tap, and long click gestures for a view inside a gridview?

I have ImageViews inside of a GridView, I had been using an OnItemClickListener along with an OnItemLongClickListener set on the GridView to open the image on a larger page and to delete the item respectively. Now, I have to implement rearranging of the ImageViews in the GridView, so I plan to move the deletion function to a double tap gesture, (please do not lecture me on android style guidelines (including the possibility of contextual actionbars, which I suggested), as this is what my boss asks for to emulate functions inside our ios app) in order to reserve long click for the drag and drop. I set an OnTouchListener on each view in the getView of my custom adapter, feeding a GestureDetecter with a listener extending SimpleOnGestureListener the given MotionEvent with onTouchEvent. I know what to do up to that point, but when I included (onDown of course, to get other callbacks) onDoubleTap, onSingleTapConfirmed, and onLongPressed all taps were interpreted as long clicks. And when I removed the both callback methods to be replaced with their listener counterparts once again (ie OnItemClickListeners) I received those two gestures but not the double tap, which makes sense, as double taps start out as a single tap unless you wait for a bit less than a second to confirm them as singles rather than potential doubles. I also tried placing the OnItemClickListener, but not the OnItemLongClickListener, with the callback in the extended SimpleOnGestureListener. In this case, only long presses were ever interpreted, but other gestures caused no response. Here is my code as it stands now, and do note that I returned false in the onTouchEvent in order to allow others (itemclicklisteners) to consume the events following the attempts made in the GestureDetector.
public class MainBoardGridAdapter extends GenericBoardGridAdapter implements OnItemLongClickListener {
private class Ges extends GestureDetector.SimpleOnGestureListener {
int pos;
public Ges(View v) {
pos = (Integer) v.getTag();
}
#Override
public boolean onDown(MotionEvent me) {
//this does get called but none of these methods below
return true;
}
#Override
public boolean onDoubleTap(MotionEvent me) {
new DeleteConfirmationPrompt(c, "board") {
#Override
protected boolean onDeleteConfirmed() {
// delete the visionboard
return deleteBoard(pos);
}
}; // Constructor shows dialog
return false;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
MainBoardGridAdapter.super.flagForUpdate(pos);
if (listener != null) {
listener.onBoardClick(pos, getName(pos));
} else {
Intent intent = new Intent(c, VisionBoardActivity.class);
intent.putExtra(VisionBoardActivity.EXTRA_VISION_BOARD_NAME, getName(pos));
frag.startActivityForResult(intent, MyBoardsFragment.REQUEST_EDIT);
}
return false;
}
}
#Override
public boolean onItemLongClick(AdapterView<?> parent, View v,
final int pos, long id) {
Toast.makeText(c, "Long", Toast.LENGTH_LONG).show();
return false;
}
// called by getView of extended adapter
#Override
public void onImageLoaded(ImageView iv, String data, View root) {
iv.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
(new GestureDetector(c, (new Ges(v)))).onTouchEvent(event);
return false;
}
});
}
}
And in the Activity, gv is my GridView:
gv.setOnItemLongClickListener(gridAdapter);
Also note that I had been using true in the return value in the GestureDetector methods, until trying the current configuration.There was no difference to be seen.
Thank you for your valuable time and help, I hope that someone will be able to point out what I am doing incorrectly.
-Jackson

Java SWT: widgetSelected vs widgetDefaultSelected

For example I want to execute something when user clicks on a button. Which do I use? The documentation didn't appear to make it very clear
UPDATE
A quick test shows that Widget Selected is triggered but not Default Selected.
In TasksView.main()
TasksView view = new TasksView(shell, SWT.None);
TasksController controller = new TasksController(view);
In TasksController
public class TasksController extends ControllerAbstract {
protected TasksView view;
public TasksController(TasksView view) {
this.view = view;
view.addTaskListener(new AddTaskListener());
}
protected class AddTaskListener implements SelectionListener {
#Override
public void widgetDefaultSelected(SelectionEvent arg0) {
System.out.println("Default Selected");
}
#Override
public void widgetSelected(SelectionEvent arg0) {
System.out.println("Widget Selected");
}
}
}
btw, Did I do MVC correctly?
Use widgetSelected. In fact, all the better is to simply extend SelectionAdapter and only override the widgetSelected method and completely ignore widgetDefaultSelected.
SelectionListener.widgetDefaultSelected(e) has a toolkit dependent behavior. I usually just invoke SelectionListener.widgetSelected(...). (Note that this is not the default in SelectionAdapter.widgetDefaultSelected(e) - you will have to do this yourself.

Categories

Resources