My Android app shows a floorplan, on which transparent Buttons are set on specific areas. I also implemented a Voice Recognition, that returns a Listview. When the user chooses one item the performClick() Method is performed, which calls the OnClick method. The OnClick method is also called, when the user clicks on the specific area on the display (transparent button)
My question is, how can I see, if the Button is clicked by performClick() or by click on the display?
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
button.setBackgroundColor(Color.GREEN);
}
});
wordsList.setOnItemClickListener(
new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view,
int position, long id) {
// TODO Auto-generated method stub
Object o = wordsList.getItemAtPosition(position);
String pen = o.toString();
if (pen.equals("String")) {
button.performClick();
Toast.makeText(getApplicationContext(), "You have chosen: " + " " + pen, Toast.LENGTH_LONG).show();
}
}
}
);
I already found that post, but I don't know how to implement this in Java.
how to check if the click is Performclick or not
I had the exact same question. Surely I thought there must be a built-in return method of some sort that could tell us whether or not a click was performed by the actual onClick() method or by performClick() but after a while of searching I instead decided to make my own solution...
In the class that perform clicked is called create:
public static boolean performClicked;
In your method that calls "performClick()" simply change
performClicked = true;
right before the call to perform click.
in your onClick use a similar if statement:
if (performClicked){
performClicked = false;
//DO WHAT YOU NEED TO DO WITH THIS INFO
}
I know this is kind of an obvious answer, but maybe not.
Related
I am beginner to Android development. I have 3 edit boxes and one "Edit" button. When I launch the activity all the edit boxes should be disabled. When I click on the Edit button all the 3 edit boxes should get enabled and button text should change to "Save". After updating the data in the edit boxes, when I click on the "Save" button, I should be able to send the updated data to the backend.
My problem is how can I make use of a single button for two function "Edit" and "Save".
Please help me.
You can do it this way:
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
String ButtonText = button.getText().toString();
if(ButtonText.equals("Save"){
//code for save
button.setText("Edit");
}
else{
//code for edit
button.setText("Save");
}
}
});
If I were you I would actually use two buttons one for edit, and one for save. Make them the same size and in the same position, when you want to switch between them make one invisible, and the other visible. Doing it that way would let you keep your onClickListeners separate which would make your code more understandable in my mind.
That being said you could technically achieve it with a single button as well. Just change the text on the button when you want to switch between them, and add an if statement into your click listener to check which "mode" your button is currently in to determine which action it should take.
I am not sure there is an easy way to do this or not. but you can sure use different behaviors of button clicks like
// When you press it for long time.
dummyButton.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
return true; // Can do lot more stuff here I am just returning boolean
}
});
// Normal click of button
dummyButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//do lot more stuff here.
}
});
Do it this way :
Make a public boolean variable
public boolean isClickedFirstTime = true;
make your 3 editTexts enabled false in xml and
onClick of your button
#Override
public void onClick(View v) {
if (v.getId() == R.id.edit_button_id) { //whatever your id of button
Button button = (Button) findViewById(R.id.edit_button_id);
if(isClickedFirstTime)
{
edit1.setEnabled(true);
edit2.setEnabled(true);
edit3.setEnabled(true);
butt.setText("Save");
isClickedFirstTime = false;
}
else
{
....//Get your values from editText and update your database
isClickedFirstTime = true;
}
}
I need your help if any one can be, it will be great thing for my solution.
I don't know is it possible or not, but I want to try to fix this out any how..
Actually I want to implement two method on single button click event, its simple click and long click, here my code ::
homebutton = (ImageButton) findViewById(R.id.home_icon);
homebutton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent(context, MainActivity.class);
startActivity(intent);
}
});
homebutton.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View arg0) {
Toast.makeText(getApplicationContext(), "Long Clicked " , Toast.LENGTH_SHORT).show();
return false;
}
});
So, here i am getting something wrong, even single click is working perfectly, and long click is also working, but problem is that after long click event its also start MainActivity as defined in above code of onClick method..
That should not be done, return false is also there, still not working as i want..
So, anybody please help me to get it resolve..
Thanks in Advance..
I believe you need to return TRUE in your onLongClick method - telling the framework that the touch event is consumed and no further event handling is required.
homebutton.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View arg0) {
Toast.makeText(getApplicationContext(), "Long Clicked " ,
Toast.LENGTH_SHORT).show();
return true; // <- set to true
}
});
I want to use the same button to perform 2 different methods.
One method when user single clicks it and a second method (different) when the user LONG clicks it.
I use this for the single short click (which works great):
Button downSelected = (Button) findViewById(R.id.downSelected);
downSelected.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
method();
}
}
});
I've tried to add a longClickListener but it didn't work.
Appreciate any ideas on how to solve this.
Thanks!
I've done it before, I just used:
down.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
return true;
}
});
Per documentation:
public void setOnLongClickListener
(View.OnLongClickListener l)
Since: API Level 1 Register a callback
to be invoked when this view is
clicked and held. If this view is not
long clickable, it becomes long
clickable.
Notice that it requires to return a boolean, this should work.
To get both functions working for a clickable image that will respond to both short and long clicks, I tried the following that seems to work perfectly:
image = (ImageView) findViewById(R.id.imageViewCompass);
image.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
shortclick();
}
});
image.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
longclick();
return true;
}
});
//Then the functions that are called:
public void shortclick()
{
Toast.makeText(this, "Why did you do that? That hurts!!!", Toast.LENGTH_LONG).show();
}
public void longclick()
{
Toast.makeText(this, "Why did you do that? That REALLY hurts!!!", Toast.LENGTH_LONG).show();
}
It seems that the easy way of declaring the item in XML as clickable and then defining a function to call on the click only applies to short clicks - you must have a listener to differentiate between short and long clicks.
Initially when i implemented a longClick and a click to perform two separate events the problem i face was that when i had a longclick , the application also performed the action to be performed for a simple click . The solution i realized was to change the return type of the longClick to true which is normally false by default . Change it and it works perfectly .
Change return false; to return true; in longClickListener
You long click the button, if it returns true then it does the work. If it returns false then it does it's work and also calls the short click and then the onClick also works.
Try using an ontouch listener instead of a clicklistener.
http://developer.android.com/reference/android/view/View.OnTouchListener.html
The simplest and updated method is using a long click listener like
someView.setOnLongClickListener {
//do your work
true
}
Just wondering how you handle the following problem: a result is calculated depending on two spinners' selected items. To handle the UI things, i.e. a user picks a new item in one of the spinners, I install a listener using setOnItemSelectedListener for the spinner in my onCreate() method of the activity.
Now: that works, of course, fine. The listener's work is to trigger a new calculation of the result.
The problem: because I intercept onPause() onResume() to save/restore the last state, I got a method that sets these two spinners' selected item programmatically like in here:
startSpinner.setSelection(pStart);
destSpinner.setSelection(pDest);
These two calls invoke the listeners, too! My calculation method for the result plus the notification of a new result set is invoked twice here!
A stupid direct approach for this would be to have a boolean variable disabling whatever the listener does inside, setting it before setting the selected items and resetting it afterwards.
Okay. But is there a better method??
I don't want listeners to be called by code - actions, only by user actions! :-(
How do you do it?
Thanks!
A cleaner solution, in my opinion, to differentiate between programmatic and user-initiated changes is the following:
Create your listener for the spinner as both an OnTouchListener and OnItemSelectedListener
public class SpinnerInteractionListener implements AdapterView.OnItemSelectedListener, View.OnTouchListener {
boolean userSelect = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
userSelect = true;
return false;
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (userSelect) {
// Your selection handling code here
userSelect = false;
}
}
}
Add the listener to the spinner registering for both event types
SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);
This way, any unexpected calls to your handler method due to initialization or re-initialization will be ignored.
Okay, I got it working the way I want to now.
The thing to understand here (and I did not when I was writing that question...) is that everything in Android runs in one thread - the UI thread.
Meaning: even though you set Spinner's values here and there: they are only updated (visually) and their listeners are only called after all methods you're currently in (like onCreate, onResume or whatever) are finished.
This allows the following:
keep the selected positions in field variables. (like currentPos1, currentPos2)
the listeners onItemSelectedListener() call a method like refreshMyResult() or whatever.
when setting positions programmatically, set the spinners and call your own refresh method manually right after that.
The refreshMyResult() method looks like this:
int newPos1 = mySpinner1.getSelectedItemPosition();
int newPos2 = mySpinner2.getSelectedItemPosition();
// only do something if update is not done yet
if (newPos1 != currentPos1 || newPos2 != currentPos2) {
currentPos1 = newPos1;
currentPos2 = newPos2;
// do whatever has to be done to update things!
}
Because the listeners will be called later - and by then, the remembered position in currentPos is already updated - nothing will happen and no unnecessary update of anything else will take place.
When a user selects a new value in one of the spinners, well - the update will be performed accordingly!
That's it! :-)
Ahh - one more thing: the answer to my question is: No.
The listeners cannot be disabled (easily) and will be called whenever a value is changed.
I have an easier, and I think, better solution. Since I had to refresh the spinners even after initialization, this is a more generic approach.
Please refer the accepted answer:
Undesired onItemSelected calls
First add boolean values for stopping spinner listener call
Boolean check = false;
Then you add on Touch listener and on Item click Listener Like below code
holder.filters.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
check = true;
return false;
}
});
holder.filters.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
#Override
public void onItemSelected(AdapterView<?> parent, View arg1, int position, long id)
{
flag = filterids.get(position);
if(check)
{
check = false;
new Applyfilters().execute(flag,"3");
}else{
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0)
{
// TODO Auto-generated method stub
}
});
Its simple working good for stopping server call multiple times.
It is very easy you can call the Spinner.setSelection(int position, boolean animate) method with false so the listeners will not react on the change.
Spinner.setSelection(int position, boolean animate) does trigger the listener on 4.3
I created a library that help for all, that no need to call item onClick action in Spinner
For example:
spinner.setSelection(withAction,position);
where withAction is a boolean flag, that used for call or not item action
Link on Github:
https://github.com/scijoker/spinner2
My solution is very easy. First initialize a global boolean variable.
boolean shouldWork = true;
Then use below code in your onCreate() method.
Spinner spinner = findViewById(R.id.spinner);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
if (shouldWork) {
// Do your actions here
}
else
shouldWork = true;
}
public void onNothingSelected(AdapterView<?> parentView) {
}
});
Now you can use the setSelection method in everwhere without invoking the onItemSelected() method by below code.
shouldWork = false;
spinner.setSelection(0);
Add the OnItemSelectedListener for each spinner after you have set any previous value in onResume.
When Spinner.setSelection(position) is used, it always activates setOnItemSelectedListener()
To avoid firing the code twice I use this solution:
private mIsSpinnerFirstCall=true;
...
Spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
//If a new value is selected (avoid activating on setSelection())
if(!mIsSpinnerFirstCall) {
// Your code goes gere
}
mIsSpinnerFirstCall = false;
}
public void onNothingSelected(AdapterView<?> arg0) {
}
});
This solution is valid when you are sure that Spinner.setSelection(position) us used. Also, it is important to set mIsSpinnerFirstCall=true each time before using Spinner.setSelection(position)
In my case, since I'm triggering spinner programmatically, then I just have to add spinnerSelected flag after spinner.performClick() like below.
private var spinnerSelected = false
someView.setOnClickListener {
spinner.performClick()
spinnerSelected = true
}
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
// do nothing
}
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
if (spinnerSelected) {
//... do something
spinnerSelected = false
}
}
}
This following method will help you to stop invoking automatically the selection listener
yourspinnerobj.post(new Runnable() {
#Override
public void run() {
yourspinnerobj.setOnItemSelectedListener(yourspinnerlistener);
}
});
This is my answer: spinner.setClickable(false); tell spinner that this is not a clickable event before executing the setSelection function, and then use spinner.setClickable(true); to restore it after the setSelection function is executed. after the setSelection function is executed. On the other hand, it can also prevent the user from clicking on the spinner during the execution of the setSelection function, although the chance of this is too small, but it should be handled in the code.
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id){
if(!selectFridaSpinner.isClickable())return;
}
spinner.setClickable(false);
spinner.setSelection(2);
spinner.setClickable(true);
There are a lot of options on how to define a click/tap on the touchscreen. One of them for example is setting a boolean.
Example for boolean:
boolean buttonClicked = true;
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (buttonClicked) {
//do that and this
}
}
});
And there's a isPressed() method:
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (button.isPressed()) {
//do that and this
}
}
});
What exactly is the difference between them? And when and why do I use boolean and the method isPressed()?
Because you are referring to a button in both of your examples, I assume that you are referring to the user tapping on a button, not just a random touch on the screen.
That being said, both of the examples you provided are not good.
In your first example, the boolean is useless because it is always true, so //do that and this will always be reached.
In your second example, your if statement is useless, because the onClick method by its nature is only reached when the button is tapped.
A good way to listen for a button press is using a click listener like this:
Button button = (Button) findViewById(R.id.buttonId);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Code placed here will run every time the button is tapped
}
});
...where R.id.buttonId is the ID of your button in the layout.
If you need to define click event for a View you can use onClickListener, onTouchListener.
For more information check for Android official Documentation.
onTouchListener
onTouchListener
When considering your first code snippet, You can use boolean to perform another operation on button click event. as example something like this ,
boolean buttonClicked = false;
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//true after button clicked
buttonClicked = true;
}
});
//if buttonClicked equals true
if (buttonClicked){
//perform operation only after button clicked
}
when considering your second code snippet, no need of button.isPressed() inside
button's onClick() callback. Because what you want to do by checking button.isPressed() is done without it inside button's onClick() callback.
Keep in mind these things.
isPressed() is a public method of View Class
Button is a subclass of View Class
isPressed() is a public method of Button Class as well.
About isPressed() from Android official documentation.
Indicates whether the view is currently in pressed state. Unless
setPressed(boolean) is explicitly called, only clickable views can
enter the pressed state.
Returns true if the view is currently pressed, false otherwise.