Android Button listener implementation - java

Hey guys i'm new in Android's dev and for a project, I have to implement a listener for a button.
But unfortunately, he can't detect the button I think.
Here is the java code :
public class Touch extends AppCompatActivity implements OnTouchListener,OnClickListener {
private button boutonCompteur = null;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.id.Compteur);
boutonCompteur = (button) findViewById(R.id.Compteur);
boutonCompteur.setOnTouchListener(this);
boutonCompteur.setOnClickListener(this);
}
#Override
public boolean onTouch(View v, MotionEvent event)
{
return true;
} }
and here is the XML :
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="appuyez ici pour compter votre nombre de touch"
android:id="#+id/Compteur"
android:height="130dp"
android:textColor="#1818e3"
android:textColorHighlight="#cd5555"
android:textSize="22dp"
android:textStyle="italic"
android:layout_marginTop="150dp"
android:layout_alignParentStart="true" />
Thanks for your answers :)

I am going to use some visual help to answer your question and identify why is not working...
take a look at the image below and note:
You need a layout for your activity and this is not the same as the button
You need to find the button in the layout, that is odne by the id you used in the xml file, and is not the same as the Layout!!
you need to set the rigth listener to get the onclick, android has for that the OnClickListener interface
the word button between parenthesis is a casting, (android will try to convert something to a class, therefore the class is the class button, and not the name of your variable)
all the code that you write inside the onClick is what will be executed once the button is pressed.
Conclusion
Take the image as a reference and implement it in your code.

Remove onTouch , use onClick only.
Remove this line
boutonCompteur.setOnTouchListener(this);
and change public boolean onTouch(View v, MotionEvent event) to
public void onClick(View v) {
// Do whatever you want
}
And also change private button boutonCompteur = null; to private Button boutonCompteur; . (I don't think you need to add =null when doing button declaration).

Related

An OnClickListener for DrawableLeft in an EditText?

I am trying create an OnTouchListener to my editText ("search").
I took the code from post : Click listener for drawableleft in EditText in Android?
(Along with other posts) I am getting an error saying
Custom view EditText has set OnTouchListener called on it but does not
override PerformClick
Not quite sure where to go from here, as there is not much written about this that I can find. Thanks from your help!
search.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
final int DRAWABLE_LEFT = 0;
if(event.getX() <= (search.getCompoundDrawables()[DRAWABLE_LEFT].getBounds().width()))
{
// your action here
return true;
}
return false;
}
});
Thanks
You can suppress the error by using #SuppressLint("ClickableViewAccessibility")
Check out this question for more information on your error.

BindingAdapter with lambda as argument

With Android databinding, I can do the following:
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="#{() -> viewModel.onClick()}" />
My ViewModel does not have to implement OnClickListener, but just have a method:
public void onClick() {
}
What it passes to the onClick attribute in the Xml looks like a lambda to me.
How can I do this with my own BindingAdapters?
What I want:
Let's assume I want to bind touch events and I want to pass the MotionEvent, I would imagine this to look in the Xml like this:
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:onTouch="(view, event) -> viewModel.onTouch(event)" />
and the BindingAdapter something like:
#BindingAdapter("onTouch")
public static void onTouch(View view, ??? lambda) {
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(final View v, final MotionEvent event) {
return lambda(event);
}
});
}
I do not want my ViewModel to implement OnTouchListener and bind it like:
#BindingAdapter()
public static void onTouch(View view, View.OnTouchListener onTouchListener) {
view.setOnTouchListener(onTouchListener);
}
and I do not want bind the touch event directly to my ViewModel like:
#BindingAdapter()
public static void onTouch(final View view, final MyViewModel myViewModel) {
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(final View v, final MotionEvent event) {
return myViewModel.onTouch(view, myViewModel);
}
});
}
Is this possible with Databinding?
As you want it to work like the built-in onClick, let's take a look at the official binding adapter for onClick attribute:
#BindingAdapter({"android:onClick", "android:clickable"})
public static void setOnClick(View view, View.OnClickListener clickListener, boolean clickable) {
view.setOnClickListener(clickListener);
view.setClickable(clickable);
}
As you can see, the binding adapter doesn't take a lambda as argument, it takes a listener. But you can pass a lambda to it in xml (since it is a single method interface)
So here is the binding adapter you need: (I chose another attribute name, since onTouch is already used by framework)
#BindingAdapter("onImageTouch")
public static void onImageTouch(View view, View.OnTouchListener onTouchListener) {
view.setOnTouchListener(onTouchListener);
}
This is how you use it in xml:
app:onImageTouch="#{(view, event) -> viewModel.onImageTouch(event)}"
And here is the corresponding method in viewmodel:
public boolean onImageTouch(MotionEvent event){
Timber.e("OnImageTouch is called");
return true;
}
(It does nothing, but notice that it should return a boolean because onTouch callback returns a boolean.)
You don't need to implement OnTouchListener in your viewmodel or activity. This works very similar to the example with onClick that you gave in the beginning.
Let me note that there is already a built-in binding adapter for onTouch attribute, but I guess it was just an example and you in fact want to learn how to make custom ones. But be careful not to choose attribute names that already exist in the framework, to avoid any clashes.
You can use a lambda with your own method if it returns a boolean, and use the attribute app:onTouchListener. No custom BindingAdapter needed.
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:onTouchListener="(view, event) -> viewModel.onTouch(event)" />
android:onTouch also works but you get an Unknown attribute lint warning
It is possible to pass data to your view model however you also have to pass view along with data. so in your case. what you need to do is as follow.
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="#{() -> viewModel.onClick(view.someData)}" />
And in your View Model.
public void onClick(View v,String someData) {
}

