How to remove text formatting when pasting from clipboard on Android - java

Right now I am working on an Android application that requires allowing the user to cut copy and paste onto an editText fields. But when I copy a formatted string from other places (i.e. a string that is underlined) and paste it on to the editText field, it shows it as a formatted version. How do I remove this?
I have tried to add a textwatcher by adding addTextChangedListener, and in the after text change I just do edittext.setText(s.toString()+"") but this creates an infinite loop. :(
Please help! Thanks in advance.
Edit----
I have made some progress by setting setCustomSelectionActionModeCallback
editDestination_.setCustomSelectionActionModeCallback(new Callback() {
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {return true;}
#Override
public void onDestroyActionMode(ActionMode mode) {}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.removeItem(android.R.id.paste);
menu.removeItem(android.R.id.selectAll);
menu.add(0, CUSTOM_PASTE, 0, "Paste").setIcon(R.drawable.paste_ic);
return true;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case CUSTOM_PASTE:
edittext.setText(readFromClipboard(aContext_));
// Finish and close the ActionMode
mode.finish();
return true;
default:
break;
}
return false;
}
});
This is working pretty well until I realize there are two types of cut/copy/and paste on my phone. One is when the edit text is empty and I long click on the field. This bring up a popup menu. The other one is when there is text in the field, and when I long click, this bring up a cut/copy/and paste bar below my action bar. My code from above is only affecting the bar-below-action bar one. :(

PROBLEM :
The thing you are doing is creating an infinite loop because everytime you call setText(), again afterTextChanged() gets called (because you are changing the text inside the EditText.
SOLUTION :
Suppose the EditText is editTextToClearStyle
EditText editTextToClearStyle = (EditText)findViewById(R.id.youredittextname);
editTextToClearStyle.addTextChangedListener(new TextWatcher(){
public void afterTextChanged(Editable s) {
editTextToClearStyle.setTextAppearance(getApplicationContext(),R.style.normalText);
}

I have solved it.
I set a onLongClickListener to catch it before the popup-cut/copy/paste menu shows up.
CharSequence actions[] = new CharSequence[] {"paste"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
builder.setItems(actions, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
edittext.setText(readFromClipboard(aContext_));
}
});
builder.show();
Then if there is a string already present in the EditText, I return false to allow normal android system below-action-bar-cut/copy/paste function to work.

Related

there's no working way to disable the menu Copy / Past / Cut ? it keep showing java

i need Help, i'm working on a Simple Text Editor and i want to implement a custom Menu Copy Past Cut .. and more, but to do that i need to Hide the Original Menu, My problem is just in this Step of Hiding the original Menu (Copy.. Past..) it Kepp showing while using the common ways, such as the first bellow Code.
this way not working at all.
and also the way of disabling the long click (if disabling the Long click we can't select the Text) and if text not selected can't use my custom menu.
in some Application such as Code Editor, have this function :
so, which way i follow to implement this ? can you guide/help me plz ! bcz now all steps is ok for me (when selecting text my menu appear) But also the original Menu (copy past cut) appear and i want to disable it...
the Code Bellow not working and the screen shot show that
edittext.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
public void onDestroyActionMode(ActionMode mode) {
}
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return false;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
});
finally i got the solution with help of guide in web, and with my own search, no body wanted to share the solution with me.
after i got it, i want to share with you. maybe it helps someone.
the suggestions shared all not working, some will disable selecting texts and others also do this + not working on all api..
in my case the editText id is edittext1.
in your activity past the bellow code :
private class MyActionModeCallback implements ActionMode.Callback {
private Menu mMenu;
#Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
//After the menu is created, the object is obtained for subsequent operations
this.mMenu=menu;
mMenu.clear();
return true;
}
#Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
switch (menuItem.getItemId()){
}
return true;
}
#Override
public void onDestroyActionMode(ActionMode actionMode) {
}
}
and how to use it :
edittext1.setCustomSelectionActionModeCallback(new MyActionModeCallback());

Simple edit text?

