This article is the second part of "Android application development: how do you implement this?"
The main target is (arbitrarily) assuming "beginners and intermediates who have learned to google" like me. Since it explains both Java and Kotlin, even those who say "I understand the implementation in Java, but how do you write it in Kotlin?" I think it will be useful.
The first was Button Edition.
A sample of this project can be found at the link below. The master branch is the Kotlin source code and the java branch is the Java source code.
https://github.com/Dai1678/SampleCodePrograms
There is no tsukkomi that you are already using Text in the first time. That's an essential function.
It's just boring to just put a TextView As a sample
--TextView that can be copied by long-pressing the character --Only here is ordinary EditText --Text Clock found by some kind of completion function ――TexInputLayout / EditText that everyone loves Material Design can be easily created
In addition, I added a function like a simple login form using these.
Android Studio 3.0+ Confirmed operation on Android 8.0
build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 27
defaultConfig {
applicationId "net.ddns.dai.samplecodeprograms"
minSdkVersion 17
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:27.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:design:27.1.0'
implementation 'com.android.support:customtabs:27.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
activity_text_sample.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="10dp"
tools:context=".TextSampleActivity">
<TextView
android:id="@+id/userName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Your username is ◯◯\n Press and hold to copy"
android:textSize="20sp"
android:textIsSelectable="true"/>
<EditText
android:id="@+id/editPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Please set a password"
android:textSize="20sp"
android:maxLines="1"
android:layout_marginTop="20dp" />
<TextClock
android:id="@+id/currentTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:hint="yyyy/MM/dd HH:mm:ss"
android:textSize="20sp"
android:timeZone="Asia/Tokyo"
android:format12Hour="yyyy/MM/dd HH:mm:ss"
android:format24Hour="yyyy/MM/dd HH:mm:ss"/>
<android.support.design.widget.TextInputLayout
android:id="@+id/nameTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:counterEnabled="true"
app:counterMaxLength="10"
app:errorEnabled="true"
app:hintAnimationEnabled="true"
app:hintEnabled="true">
<android.support.design.widget.TextInputEditText
android:id="@+id/userNameInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="username"
android:maxLines="1"
android:textSize="20sp" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/passwordTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterEnabled="false"
app:errorEnabled="false"
app:hintAnimationEnabled="true"
app:hintEnabled="true">
<android.support.design.widget.TextInputEditText
android:id="@+id/userPassWordInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="password"
android:maxLines="1"
android:textSize="20sp" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/loginButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Login"/>
</LinearLayout>
You can display characters with <TextView />
.
--ʻ android: The recommended unit for textSizeis
sp. It expands and contracts depending on the font size setting of the terminal. --When android: textIsSelectable
is set to true, you can select the range by tapping the displayed character.
You can enter characters with <EditText />
.
―― ʻandroid: hint allows you to set a string that prompts the user to enter when nothing is entered. (In TextView etc., it is used for checking on the Preview screen of Android Studio) --When you start a new line while typing with ʻandroid: maxLines
, the input space is expanded only to the specified number of lines.
(Actually, the line breaks just because the characters disappear)
<TextClock />
can display the current date and time as a formatted string.
and ʻandroid: format24Hour
, you can set the format in 12-hour format and 24-hour format, respectively.
In the sample, it is yyyy (AD) / MM (month) / dd (day) HH (hour): mm (minute): ss (second).Use <TextInputLayout />
and <TextInputEditText />
as a set (when preparing two input fields, prepare two each).
You can use this to implement EditText with material design animations.
Don't forget ʻimplementation'com.android.support: design: (version)in build.gradle when using it. Also, when using app: ~ in xml, don't forget
xmlns: app =" http://schemas.android.com/apk/res-auto "`.
--When ʻapp: counterEnabled is set to true, the number of characters entered is displayed in the lower right corner. --If you specify ʻapp: counterMaxLength
, you can visualize the character limit like 0/10
.
(With this alone, you can continue typing even if the number of characters is exceeded)
--When ʻapp: errorEnabled is set to true --If ʻapp: hintEnabled
is set to true, the hint string is displayed in the upper left while typing.
--ʻApp: If hintAnimationEnabled` is set to true, the animation will be applied to the hint string.
It is often used when dealing with the characters displayed or entered in TextView or EditText. getText and setText.
example.java
//Since the return value of getText is TextView type, Cast with toString etc.(Type conversion)And substitute
String str = textView.getText().toString();
textView.setText("String");
TextInputEditText is basically the same usage.
In the sample, generate a 10-digit random number with the generateUserName method and decide the user name arbitrarily. Set the password with any character string in EditText with the hint of "Please set the password". When the login button is pressed, the character string is compared with the character string entered in TextInputEditText that has the hints of "user name" and "password".
I wanted to use EditText, which is material design, so I tried it.
Basically, if you add it to xml, it will work without permission, but On the code side, if more than the number of ʻapp: counterMaxLength` specified in xml is entered An error message was displayed.
example.java
userNameInput.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable editable) {
}
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
if (charSequence.length() > nameTextInputLayout.getCounterMaxLength()){
nameTextInputLayout.setError("Please enter the user name within 10 characters");
}else{
nameTextInputLayout.setError(null);
}
}
});
userNameInput will be the TextInputLayout where you enter your user name. I've added a Listener to this to monitor the characters typed in TextWatcher.
beforeTextChanged(CharSequence charSequence, int start, int count,int after)
--Method called just before the string is modified
- CharSequence charSequence
The string currently entered in EditText
- int start
Start position of the newly added character string in the charSequence character string
- int count
Total number of changed strings in the charSequence string
- int after
Number of newly added strings
onTextChanged(CharSequence charSequence, int start, int before, int count)
--Called when one character is entered
- CharSequence charSequence
The string currently entered in EditText
- int start
Start position of the newly added character string in the charSequence character string
- int before
Number of existing strings to be deleted
- int count
Total number of changed strings in the charSequence string
afterTextChanged(Editable editable)
--Finally this method is called
- Editable editable
The final modifiable, modified string
To display the error message, use the setError method, and if nothing is displayed, specify null as an argument.
I have omitted explanations other than those related to text, but the following is the source code.
TextSampleActivity.java
public class TextSampleActivity extends AppCompatActivity {
private final int NoInput = -2;
private final int LOGIN = 1;
private final int ERROR = -1;
@SuppressLint("SetTextI18n")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text_sample);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true);
}
final String name = generateUserName();
TextView userName = findViewById(R.id.userName);
userName.setText("Your username is" + name + "is\n Press and hold to copy");
Button loginButton = findViewById(R.id.loginButton);
final EditText editPassWord = findViewById(R.id.editPassword);
final TextInputEditText userNameInput = findViewById(R.id.userNameInput);
final TextInputEditText userPassWordInput = findViewById(R.id.userPassWordInput);
final TextInputLayout nameTextInputLayout = findViewById(R.id.nameTextInputLayout);
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String yourPassWord = editPassWord.getText().toString();
String inputUserName = userNameInput.getText().toString();
String inputUserPassWord = userPassWordInput.getText().toString();
if (inputUserName.equals("")){
//Prompt for yourPassWord
showResult(view, NoInput);
}else{
boolean loginResult = name.equals(inputUserName) && yourPassWord.equals(inputUserPassWord);
if (loginResult){
//login
showResult(view, LOGIN);
}else{
//error
showResult(view, ERROR);
}
}
}
});
userNameInput.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable editable) {
}
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
if (charSequence.length() > nameTextInputLayout.getCounterMaxLength()){
nameTextInputLayout.setError("Please enter the user name within 10 characters");
}else{
nameTextInputLayout.setError(null);
}
}
});
}
private String generateUserName(){
final String letters = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuilder stringBuilder = new StringBuilder();
while (stringBuilder.length() < 10){
int val = random.nextInt(letters.length());
stringBuilder.append(letters.charAt(val));
}
return stringBuilder.toString();
}
@SuppressLint("SimpleDateFormat")
private void showResult(View view, int result){
String showText = "";
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
switch (result){
case NoInput:
showText = "Please set a password";
break;
case LOGIN:
showText = dateFormat.format(date) + "You logged in to!";
break;
case ERROR:
showText = "The user name or password entered is incorrect";
}
Snackbar.make(view, showText, Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}
Why did I have to add the final modifier to the variables named editPassWord, userNameInput, userPassWordInput? This is to prevent the value from being changed during processing such as OnClickListener that defines an anonymous class. If you want to do something like count-up during processing, you can use the member variables of the class.
The way to write getText and setText in Kotlin is a little cool.
example.kt
val str = textView.text.toString() //Used as setText
textView.text = "String" //Used as getText
You can do both with .text. Especially when using it as getText, instead of passing a String type as an argument like java It is expressed in the form of substitution.
As an aside, in Kotlin, when you want to embed a variable in a string, you can express it naturally by using $
. It's the same as PHP.
example.kt
userName.text = "Your username is${name}is\n Press and hold to copy"
//This is fine when putting spaces before and after the variable
userName.text = "Your username is$is name\n Press and hold to copy"
Below is the source code of the sample app in Kotlin.
TextSampleActivity.kt
class TextSampleActivity : AppCompatActivity() {
private val noInput = -2
private val login = 1
private val error = -1
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_text_sample)
val actionBar = supportActionBar
actionBar!!.setDisplayHomeAsUpEnabled(true)
//Create yourName
val name = generateUserName(10)
userName.text = "Your username is${name}is\n Press and hold to copy"
loginButton.setOnClickListener { view ->
val yourPassWord = editPassword.text.toString()
val inputUserName = userNameInput.text.toString()
val inputUserPassWord = userPassWordInput.text.toString()
if (inputUserPassWord == ""){
//Prompt for yourPassWord
showResult(view, noInput)
}else{
val loginResult = name == inputUserName && yourPassWord == inputUserPassWord
if (loginResult){
//login
showResult(view, login)
}else{
//error
showResult(view, error)
}
}
}
userNameInput.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, start: Int, count: Int, after: Int) {}
override fun afterTextChanged(editable: Editable) {}
override fun onTextChanged(charSequence: CharSequence, start: Int, before: Int, count: Int) {
if (charSequence.length > nameTextInputLayout.counterMaxLength) {
nameTextInputLayout.error = "Please enter the user name within 10 characters"
} else {
nameTextInputLayout.error = null
}
}
})
}
//Random number creation with the number of digits of the argument value
private fun generateUserName(length: Int): String {
val letters = "abcdefghijklmnopqrstuvwxyz0123456789"
var str = ""
while (str.length < length) {
str += letters[Random().nextInt(letters.length)]
}
return str
}
@SuppressLint("SimpleDateFormat")
private fun showResult(view: View, result: Int){
var showText = ""
val dateFormat = SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
val date = Date(System.currentTimeMillis())
when (result) {
noInput -> {
showText = "Please set a password"
}
login -> {
showText = "${dateFormat.format(date)}You have logged in to!"
}
error -> {
showText = "The user name or password entered is incorrect"
}
}
Snackbar.make(view, showText, Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
}
I learned about TextInputLayout based on this article. -Android --Text field implementation with TextInputLayout
I've used it many times already, but about Toast and Snack Bar. Maybe I'll omit it and do something else ...
It's not out of material
I would like to show it to juniors at the university, but I would be grateful if Qiita users could comment if there is demand. If you have any mistakes, please make a correction request.
Recommended Posts