Issue: Character Counter Runs Off Screen
I am finding it extremely difficult to have a character counter which does not disappear once the input text scrolls over one screen size.
This is what I have in the layout xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
xmlns:android.support.design="http://schemas.android.com/tools">
<android.support.design.widget.TextInputLayout
android:id="@+id/textContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterEnabled="true"
android:overScrollMode="never"
android.support.design:errorEnabled="true"
android.support.design:hintEnabled="true"
app:counterMaxLength="@integer/global_comments_size">
<android.support.design.widget.TextInputEditText
android:id="@+id/action_global_comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:layout_marginTop="8dp"
android:hint="@string/edit_comments"
android:imeOptions="actionDone"
android:inputType="textMultiLine"
android:scrollbars="vertical"
android:maxLength="@integer/global_comments_size"
/>
</android.support.design.widget.TextInputLayout>
</RelativeLayout>
counter visible until scroll leaves the screen
Counter becomes invisible as the text scroll over the screen
Probable Options:
I see following three options as possible solutions.
Make a bottom toolbar and add the counter programmatically
Make a pop-up show programmatically once the maximum size is reached
Somehow configure TextInputLayout in xml or use some other library.
I would prefer option 3. However, am at loss right now and do not find any solution or hint neither in the documentation nor by googling the forums.
Solution Found
After more reading I found out that the question has already been asked on stackoverflow here about counter running off the screen with solution proposals. However, the solution is not as expected with a simple xml entry but has to be done programmatically
I am posting my solution with source code based on the information collected from here and here.
I found the solution by reading through the documentation and stackoverflow. I am posting a complete example here to make it easier to reproduce the behavior.
Unfortunately, there does not seem to be a way of simply configuring an xml property which would make the counter stay in visible area of screen.
The solution lies in using the interface class TextWatchers which luckily requires only a few lines of code.
1) Create res/values/strings.xml file to define the constant for the maximum character size
<integer name="max_comment_size">50</integer>
2) add the following two views in your activity i.e. res/layout/activity_main.xml
I like to have the counter on top. You may want to swap TextView and TextEdit if you prefer having it at the bottom.
<TextView
android:id="@+id/constraint_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Remaining characters/Maximum characters: --/--" />
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textMultiLine"
android:maxLength="@integer/max_comment_size" />
Please note that textMultiLine does not limit the number of maximum lines for the EditText field. It only limits the layout size. With maxLength, you can specify the maximum number of allowed characters.
3) Use TextWatcher in the java file to count entered characters and show them in the TextView Java file in my example is: java/com/example/mycompany/textcounter/MainActivity.java
The interface class TextWatcher has three methods which need to be implemented. However, only onTextChange() is of interest to us for this purpose.
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
private EditText mEditText;
private final TextWatcher mTextEditorWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) { } //nothing to be done here
public void onTextChanged(CharSequence s, int start, int before, int count) {
Integer max_comment = getResources().getInteger(R.integer.max_comment_size);
mTextView.setText("Remaining characters" + "/Maximum characters: "+ String.valueOf(max_comment-s.length()) +"/" + max_comment);
}
public void afterTextChanged(Editable s) { } //nothing to be done here
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initializing views
mEditText = (EditText) findViewById(R.id.editText);
mTextView = (TextView) findViewById(R.id.constraint_textview);
mEditText.addTextChangedListener(mTextEditorWatcher);
}
}
Further Notes:
The solution is based on information provided here about counter running off screen and here on how to use TextWatcher
See android documentation on TextWatcher and TextEdit, too.
I have limited the maximum number of input character in my TextEdit field with maxLength. If you do need to limit the maximum number of lines, see discussion and possible solutions here and here or use the search on stackoverflow.