I am getting the users information from an edit text. I do have a listener that gets their entered information after clicking submit, but I want to also get the entered info after clicking back or clicking somewhere else:
For example, if the users clicks on the black space, I want to get the text they entered. If they type "hello", and click back rather than "enter", I still want to get the text hello. If, however, they don't type anything, I don't care about their input. How can I achieve this?
Thanks,
Ruchir
First add these as a class variables
private String inputText;
private EditText yourEditText;
Get the instance of your EditText View
yourEditText = (EditText)findViewById(R.id.your_editText);
When a button is clicked, you can get the content of the EditText field like this
Button mButton = (Button)findViewById(R.id.m_button);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
inputText = yourEditText.getText().toString();
}
});
If a user press the Back button, you can get the input if any like this
#Override
public void onBackPressed() {
inputText = yourEditText.getText().toString();
super.onBackPressed();
}
Then check if there is any value assigned to your String variable
if(inputText.equals("") || inputText == null){
// there is no value
}else{
// there is value entered.
}
To extend my solution for clicking some where else
add a class variable
private boolean isEditTextHasFocus;
then create a focus listener which will check if the Edittext has focus
private View.OnFocusChangeListener focusListener = new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus){
isEditTextHasFocus = true;
} else {
isEditTextHasFocus = false;
}
}
}
Add this line in onCreate(Bundle savedInstanceState) method
yourEditText.setOnFocusChangeListener(focusListener);
Then override to onTouchEvent(MotionEvent event) listener and access the Edittext input when the key up action is called
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if(!isEditTextHasFocus){
inputText = yourEditText.getText().toString();
}
}
return true;
}
I hope this will give you a further idea to find your unique solution.
Overriding what happens when the back button is pressed is bad practice and is unnecessary for what you want to do.
You need to use a special listener called onFocusChangedListener. This function is called anytime an element gains or loses focus. In this case for your editText it will be called whenever someone clicks on it or away. Pressing the back button or leaving the editText in any way will call this function. In the following code I check if
if(!username.hasFocus())
which makes it so the value is only saved when focus from the editText is lost rather than everytime focus is changed.
You haven't added any of your own code so I am just going to use obvious placeholder variables in my code example.
Edittext username = (EditText findViewById(R.id.YOUR_EDITTEXTS_ID);
String previousValue = ""; // to keep track of value change
String usernameValue = "";
username.setOnFocusChangeListener(new View.OnFocusChangeListener(
{
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (username.hasFocus()){
//take note of value for comparison when clicking away
previousValue = username.getText().toString();
} else if (!username.hasFocus()){
// check if value has changed
if (!previousValue.equals(username.getText().toString()){
usernameValue = username.getText().toString();
}
}
}
});

How to fix Context Menu Bar functions (copy/paste etc) after calling setCustomSelectionActionModeCallback() on EditText?

I'm writing Notepad App in which I've got slider menu showing some text format panel. I toggle view of this panel when user tries to select some text, so I've implemented my menu-toggling code into my EditText's setCustomSelectionActionModeCallback() which looks like this:
private void manageContextMenuBar(EditText editText) {
editText.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return true;
}
// There menu is hidden
public void onDestroyActionMode(ActionMode mode) {
if (findViewById(R.id.sliderMenu).getVisibility() == View.VISIBLE) {
findViewById(R.id.sliderMenu).setVisibility(View.GONE);
}
}
// There menu shows up
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
if (findViewById(R.id.sliderMenu).getVisibility() == View.GONE) {
findViewById(R.id.sliderMenu).setVisibility(View.VISIBLE);
}
return true;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return true;
}
});
}
When I long click on text my format menu shows up, and also software context menu with paste/copy/cut button on it.
The problem is that because of my "Overriding" context menu functions, they stopped working. I can click the buttons, but they doesn't work.
I hope You will understand my problem
Any help will be appreciated :)
You should return false from onActionItemClicked method. This way when you click on those menu items Android uses the default actions.
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
From the onActionItemClicked method Documentation:
Returns: true if this callback handled the event, false if the standard MenuItem invocation should continue.

Popup menu appears blank

