Is there a way to allow the user to select / copy text in a TextView? I need the same functionality of EditText where you can long-press the control and get the popup options of select all / copy, but I need the control to look like a TextView.
Tried a few things like making an EditText use the editable="none" option or inputType="none", but those still retain the framed background of an EditText, which I don't want,
Thanks
------- Update ----------------------
This is 99% there, all I'd want is for the selection hilight to be visible (the orange stuff). Other than that it's good, could live with this though:
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:editable="false"
style="?android:attr/textViewStyle"
android:textColor="#color/white"
android:textAppearance="#android:style/TextAppearance.Medium"
android:cursorVisible="false"
android:background="#null" />
I guess it's being caused because of cursorVisible="false" but without that the cursor is present even without any selection being made.
android:textIsSelectable works (at least in ICS - I haven't yet checked in earlier versions)
<TextView
android:id="#+id/deviceIdTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:text="" />
Text View needs to be enabled, focusable, longClickable and textIsSelectable
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="#+id/pwTextView"
android:enabled="true"
android:textIsSelectable="true"
android:focusable="true"
android:longClickable="true" />
I think I have a better solution.
Just call
registerForContextMenu(yourTextView);
and your TextView will be registered for receiving context menu events.
Then override onCreateContextMenu in your Activity
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
//user has long pressed your TextView
menu.add(0, v.getId(), 0, "text that you want to show in the context menu - I use simply Copy");
//cast the received View to TextView so that you can get its text
TextView yourTextView = (TextView) v;
//place your TextView's text in clipboard
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
clipboard.setText(yourTextView.getText());
}
Hope this helps you and anyone else looking for a way to copy text from a TextView
textview1.setTextIsSelectable(true);
This will enable user to select and copy text on long clicking or as we do usually
Using Kotlin Programmatically (Manual Copy)
button.setTextIsSelectable(true)
Or, add a Kotlin property extension
var TextView.selectable
get() = isTextSelectable
set(value) = setTextIsSelectable(value)
Then call
textview.selectable = true
// or
if (textview.selectable) { ...
Using Kotlin Programmatically (Auto-Copy)
If you want to auto-copy when user long-presses you view, this is the base code required:
myView.setOnLongClickListener {
val clipboardManager = context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("Copied String", myString)
clipboardManager.setPrimaryClip(clip)
true // Or false if not consumed
}
You may want to add a Toast to confirm it happened
Or, add a Kotlin extension function
myView.copyOnHold() // pass custom string to not use view contents
fun TextView.copyOnHold(customText: String? = null) {
setOnLongClickListener {
val clipboardManager = context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("Copied String", customText ?: text)
clipboardManager.setPrimaryClip(clip)
true // Or false if not consumed
}
}
Using Xml (Manual Copy)
Add this to your <TextView>
android:textIsSelectable="true"
NOTE: All of these require android:enabled="true" and android:focusable="true", which are the default values for a TextView.
I'm trying to implement the same, and your question helped me to set my editext layout correctly. So Thanks! :)
Then I realized, that the highlight will actually be visible if the cursor is on.
But I just like you do not want to see a cursor before long clicking on the text, so I hide the cursor in the layout.xml file just like you, and added an eventlistener for long click and display the cursor only when a selection starts.
So add the listener in your Activity in the onCreate section:
public TextView htmltextview;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
...
htmltextview.setOnLongClickListener(new OnLongClickListener(){
public boolean onLongClick(View v) {
htmltextview.setCursorVisible(true);
return false;
}
});
}
And voilá, no cursor at the beginning, and if you long-click, the cursor appears with the selection boundaries.
I hope I could help.
Cheers,
fm
I was also trying to do something similar but still needed a custom approach with manipulation of highlighting of text in TextView. I triggered highlight and copying on LongClick action.
This is how I managed using SpannableString:
SpannableString highlightString = new SpannableString(textView.getText());
highlightString.setSpan(new BackgroundColorSpan(ContextCompat.getColor(getActivity(), R.color.gray))
, 0, textView.getText().length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(highlightString);
copyToClipboard(urlToShare);
and the copy function:
public void copyToClipboard(String copyText) {
ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("url", copyText);
clipboard.setPrimaryClip(clip);
Toast toast = Toast.makeText(getActivity(), "Link is copied", Toast.LENGTH_SHORT);
toast.show();
}
I hope it's helpful for someone who ends up on this question :)
I have found it doesn't work the first time I double click, but it works there after ( at least in android 11). This told me it needed to get focus. So, in the onCreate event, I first made the text view selectable, then I requested the focus to shift to the text view. Now I'm not saying the text view can lose focus and the first attempted selection will work. Not guaranteed. What is guaranteed is once it has focus, it'll work every time until it loses focus again. Don't forget about androids animations. So allow at least a half second for the non overridable animation to play out when the keyboard is hiding.
// In onCreate
TextView1.setTextIsSelectable( true );
// Allow animations to play out.
timer = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView1.requestFocus();
}
});
}
};
_timer.schedule(timer, (int)(1000));
}
Thanks a lot gilbot for your explanation. I just want to add another thing.
Selected text background color follows your app theme's colorAccent
For example check the image below
Here AppTheme is my application theme.
<item name="colorAccent">#color/cold</item>
and the colorAccent value will be the selected text background color.
Just use this simple library:
GitHub: Selectable TextView
Related
I'm trying to play around with some Kotlin and Anko (more familiar with iOS) and taking from their example, there is this code:
internal open class TextListWithCheckboxItem(val text: String = "") : ListItem {
protected inline fun createTextView(ui: AnkoContext<ListItemAdapter>, init: TextView.() -> Unit) = ui.apply {
textView {
id = android.R.id.text1
text = "Text list item" // default text (for the preview)
isClickable = true
setOnClickListener {
Log.d("test", "message")
}
init()
}
checkBox {
id = View.generateViewId()
setOnClickListener {
Log.d("hi", "bye")
}
init()
}
}.view
My row appears how I want with a checkbox and textview. But I want to bind an action to the row selection not the checkbox selection. Putting a log message in both, I see that I get a log message when the row is selected which flips the checkbox. It does not, however, log my "test:message" from the textView click handler. Is there a way to get around this?
Apparently your issue has been addressed here. As the checkbox is consuming all the focus of ListItem you should set the CheckBox's focusable flag to false:
checkBox {
focusable = View.NOT_FOCUSABLE
}
Unfortunately setFocusable call requires at least API 26, but you could define view .xml and inflate the view manually as described here:
<CheckBox
...
android:focusable="false" />
Alternatively you could try setting a onTouchListener returning false which means the touch event will be passed to underlying views.
Let me know if it works ;)
I'm trying to develop an unconventional keyboard, I need to change the text in a key, depending on the combination of other keys pressed.
Like Candidates View but inside the keyboard, in one key.
I wonder if I can change the text on a key , or if I can use a different layout to the Keyboard XML.
my keyboard is based on the Soft Keyboard app example and can be referred to at this link .
You can use the Tags for your View, so you can use the setTag/getTag mechanism when pressing it..
private final View.OnClickListener myListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if (v.getTag() != null) {
if (v.getTag() instanceof String) {
getCurrentInputConnection().commitText((String) v.getTag(), 1);
} else {
Log.v(TAG, "(v.getTag() instanceof String) == false");
}
} else {
Log.e(TAG, "(v.getTag() != null) == false");
}
}
};
And the XML example of a key:
<Button
android:id="#+id/aButton_N"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:tag="n"
android:text="n"
android:onClick="myListener"
android:textAllCaps="false" />
An example of alteration:
Button myBt = (Button) findViewWithTag("n");
myBt.setTag("N");
For all other purposes, remember that the "KeyboardView" is a facilitator. In your View, you can add any child of a View, so Buttons, ImageViews etc will work.
If you need the "image" (the Bitmap) that the KeyboardView uses, then you can "redrawn" (by overriding the onDrawn() function) of your keyboard, and make any alteration needed for keys or its layout...
Do note, that Keyboard, Keyboard.Key, etc. are all facilitators, for speed, low memory usage, and draw "easiness", by altering the layout, you can use anything with it, so ScrollViews / LinearLayouts / Framelayouts can greatly simplify your program/Views, but they use a bit more memory, check if your program can make this choice.
Edit:
A Button object, has several attributes. Its displaying text is a String, use button.getText().toString() to fetch it. A Tag, is a "pointer" to an Object of any kind.... if you want to writte the current text of the button, and use another related system, you can use the following:
private final View.OnClickListener myListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Button thisButton = (Button) v;
getCurrentInputConnection().commitText(thisButton.getText().toString(), 1);
}
};
And to change the "content" of the button:
Button aButton = (Button) findViewById(YOUR.ID.HERE);
aButton.setText("a new long string to replace the old value.");
And sorry for bad english, if something is hard to understand, please, let me know
You can get all keys like that
List<Keyboard.Key> keys = mKeyboardView.getKeyboard().getKeys();
By proper event you can change key's icon or label, check Keyboard.Key.
You can try using the android:keyboardMode available as part of Keyboard.Row, it selectively displays row based on the mode you are in. So you can create multiple modes with different rows (keys with different values and functions).
Here is the link for reference.
I am working on Android Smart TV application:
In a view there is a custom keyboard and an EditText.
When application launches focus goes to the keyboard.
Desired:
When the user types with keyboard (clicking with a remote) the cursor should also blink inside the editText.
How can I show this effect inside the EditText?
This happens if you set a background for the field. If you want to solve this, set the cursorDrawable to #null.
You should add textCursorDrawable with cursorVisible.
Reference to a drawable that will be drawn under the insertion cursor.
android:cursorVisible="true"
android:textCursorDrawable="#null"
You could try something like this:
editText.setText(text);
editText.setPressed(true);
editText.setSelection(editText.getText().length()); // moves the cursor to the end of the text
However, there are 2 problems with this approach:
The cursor will not blink. The logic for the blinking is in the Editor class and cannot be overridden. It requires that the EditText is focused, and only 1 View can be focused at once within a Window - in your case that will be one of the keyboard buttons.
/**
* #return True when the TextView isFocused and has a valid zero-length selection (cursor).
*/
private boolean shouldBlink() {
if (!isCursorVisible() || !mTextView.isFocused()) return false;
...
}
The cursor will not always be visible. The blinking of the cursor is based on the System time - it is visible for half a second, and hidden for the next half a second. The cursor will only be visible if the code I suggested above is called at a point in time when the cursor would be visible according to the System time.
This is why the native keyboard/IME works the way it does. It is a separate Window that allows the EditText to maintain focus and have the blinking cursor functionality, while the user is tapping on Views in a different Window (the keyboard/IME).
That being said, there is a workaround for the problems above - make sure to set shouldBlink to false when you no longer need it though, it's a guaranteed memory leak or crash otherwise:
private void blink() {
if (shouldBlink) {
editText.setText(editText.getText());
editText.setPressed(true);
editText.setSelection(editText.getText().length());
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if (shouldBlink) {
blink();
}
}
}, 500);
}
}
You can do this..I hope/think that u have a layout for the buttons u have created, by this u can set a Focus Listener for that layout and inside the onFocusChange method you can check if(layout.hasFocus()) and do this...
For example if your editText is named as et, u can set this to it:
et.setActivated(true);
et.setPressed(true);
I have a small example code for you having two edit text
et2.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(et2.hasFocus()){
//et1.setCursorVisible(true);
et1.setActivated(true);
et1.setPressed(true);
}
}
});
In your layout xml file add the following line in your edit text:
<requestFocus/>
This will place the cursor in your editText widget.
Hope it helps.
simply add
editText.requestFocus();
There is a couple of ways doing it:
1) XML
android:cursorVisible="true"
2) Java
mEditText.setOnClickListener(editTextClickListener);
OnClickListener editTextClickListener = new OnClickListener() {
public void onClick(View v) {
if (v.getId() == mEditText.getId()) {
mEditText.setCursorVisible(true);
}
}
};
or
if (mEditText.hasFocus()){
mEditText.setCursorVisible(true);
}
I know this is necro, but this was much better than the solutions above. Just extend EditText and add:
#Override
public boolean isCursorVisible() {
return true;
}
#Override
public boolean isFocused() {
return true;
}
And in your XML:
<com.foo.MyEditText
...
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
android:cursorVisible="true"/>
Now the EditText thinks it is focused and the cursor is visible, but it actually can't be focused.
private void setFocusCursor(){
mBinding.replyConversationsFooter.footerEditText.setFocusable(true);
`mBinding.replyConversationsFooter.footerEditText.setFocusableInTouchMode(true);`
`mBinding.replyConversationsFooter.footerEditText.requestFocus();`
}
Just call this function in oncreateView() and there you go.
We can only set one and only focus on a window.So doing this will help you solve your problem.
You can use the following code in your Activity:
//Get the EditText using
EditText et = (EditText)findViewById(R.id.editText);
//Set setCursorVisible to true
et.setCursorVisible(true);
You can explicitly put caret to last position in text:
int pos = editText.getText().length();
editText.setSelection(pos);
This will always focus on first character on edittext.
android:focusable="true"
Tested on API 27, 28 emulator.
Remove a background attribute, add focusable:
<EditText
...
android:focusable="true"
android:focusableInTouchMode="true"
/>
In code write: edit.requestFocus(); Though an underline will be visible.
In order to remove an underline, see https://stackoverflow.com/a/52052087/2914140:
edit.getBackground().mutate().setColorFilter(ContextCompat.getColor(getContext(), R.color.white), PorterDuff.Mode.SRC_ATOP);
To change a color of the cursor see https://stackoverflow.com/a/49462015/2914140:
add android:textCursorDrawable="#drawable/shape_cursor", while shape_cursor is:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size
android:width="1dp"
android:height="25dp"
/>
<solid android:color="#color/gray" />
</shape>
It works on API 27, 28 emulator, but on a real device (API 21) cursor disappears. I tried many variants from here and there, but nothing helped.
Then I noticed that when EditText contains at least one symbol, it shows cursor. I added a TextWatcher to add a space when nothing entered.
private lateinit var someText: String
...
edit.requestFocus()
edit.setText(" ")
edit.addTextChangedListener(YourTextWatcher())
private inner class YourTextWatcher : TextWatcher {
override fun afterTextChanged(s: Editable?) {
someText = s.toString().trim()
if (someText.isEmpty()) {
// To not fall into infinite loop.
if (s?.length != 1) {
edit.setText(" ")
}
} else {
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
}
Also you can add paddings in order to tap inside EditText, if it is small.
I did like this:
var msgEditText = dialog.findViewById(R.id.msg1textView) as EditText
msgEditText.isActivated = true
msgEditText.isPressed = true
msgEditText.requestFocus()
msgEditText.setSelection(view.getText().length)
I have a dropdown spinner which is showed when click on a button looks like this:
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Spinner
android:id="#+id/spinMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:spinnerMode="dropdown"
android:visibility="invisible" />
<ListView
android:id="#+id/lvWall"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Here is snippet showing dropdown popup:
findViewById(R.id.btn).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
spinMenu.performClick();
}
});
My spinner can show dropdown popup correctly. The problem is my layout has a listview which getting data from web service in background. When data is loading completely, all list items will be showed or refreshed, and the spinner's dropdown popup is dismiss (I even don't touch anything on screen). I think the problem is window has changed focus on other view. So how can I prevent it?
Update:
Here is my list after load data from background, it's very simple:
List<Feed> data = result;
FeedAdapter adapter = new FeedAdapter (this, data);
ListView lvWall = (ListView)findViewById(R.id.lvWall);
lvWall.setAdapter(adapter);
And data for spinner:
List<String> list = getMenus();
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinMenu.setAdapter(dataAdapter);
If I understand correctly, you have a Spinner view which you set as invisible with the only purpose of showing the popup menu, but not the Spinner view itself. In that case, the problem is probably related to this snippet in Spinner.java, more precisely in DropdownPopup.show():
public void show(int textDirection, int textAlignment) {
...
super.show();
...
// Make sure we hide if our anchor goes away.
// TODO: This might be appropriate to push all the way down to PopupWindow,
// but it may have other side effects to investigate first. (Text editing handles, etc.)
final ViewTreeObserver vto = getViewTreeObserver();
if (vto != null) {
final OnGlobalLayoutListener layoutListener = new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (!Spinner.this.isVisibleToUser()) {
dismiss();
} else {
computeContentWidth();
...
What does this mean? Basically that the Spinner is set up with a ViewTreeObserver to be notified whenever a layout pass changes the views in the screen. And if the Spinner is not visible after that happens, the popup is dismissed. Loading the ListView evidently causes a change in the view hierarchy, and it's being fired when the data arrives from the server.
For general usage this is completely logical: if the Spinner is hidden, or it goes off screen, or something like that, it would be reasonable to make the popup go away. However, it's interferring with what you're attempting to do. It would be nice if you could somehow override isVisibleToUser(), but unfortunately it's marked as #hide, so that's not possible.
Might I suggest a workaround, like setting the Spinner visible but really small? Like, with a height of 1px? I believe that should be enough to fool this method.
Another option, and probably a more sensible one, would be to forgo the Spinner altogether and use a PopupMenu instead. You can anchor it to the Button, load it dynamically, and show it when the button is pressed. The visual effect should be the same.
If you think the problem is due to the change of focus . You can set it with multiple ways.
first create a focuschangeListener and onfocuschange do whatever you like
yourView.setOnFocusChangeListener(testListener);
#Override
public void onFocusChange(View arg0,
boolean isFocused)
{
if(isFocused)
{
//do your work here
}
else
{
}
}
And second way to prevent view from focus..
<!-- Dummy item to prevent AutoCompleteTextView from receiving focus -->
<LinearLayout
android:focusable="true" android:focusableInTouchMode="true"
android:layout_width="0px" android:layout_height="0px"/>
<!-- :nextFocusUp and :nextFocusLeft have been set to the id of this component
to prevent the dummy from receiving focus again -->
<AutoCompleteTextView android:id="#+id/autotext"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:nextFocusUp="#id/autotext" android:nextFocusLeft="#id/autotext"/>
I like my UIs to be intuitive; each screen should naturally and unobtrusively guide the user on to the next step in the app. Barring that, I strive to make things as confusing and confounding as possible.
Just kidding :-)
I've got three TableRows, each containing a read-only and non-focusable EditText control and then a button to its right. Each button starts the same activity but with a different argument. The user makes a selection there and the sub-activity finishes, populating the appropriate EditText with the user's selection.
It's the classic cascading values mechanism; each selection narrows the available options for the next selection, etc. Thus I'm disabling both controls on each of the next rows until the EditText on the current row contains a value.
I need to do one of two things, in this order of preference:
When a button is clicked, immediately remove focus without setting focus to a different button
Set focus to the first button when the activity starts
The problem manifests after the sub-activity returns; the button that was clicked retains focus.
Re: #1 above - There doesn't appear to be a removeFocus() method, or something similar
Re: #2 above - I can use requestFocus() to set focus to the button on the next row, and that works after the sub-activity returns, but for some reason it doesn't work in the parent activity's onCreate().
I need UI consistency in either direction--either no buttons have focus after the sub-activity finishes or each button receives focus depending on its place in the logic flow, including the very first (and only) active button prior to any selection.
Using clearFocus() didn't seem to be working for me either as you found (saw in comments to another answer), but what worked for me in the end was adding:
<LinearLayout
android:id="#+id/my_layout"
android:focusable="true"
android:focusableInTouchMode="true" ...>
to my very top level Layout View (a linear layout). To remove focus from all Buttons/EditTexts etc, you can then just do
LinearLayout myLayout = (LinearLayout) activity.findViewById(R.id.my_layout);
myLayout.requestFocus();
Requesting focus did nothing unless I set the view to be focusable.
Old question, but I came across it when I had a similar issue and thought I'd share what I ended up doing.
The view that gained focus was different each time so I used the very generic:
View current = getCurrentFocus();
if (current != null) current.clearFocus();
You can use View.clearFocus().
Use View.requestFocus() called from onResume().
android:descendantFocusability="beforeDescendants"
using the following in the activity with some layout options below seemed to work as desired.
getWindow().getDecorView().findViewById(android.R.id.content).clearFocus();
in connection with the following parameters on the root view.
<?xml
android:focusable="true"
android:focusableInTouchMode="true"
android:descendantFocusability="beforeDescendants" />
https://developer.android.com/reference/android/view/ViewGroup#attr_android:descendantFocusability
Answer thanks to:
https://forums.xamarin.com/discussion/1856/how-to-disable-auto-focus-on-edit-text
About windowSoftInputMode
There's yet another point of contention to be aware of. By default,
Android will automatically assign initial focus to the first EditText
or focusable control in your Activity. It naturally follows that the
InputMethod (typically the soft keyboard) will respond to the focus
event by showing itself. The windowSoftInputMode attribute in
AndroidManifest.xml, when set to stateAlwaysHidden, instructs the
keyboard to ignore this automatically-assigned initial focus.
<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
great reference
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/ll_root_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
LinearLayout llRootView = findViewBindId(R.id.ll_root_view);
llRootView.clearFocus();
I use this when already finished update profile info and remove all focus from EditText in my layout
====> Update: In parent layout content my EditText add line:
android:focusableInTouchMode="true"
What about just adding android:windowSoftInputMode="stateHidden" on your activity in the manifest.
Taken from a smart man commenting on this: https://stackoverflow.com/a/2059394/956975
I tried to disable and enable focusability for view and it worked for me (focus was reset):
focusedView.setFocusable(false);
focusedView.setFocusableInTouchMode(false);
focusedView.setFocusable(true);
focusedView.setFocusableInTouchMode(true);
First of all, it will 100% work........
Create onResume() method.
Inside this onResume() find the view which is focusing again and again by findViewById().
Inside this onResume() set requestFocus() to this view.
Inside this onResume() set clearFocus to this view.
Go in xml of same layout and find that top view which you want to be focused and set focusable true and focusableInTuch true.
Inside this onResume() find the above top view by findViewById
Inside this onResume() set requestFocus() to this view at the last.
And now enjoy......
android:focusableInTouchMode="true"
android:focusable="true"
android:clickable="true"
Add them to your ViewGroup that includes your EditTextView.
It works properly to my Constraint Layout. Hope this help
You could try turning off the main Activity's ability to save its state (thus making it forget what control had text and what had focus). You will need to have some other way of remembering what your EditText's have and repopulating them onResume(). Launch your sub-Activities with startActivityForResult() and create an onActivityResult() handler in your main Activity that will update the EditText's correctly. This way you can set the proper button you want focused onResume() at the same time you repopulate the EditText's by using a myButton.post(new Runnable(){ run() { myButton.requestFocus(); } });
The View.post() method is useful for setting focus initially because that runnable will be executed after the window is created and things settle down, allowing the focus mechanism to function properly by that time. Trying to set focus during onCreate/Start/Resume() usually has issues, I've found.
Please note this is pseudo-code and non-tested, but it's a possible direction you could try.
You do not need to clear focus, just add this code where you want to focus
time_statusTV.setFocusable(true);
time_statusTV.requestFocus();
InputMethodManager imm = (InputMethodManager)this.getSystemService(Service.INPUT_METHOD_SERVICE);
imm.showSoftInput( time_statusTV, 0);
Try the following (calling clearAllEditTextFocuses();)
private final boolean clearAllEditTextFocuses() {
View v = getCurrentFocus();
if(v instanceof EditText) {
final FocusedEditTextItems list = new FocusedEditTextItems();
list.addAndClearFocus((EditText) v);
//Focus von allen EditTexten entfernen
boolean repeat = true;
do {
v = getCurrentFocus();
if(v instanceof EditText) {
if(list.containsView(v))
repeat = false;
else list.addAndClearFocus((EditText) v);
} else repeat = false;
} while(repeat);
final boolean result = !(v instanceof EditText);
//Focus wieder setzen
list.reset();
return result;
} else return false;
}
private final static class FocusedEditTextItem {
private final boolean focusable;
private final boolean focusableInTouchMode;
#NonNull
private final EditText editText;
private FocusedEditTextItem(final #NonNull EditText v) {
editText = v;
focusable = v.isFocusable();
focusableInTouchMode = v.isFocusableInTouchMode();
}
private final void clearFocus() {
if(focusable)
editText.setFocusable(false);
if(focusableInTouchMode)
editText.setFocusableInTouchMode(false);
editText.clearFocus();
}
private final void reset() {
if(focusable)
editText.setFocusable(true);
if(focusableInTouchMode)
editText.setFocusableInTouchMode(true);
}
}
private final static class FocusedEditTextItems extends ArrayList<FocusedEditTextItem> {
private final void addAndClearFocus(final #NonNull EditText v) {
final FocusedEditTextItem item = new FocusedEditTextItem(v);
add(item);
item.clearFocus();
}
private final boolean containsView(final #NonNull View v) {
boolean result = false;
for(FocusedEditTextItem item: this) {
if(item.editText == v) {
result = true;
break;
}
}
return result;
}
private final void reset() {
for(FocusedEditTextItem item: this)
item.reset();
}
}