My Question is lightweight. I wish to know how do I set a click event inside an EditText also determining which drawable or word is pressed. Basically I have an EditText that can contain word-wrapped drawables or static text.
So I'm expecting something like this:
editText.setOnCustomPressListener(new OnCustomPressListener(){
void onWordTapped(String text){
}
void onAttachmentTapped(CharSequence ch){
}
})
Please help, I've been looking for weeks.
Are you looking for this?
mEditText.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
It would be good to see more code (your xml)
This is not ideal but this is working anyway.
editText.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
int startSelection = editor.getSelectionStart();
int endSelection = editor.getSelectionEnd();
String selectedText = editor.getText().toString().substring(startSelection, endSelection);
AppConfig.quicktoast(selectedText);
}
return false;
}
});
Related
I am trying to make a simple app: there is one button in the middle which a child would press. As long as that button is held down it would play a certain MP3.
At the moment, I tried with onClick, but, that plays only when the button is released.
Instead of using an onClickListener which exposes nothing more then an interface for press and release, you would need to use an onTouchListener - which exposes all touch events of a view.
myButton.setOnTouchListener( new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch ( event.getAction() ) {
MotionEvent.ACTION_DOWN:
// start playing
return true;
MotionEvent.ACTION_UP:
// stop playing
return true;
}
return false;
}
});
Try something like this. Using the boolean "playing" you can create a thread/loop elsewhere to check if still playing and keep audio going.
button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
if (arg1.getAction()==MotionEvent.ACTION_DOWN) {
playing = true;
} else {
playing = false;
}
return true;
}
});
Try the OnFocusChangeListener
Button.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
// code to execute when Button loses focus, i.e. stop music
}
}
});
Since a button is a view component you can use View.OnTouchListener event listener with ACTION_BUTTON_PRESS & ACTION_BUTTON_RELEASE MotionEvent.
Here is an example:
yourButton.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_BUTTON_PRESS){
// Start Video
return true;
} else if (event.getAction() == MotionEvent.ACTION_BUTTON_RELEASE) {
// End Video
return true;
}
return false;
}
});
This is my code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void start_recording(View view){
MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.test1);
mediaPlayer.start();
}
}
i have to decrease a counter When a char is written , but my code is decreasing two chars Instead of one but Only When delete key is pressed , but if
if I press another key does not work
private Button send;
private TextView max;
private TextView msg;
int limit=140;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
max = (TextView) findViewById(R.id.max);
send = (Button) findViewById(R.id.send);
msg = (TextView) findViewById(R.id.msg);
msg.setOnKeyListener(this);
}
#Override
public void onClick(View view) {
}
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
max.setText(String.valueOf(limit--));
return false;
}
The problem is that onKey is called twice, once for down and one for up.
You can use another method such as onKeyDown:
onKeyDown documentation
public boolean onKeyDown(int keyCode, KeyEvent event) {
return super.onKeyDown(keyCode, event);
}
Or use a filter using onKey.
onKey gets fired twice. Once when the key is pressed down, and once when it is released.
Or you can try:
onKeyDown()
onKeyUp()
KeyEvent.getAction().
In this java image, you can see that the person made both a released and a pressed method. This picture is for java, but the concept for android is the same. Use the methods I gave you in that numbered list.
Otherwise, right now, you are listening for two events.
On the right is key pressed, and the left is key released:
If this was helpful, please mark as best answer. If you need more help, let me know!
Okey i have found the answer,
first of all msg is not a TextView, is a EditText
and then we can use addTextChangeListener.
thanks all of you who responds
private Button send;
private TextView max;
private EditText msg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
max = (TextView) findViewById(R.id.max);
send = (Button) findViewById(R.id.send);
msg = (EditText) findViewById(R.id.msg);
msg.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
max.setText(String.valueOf(140- (msg.getText().toString().length())));
if(msg.getText().toString().length()>=140){
send.setEnabled(false);
}else
send.setEnabled(true);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
#Override
public void onClick(View view) {
}
I have looked at many posts and similiar questions have been asked. But none of the solution is working. First of all I've tried using onKeyListener, but in many posts, it is stated that it does not work for soft keyboard. So I tried to use TextWatcher instead, but it still does not printout anything.
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback{
private MainThread thread;
private EditText editText;
private Bitmap textBitmap;
public GamePanel(Context context){
super(context);
//Add callback to the surfaceview to intercept events
getHolder().addCallback(this);
//Make GamePanel focusable so it can handle events
setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,int width, int height){}
#Override
public void surfaceDestroyed(SurfaceHolder holder){}
#Override
public void surfaceCreated(SurfaceHolder holder){
editText = new EditText(getContext());
editText.setSingleLine(true);
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setDrawingCacheEnabled(true);
editText.layout(0, 0, WIDTH - 200, 100);
editText.buildDrawingCache();
textBitmap = Bitmap.createBitmap(editText.getDrawingCache());
thread = new MainThread(getHolder(), this);
//Start the game loop
thread.setRunning(true);
thread.start();
/*editText.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
Toast.makeText(getContext(), "ABCD", Toast.LENGTH_SHORT).show();
System.out.println("KEY PRESSED");
}
return true;
}
});*/
/*editText.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
System.out.println("KEY PRESSED");
}
#Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
System.out.println("KEY PRESSED");
}
});*/
editText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
System.out.println("ABC");
return true;
}
return false;
}
});
}
#Override
public boolean onTouchEvent(MotionEvent event){
if(event.getAction() == MotionEvent.ACTION_DOWN ){
editText.setFocusableInTouchMode(true);
editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
//imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
return true;
}
return super.onTouchEvent(event);
}
#Override
public void draw(Canvas canvas){
if (canvas != null) {
canvas.drawBitmap(textBitmap,50,50,null);
canvas.restoreToCount(savedState);
}
}
Does drawing EditText with canvas.drawBitmap have anything to do with those solutions not working? Or is there any mistakes on implementing them?
Any solutions are welcomed, need explanations if possible. Thanks!
EDIT : tried to use onEditorActionListener
First of all check
Did you include this line in your xml inside the EditText
android:singleLine="true"
if not, please add it first.
Next for e.g i wanna use Done button inside my soft keyboard, than here is what you can do.
<EditText
android:id="edName"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:singleLine="true" //this line to take input in single line (if you don't include this line, Done button will not take any actions)
android:imeOptions="actionDone"/> //this line to provide done button
Now to take the input from keyboard for done button, add this code after findViewById in your onCreate
//TODO softKey "Done" listener for keyboard
edName.setOnEditorActionListener(new EditText.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
//Do what you want here
return true;
}
return false;
}
});
I'm doing a calculator for fun, the code is in this post:
Start of activity not working Java
I have many buttons in my calculator, and one of them is a button that i want to use to clear the last charater of text in the textbox when i click and when i press it for more that x seconds i want it to clear all the text.
I've searched for many posts and i learned that the OnTouch method using handler is good for things that are being pressed, but how can i implement both things for my button?
Thanks in advance for the answers!
UPDATE
I used the Onclick listener and OnLongClick listener and it works exactly as i want!
You just want to set a View.OnClickListener, and a View.OnLongClickListener, like so:
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String s = mEditText.getText().toString();
if (s != null && s.length() > 0) {
mEditText.setText(s.substring(0, s.length()-1));
}
}
});
mButton.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
mEditText.setText("");
return true;
}
});
Do this:
Button myClearButton;
//After doing myClearButton = findViewById(int id) or other methods of getting your button call this method:
setClearButtonClickListeners(){
myClearButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
clearLastChar();
}
});
myClearButton.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
clearAllChars();
return true;
}
});
}
Just implement the clearLastChar() and clearAllChars() methods;
clearButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clear();
Toast.makeText(HomeSafeActivity.this, "Normal Press", Toast.LENGTH_LONG).show();
});
clearButton.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Toast.makeText(HomeSafeActivity.this, "Long preess", Toast.LENGTH_LONG).show();
yourEditText.setText("");
return true;
}
});
public void clear(){
Editable editableText = yourEditText.getEditableText();
int length = editableText.length();
if (length > 0) {
editableText.delete(length - 1, length);
}
}
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//
}
});
btn.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//
return true;
}
});
I have an app where you can press on a screen and a method gets executed, and where you can long press and another method gets executed. The problem is, when I long press on the screen the normal onClickListener also gets executed, which I don't want.
They both are simple onClickListeners, the normal one is using the MotionEvent ACTION_UP. Is there any way to prevent that from happening?
So I don't want to execute the ACTION_UP in the normal onTouchListener when the onLongClickListener executed.
Code:
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
}
return false;
}
});
layout.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
return true;
}
});
If you still want to onTouch
int flag=0
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if(flag==0){
//do something
}else{
flag=0;
}
}
return false;
}
});
layout.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
flag=1
return true;
}
});
LongClick and Click are in the same level, while Touch isn't (actually LongClick an Click are dispatched from onTouchEvent).
In your code, you always return false in onTouch method, so you don't comsume the event and it will be passed to the next level (LongClick, Click...), this is why when you long press the screen you have the both method called.
Suggestion1:
Use ClickListener instead of TouchListener.
Suggestion2:
Use GestureDetector to handle all events (touch, longclick...). This is an example
Suggestion3:
Use a flag to perform the desired event.
private boolean longClick = false;
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (longClick) {
longClick = false;
}
return false;
}
});
layout.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
longClick = true;
return false;
}
});
Suggestion4:
Use a handler with runnable. Example1 and Example2
If onclick does the same as you intended use onclick listner instead of ontouch that way you wont trigger onclick when you longclick.