in my current project there's an EditText with fixed layout_width and layout_height, called exercise
that is expanded downwards programmatically: One line of text (String) "\n"
is added to the EditText.
Sometimes the line added to the EditText, let's call it element, is too long to fit inside the full width of the object so it's splitted into a new line.
The thing is I would either like the lines' text size in exercise
to be resized to fit the EditText's width or have a clear visible distance between each line (element), but just not inside the newline due to not fitting inside the exercise
's width.
Therefore I googled as much as I could and tried out every possible solution I could find today. What I tried:
- Using either
EditText
as the object andandroid:autoSizeTextType="uniform"
&android:inputType="textMultiLine|textCapSentences"
as attributes orandroidx.appcompat.widget.AppCompatEditText
, accompanied by the attributesapp:autoSizeMaxTextSize="28sp"
,app:autoSizeMinTextSize="8sp"
andapp:autoSizeStepGranularity="1sp"
(with a device that supports just exactly API 26) - using other types of text objects
- using
lineSpacingExtra
to insert some spacing. This unfortunately also inserted the spacing between the wrapped/ splitted line so the original element's line that got splitted by wrapping inside the EditText had the spacing aswell.
That's where I am now. I can't get the text size be reduced automatically when the line would be too wide for the EditText's width.
I could supply the full XML, if needed.
I'm grateful for any hint that could help here. Thanks in advance!
CodePudding user response:
you can try something like this
if(et.getText().length()>10) {
et.setTextSize(newValue)
CodePudding user response:
Here's a really basic RecyclerView
implementation (using view binding, let me know if you're not familiar with that - you can just findViewById
all the things instead):
class MainFragment : Fragment(R.layout.fragment_main) {
lateinit var binding: FragmentMainBinding
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentMainBinding.bind(view)
with(binding) {
val adapter = MyAdapter()
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(requireContext())
addButton.setOnClickListener {
val item = textEntry.text.toString()
if (item.isNotBlank()) {
adapter.addItem(item)
textEntry.text.clear()
}
}
}
}
}
class MyAdapter : RecyclerView.Adapter<MyAdapter.ViewHolder>() {
private var data: List<String> = emptyList()
fun addItem(item: String) {
data = data item
notifyItemInserted(data.lastIndex)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = ItemViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.binding.textView.text = data[position]
}
override fun getItemCount(): Int = data.size
class ViewHolder(val binding: ItemViewBinding) : RecyclerView.ViewHolder(binding.root)
}
fragment_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:gravity="center"
android:padding="10dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@ id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/textEntry"
/>
<EditText
android:id="@ id/textEntry"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:singleLine="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/addButton"
/>
<Button
android:id="@ id/addButton"
android:text="ADD"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
item_view.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
>
<TextView
android:id="@ id/textView"
app:autoSizeTextType="uniform"
android:layout_width="match_parent"
android:layout_height="48sp"
android:maxLines="1"
android:gravity="center_vertical"
/>
</FrameLayout>
It's pretty simple - you have a text entry field and a button to add the contents as a new line. The button passes the contents to addItem
on the adapter, which appends it to the list of lines in data
. The RecyclerView
just displays all the items in data
, using a ViewHolder
layout that has an auto-sizing TextView
to scale each item.
Ideally you'd want to persist data
somehow (e.g. the Add button passes the new data to a ViewModel
, stores it somehow, updates the current list which the adapter has observe
d so it updates whenever there's a change) - I just left it as a basic proof of concept. Also, it's easier to store separate items if they're kept separate - you can always serialise it by joining them into a single string if you really want! But generally you wouldn't want to do that