I'm working on a project in Android where I have a TextView
(an EditText
to be exact) and a setting to enable or disable text wrapping for that view. I have searched the internet (a lot) but still haven't found any satisfying solution.
Currently I'm using a NestedScrollView
for the vertical scrolling and then dynamically insert one of two partial layouts, the first containing just an EditText
, the second with the EditText
wrapped inside a HorizontalScrollView
. The problem is that I currently have to restart the activity every time I return from another one to ensure I don't accidentally add two children to the NestedScrollView
(causing an exception). Also, the code that would account for that seems a bit bulky and confusing.
The first partial layout:
<com.example.application.EditorView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/editor_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:layout_gravity="start|top"
android:importantForAutofill="no"
android:inputType="textMultiLine|textCapSentences"
android:padding="@dimen/def_padding"
android:textIsSelectable="true"
android:textSize="18sp"
tools:ignore="LabelFor,ScrollViewSize" />
The second one:
<android.widget.HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/hscroll"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.application.EditorView
android:id="@+id/editor_content"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="start|top"
android:background="@android:color/transparent"
android:importantForAutofill="no"
android:inputType="textMultiLine|textCapSentences"
android:padding="@dimen/def_padding"
android:textIsSelectable="true"
android:textSize="18sp"
tools:ignore="LabelFor,ScrollViewSize" />
</android.widget.HorizontalScrollView>
(EditorView
simply extends EditText
and in no way effects the layout)
I've also found that EditText
has a setHorizontallyScrolling(true)
method, but using that I don't get a gliding effect when the user swipes which in my opinion feels less user friendly.
Having said all that, my question is: In Android, is there a way to dynamically enable text wrapping inside a HorizontalScrollView
, or to have an option to toggle it natively included inside a (custom) EditText
?
I've finally found a decent solution! Basically, in my custom View
I set the width to the screen width whenever a configuration change occurs and line wrapping is enabled (I also set it when the View
is first initialized):
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (/* line wrapping enabled */)
setWidth(Resources.getSystem().getDisplayMetrics().widthPixels);
else setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
}
This only works because, in my case, the EditText
fills the entire screen, so setting the width to the desired value is quite easy. Before I tried using MATCH_PARENT
and WRAP_CONTENT
, but inside a HorizontalScrollView
that doesn't enable text wrapping as I'd hoped.
Note that this View
is contained inside a HorizontalScrollView
inside a ScrollView
, so by default it would scroll both horizontally and vertically.
Hope this helps anyone else who comes across this problem!
EDIT: If text wrapping was previously enabled and you try disabling it with this approach, the text will still be wrapped, as the content is, by definition, already wrapped. The only fix I can think of is completely reloading the View
together with its ScrollViews
. If you find another solution, please let me know.