I am working on an app, in which I am want to use a pop-up menu to control some actions and settings. However, when I launch the app in my emulator, the items appear blank, although when I click on them, the action is fired and it works. Here is a screen of the emulator:
I am following the guide, so my code does not differ much from the dev guides, but here is my code:
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long ID)
{
// TODO Auto-generated method stub
courseId = ID;
fields = sqldbase.query(DBHelper.courseTable, new String[] {
DBHelper.courseID, DBHelper.courseName,
DBHelper.courseProf, DBHelper.averageGrade },
DBHelper.courseID + " = " + ID, null, null, null, null);
PopupMenu popup = new PopupMenu(getBaseContext(), view);
popup.getMenuInflater().inflate(R.menu.courses_popup_menu,
popup.getMenu());
popup.show();
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener()
{
#Override
public boolean onMenuItemClick(MenuItem item)
{
Log.i(TAG,"OnMenuItemClick Fired"); return false;
}
});
return false;
}
});
Could this be related to a problem with themes? I have been trying to use a Holo.light.NoTitleBar theme, so in my xml in eclipse, the word Passbook does not show, and everything is white, instead of black. However, after running in the emulator, the theme is ignored, and this shows up.
Thanks.
fixed it. apparently, popup menus use the attribute android:title instead of android:text.

TextView editable onLongClick -- But one small issue when BACK button pressed

I have been search SO for days and have finally compiled enough answers to accomplish what I wanted. First off, it seems to be an often asked question but not really answered (at least not the way I was looking for it). I thought I would share my findings but I also have one small issue left that I would like to ask for help with. Here goes:
I have a TextView which displays a score. It starts at 0 and at an onClick event the score increments and updates the TextView (score is tracked as a byte - valScore).
onLongClick: This was the challenge. I want the user to be able to do a LongClick to correct/change the score. I first found a solution that utilized another layout.xml file with just an EditText element and the OK and CANCEL buttons. This was very cumbersome to change the score as it involved the LongClick, then the dialog opens, then you had to click on the EditText element to open the keyboard, then you enter the value, click DONE and then click OK. I shortened it by figuring out how to open the software keyboard automatically when the dialog opened. However, you still had to click DONE and then OK. I didn't like this action so I continued searching.
Days later I came up with a bit of code and then more and with a lot of playing/hacking around I came up with the following solution:
// set the onLongClickListener for tvScoreHome
tvScoreHome.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
tvScoreHome.setInputType( InputType.TYPE_CLASS_NUMBER );
tvScoreHome.setFocusable(true);
tvScoreHome.setFocusableInTouchMode( true );
tvScoreHome.requestFocus();
InputMethodManager imm = (InputMethodManager) context.getSystemService(Service.INPUT_METHOD_SERVICE);
imm.showSoftInput(tvScoreHome, InputMethodManager.SHOW_FORCED);
tvScoreHome.setText("");
tvScoreHome.setOnEditorActionListener( new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
valScoreHome = Byte.valueOf( tvScoreHome.getText().toString() );
// This part will hide the keyboard after input
InputMethodManager imm = (InputMethodManager) context.getSystemService(Service.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
tvScoreHome.setFocusable( false );
tvScoreHome.setFocusableInTouchMode( false );
tvScoreHome.setText( Byte.toString(valScoreHome) );
return true;
}
return false;
}
});
return true;
}
});
This works EXACTLY how I want. User performs LongClick the keyboard opens, the user enters the new value and clicks DONE. The TextView is updated and it works great!
The problem arises if the user changes their mind and hits the BACK button on the device. The keyboard closes (GOOD), but then the focus remains on the TextView instead of removing the focus like I do if the DONE button is pressed. So if you cancel out of a change every click after that results in the keyboard opening again instead of just incrementing the score -- until you actually type a value into the keyboard and click DONE (then the regular behavior takes over again. I need to setFocusableInTouchMode to FALSE if the BACK button is pressed.
The other issue is that the setText() method is executed even if the BACK button is pressed if a different value has been typed in. Even though valScoreHome isn't updated the TextView changes. On the next increment it goes to the correct number again, but the setText() should not execute if the BACK button is pressed.
Can someone help me figure this out please?
Both issues can be handled by subclassing TextView.
The back button press that closes the keyboard is handled by overriding onKeyPreIme.
To avoid updating the text when the user closes the keyboard, the score value is saved in the variable mScore, but only if the TextView is currently not focusable. That means, the TextView "remembers" the current value of the score, that was not entered by the user. When the user closes the the keyboard, the text is set back to the saved value.
public class ScoreTextView extends TextView {
private CharSequence mScore;
public ScoreTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void setText(CharSequence text, BufferType type) {
if (!isFocusable()) {
mScore = text;
}
super.setText(text, type);
}
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
setFocusable(false);
setFocusableInTouchMode(false);
setText(mScore);
}
return super.onKeyPreIme(keyCode, event);
}
}

Categories