I cannot implement OnTouchListener to drag a PopUp Window

I want to drag my PopUpWindows. So I tried to implement the demo App to drag a simple PopUp Window from here:
https://questdot.com/android-popup-floating-window-tutorial/
The problem arises when I add the listener to the view
popVideospeedView.setOnTouchListener(new View.OnTouchListener():
then View.OnTouchListener() appears with a red underline and warns:
Class 'Anonymous class derived from OnTouchListener' must either be declared abstract or implement abstract method 'onTouch(View, MotionEvent)' in 'OnTouchListener'
it also rejects the #Override saying it cannot be overriden, and also says it cannot Resolve MotionEvent
Also, the library android.view.View.OnTouchListener from:
import android.view.View.OnTouchListener; is unused
My code is very similar to the code that runs from the link quoted, and their mini App compiles and works fine in the Android Studio SDK. But my code rejects
the implementation of the touch listener. What could I be doing wrong?
The code for my PopUp Window implementation is:
public void functionVideospeedPopupWindow() {
try {
LayoutInflater popVideospeedLayoutInflater = (LayoutInflater) LMMoviesMainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View popVideospeedView = popVideospeedLayoutInflater.inflate(R.layout.popvideospeed, null);
final PopupWindow popVideospeedPopupWindow = new PopupWindow(popVideospeedView, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, true);
popVideospeedPopupWindow.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.colorStone)));
popVideospeedPopupWindow.setOutsideTouchable(false);
popVideospeedPopupWindow.setFocusable(false);
Button videospeedCloseButton = (Button) popVideospeedView.findViewById(R.id.popvideospeed_closeButton);
popVideospeedPopupWindow.showAtLocation(popVideospeedView, Gravity.CENTER, 0, 0); // 8:Margin to the left?. 18 comienza el texto utube
popVideospeedView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// event code...
return true;
}
});
videospeedCloseButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
popVideospeedPopupWindow.dismiss();
}
});
} catch (Exception e){}
} // End of functionVideospeedPopupWindow()
The only difference that I notice with the example that runs is that their PopUp code is declared within the onCreate sector of the Class, while my PopUp Window code is located within a method that is started by the user later in the App. Is that a relevant difference? if so, then how or why?
Finally, in case that I add: OnTouchListener (or is it View.OnTouchListener?) in: implements of the Class, as in:
public Class ...etc. ... implements OnTouchListener, it underlines in red and warns:
Class 'MyMainActivity' must either be declared abstract or implement abstract method 'onTouch(View, MotionEvent)' in 'OnTouchListener'
I know that to implement the OnTouchListener interface, I should add a structure like:
public boolean onTouch(View v, MotionEvent event) {...
but how to proceed with a PopUp Window with an onTouch declared outside of the PopUp method?
Thanks a lot for any ideas and for your interest.
Solved! It turns out that Android Studio wasn't adding the library for the MotionEvent when I tried with Alt+Enter. So I manually added the library: import android.view.MotionEvent; and now View.OnTouchListener doesn't generate any warning. Thanks a lot for your help, and I hope this case can help somebody else to overcome this silly bug. Cheers

android - make textView invisible

When my app starts, the user needs to touch on the screen before the real action starts. I have a textView which gives the hint to touch the screen.
After the screen is touched, I want the text to get invisible. Right now the textView never disappears and always stays in the front.
public class MainActivity extends Activity implements OnGestureListener
{
public boolean touched = false;
TextView mMyView;
public void onTouch()
{
mMyView.setVisibility(View.GONE);
touched = true;
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
mMyView = (TextView)findViewById(R.id.textView6);
if(touched == true)
{
}
}
}
1.Always use if(something) if you want to see if it's true/false instead of writing if(something == true) [something is a boolian assigned with value true.]
2.If you point your views xml to a method using android:onClick like below,
<Button android:id="#+id/mybutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me!"
android:onClick="onTouch" />
.
What's the point of implementing OnGestureListener?
If i do this onCreate i initialize my view
View myView = findViewById(R.id.my_view);
3.If i really want a touch i will do this
myView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// ... Respond to touch events --> tv.setVisibility(View.INVISIBLE);
return true; // if you return false with this then the listener will not be called for the subsequent ACTION_MOVE and ACTION_UP string of events.
}
});
Now you can see in the 3rd ones parameter there is a MotionEvent, you can identify the motion ACTION_DOWN , ACTION_MOVE and ACTION_UP
Now think have you ever used them. You got an idea in your head about a touch so tried to use touch events .. But you don't use them. So it does the same as what onClickListner does in your case. If you want motions use that 3rd one i gave.
But simply you can use
// view is the background layout
myView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Do something here --> Hide your text tv.setVisibility(View.INVISIBLE);
}
});
Those view onClickListner or setOnTouchListener you can directly use them inside onCreate or keep them inside a method and you can call that method from onCreate. Why to keep a boolean? It's nothing major
Note i considered myView as the background layout not your textView , background is the one you click / touch
So now you changed the questions code several times and I hope it´s the final change. Only than my answer could help.
You have done this in your onCreate():
if(touched == true)
{
tv.setVisibility(View.INVISIBLE);
}
But this is executed directly and has nothing to do with you onTouch() method. Let´s assume your onTouch() works correctly. Make the TextView global:
TextView mMyView;
initialize it in onCreate():
mMyView = (TextView)findViewById(R.id.textView6);
and then hide it in onTouch():
onTouch(View view){
mMyView.setVisibility(View.GONE);
}
But you have to be sure that your method onTouch() works. You can make a Toast or a Log to check. You have to be sure that:
-The TextView is inside your layout xml that you set with setContentView(R.layout.activity_game);
-The onTouch() method is declared in your TextView's xml attribute
android:onClick="onTouch"
and set clickable of your TextView to true:
android:clickable="true";
EDIT
If you implement onGestureListener() I guess the touch event is consumed by the listener and your TextView did not recognize onTouch(). If you don´t do any gesture detection in your activity, then remove this implementation.
You are checking if screen was touched in onCreate() which is called only once at the start of the activity. Initialize TextView globally and set its visibility inside onTouch(View v, MotionEvent event)
Also your onTouch() isn;t correct. You should override public boolean onTouch(View v, MotionEvent event)
public class MainActivity extends Activity
{
public boolean touched = false;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
TextView tv = (TextView) findViewById(R.id.textView6);
tv.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
touched = true;
tv.setVisibility(View.INVISIBLE);
return true;
}
});
}
}
Instead of implementing OnGestureListener add a setOnTouchListener in your root view of your activity layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rlTestView"/>
For example rlTestView is your activity's root layout id, then use below code in your oncreate method
((RelativeLayout)findViewById(R.id.rlTestView)).setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
tv.setVisibility(View.GONE);
return true;
}
});`
Use the code below on the onCreate method and yes set the visibility as GONE instead of invisible. Also state the current visibilty of the TextView in the onTouch then set it to
tv.setVisibility(View.GONE);

How to go about having a button and a custom paint view on the same screen? android

I am pretty new to android and am trying to build an app where the user can draw a letter, press a button that connects a service that reads it, and then the letter is displayed back to them.
This is my main layout:
!(http://i58.photobucket.com/albums/g271/billmoney3/layout_zps71eb45ca.jpg)
I want the user to be able to draw in the blue area. I made the blue area a custom view called InnerDrawingView. I need help on how to organize the views and the OnTouchListener.
Right now I have this java code:
public class DoodleActivity extends Activity {
Button confirmButton;
EditText drawingResult;
InnerDrawingView innerView;
// on create
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_doodle); // main layout
// where the drawing happens
innerView = (InnerDrawingView) findViewById(R.id.innerDrawingView1);
innerView.setOnTouchListener(handleTouch);
...
...
// handle the touching of the inner view
private OnTouchListener handleTouch = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
drawingResult.setText("O RLY?!"); // just a test
return true;
}
}; // end of class
Is this the correct way to go about it? What kind of touch listener do I put in the InnerDrawingView class? Can I just call: innerView.onTouch() from inside my main activity's onTouch()? Or the onDraw() method? If someone could direct me to a good paint tutorial also that would help me a lot.
Thanks for the input.
You need to pull x and y from the "event" object. Then the code depends on your needs. You can connect a new point with the previous one (to make a segment) or just put it in the list. Pseudo-code:
public boolean onTouch(View v, MotionEvent event) {
innerView.submitNewPoint(event.getX()), event.getY());
return true;
}
If you want to handle multi-touch events you need to retrieve points count ( event.getPointerCount() ) and do something with coords from event.getX(i)/event.getY(i) (i - index of multi-touch event point).
Of cause you need to implement drawing of the points/segments/? list in the InnerDrawingView.
P.S. do not forget to make you fields private ;)

Categories

Resources