SMS 입력 화면 만들고 글자 수 표시하기
[activity_main.xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layerType="none"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:id="@+id/editTextTextMultiLine"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="1"
android:editable="true"
android:ems="10"
android:gravity="center_vertical|center_horizontal"
android:inputType="textMultiLine"
android:hint="입력상자"
android:textSize="50sp" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:text="0 / 80 바이트"
android:textSize="25sp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:onClick="onButton1Clicked"
android:text="전송"
android:textSize="25sp"/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="닫기"
android:textSize="25sp"/>
</LinearLayout>
</LinearLayout>
[MainActivity.java]
package com.example.mission04;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
TextView textview;
String str1;
final int limit = 80;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview = (TextView)findViewById(R.id.textView);
EditText edit = (EditText)findViewById(R.id.editTextTextMultiLine);
edit.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
int n = s.toString().getBytes().length;
if (n>limit) {
String temp = edit.getText().toString();
int length = temp.length();
String input = temp.substring(0, length-1);
edit.setText(input);
} else {
textview.setText(n + "/80 바이트");
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
public void onButton1Clicked(View v){
textview = findViewById(R.id.editTextTextMultiLine);
str1 = textview.getText().toString();
Toast.makeText(this, str1, Toast.LENGTH_SHORT).show();
}
}
- SMS(Short Message Service)를 보내는 창으로서, 입력상자라고 적혀 있는 공간에 텍스트를 적으면 이에 반응하여 텍스트의 용량을 기록하고 전송 시 해당 텍스트를 전송한다.
- 하지만 SMS를 실제로 보내는 형식은 아직 구현하기 어려우므로, 현재는 전송 버튼과 함께 기입된 텍스트가 Toast 형태로 아래에서 출력되는 과정을 거친다.
- 텍스트 기입에 대한 반응을 위해서 addTextChangedListener 메소드를 사용하였으며, onTextChanged(텍스트가 기입될 때마다)에 기입된 텍스트의 바이트 수를 계산하여 TextView에 출력한다.
- 텍스트 바이트 수의 상한선인 80바이트를 넘어서면 기입되지 않도록 하였다.
보완해야 할 사항
- 텍스트 바이트 수의 상한선을 넘어섰을 때 텍스트가 기입되지 않도록 하기 위해 바이트 수를 넘어선 텍스트는 삭제가 되도록 설정하였다. 그러나 전체 텍스트의 말미 부분이 삭제되도록 설정하였기에 서두 부분이나 중간 부분에 텍스트를 추가하면 텍스트 추가를 못하게 하거나 추가된 텍스트만 삭제가 되지는 않는다는 맹점이 있다.
업데이트 ver.210118
package com.example.mission04;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputFilter;
import android.text.Spanned;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
TextView textview;
String str1;
final int limit = 80;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview = (TextView)findViewById(R.id.textView);
EditText edit = (EditText)findViewById(R.id.editTextTextMultiLine);
InputFilter inputFilter = new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
return null;
}
};
/*
InputFilter lengthFilter = new InputFilter.LengthFilter(); // InputFilter 사용방법
InputFilter[] filters = new InputFilter[]{lengthFilter};
edit.setFilters(filters);
*/
edit.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
int n = s.toString().getBytes().length;
if (n>limit) {
String temp = edit.getText().toString();
int length = temp.length();
String input = temp.substring(0, length-1);
edit.setText(input);
edit.setSelection(length-1); // 추가
} else {
textview.setText(n + "/80 바이트");
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
public void onButton1Clicked(View v){
textview = findViewById(R.id.editTextTextMultiLine);
str1 = textview.getText().toString();
Toast.makeText(this, str1, Toast.LENGTH_SHORT).show();
}
}
- 코드에 따라 최대 입력 바이트 수를 넘었을 때 넘어간 문자열을 삭제한 뒤 커서를 문자열 마지막에 오도록 edittext의 setSelection 메소드를 통해 수정하였다.
- 문자열의 길이를 알아내기 위한 메소드로 InputFilter를 이용하는 방법이 있었으나, 문자열의 바이트 수를 체크하는 것에는 한계가 있어 코드를 더 발전시키지는 못하였다. (주석 처리)