티스토리 뷰
MVVM + Room + RecyclerView + CardView + AlertDialog
build.gradle (Module: app)
dependencies {
// RecyclerView
implementation 'androidx.recyclerview:recyclerview:1.1.0'
// CardView
implementation 'androidx.cardview:cardview:1.0.0'
// Room
implementation 'androidx.room:room-runtime:2.2.5'
annotationProcessor 'androidx.room:room-compiler:2.2.5'
testImplementation 'androidx.room:room-testing:2.2.5'
}
UserEntity.java
package com.jwsoft.javaproject;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "user")
public class UserEntity {
@PrimaryKey(autoGenerate = true)
public Long id;
@ColumnInfo(name = "name")
public String name;
@ColumnInfo(name = "phone")
public String phone;
@ColumnInfo(name = "age")
public int age;
}
UserDao.java
package com.jwsoft.javaproject;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import java.util.List;
@Dao
public interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(UserEntity user);
@Query("SELECT * FROM user ORDER BY age ASC")
LiveData<List<UserEntity>> getAll();
@Query("DELETE FROM user")
void deleteAll();
@Delete
void delete(UserEntity user);
}
UserDB.java
package com.jwsoft.javaproject;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
@Database(entities = {UserEntity.class}, version = 1)
public abstract class UserDB extends RoomDatabase {
public abstract UserDao userDao();
public static UserDB INSTANCE;
public static UserDB getInstance(Context context) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context, UserDB.class, "MyApp.db")
.fallbackToDestructiveMigration()
.build();
}
return INSTANCE;
}
}
UserRepository.java
package com.jwsoft.javaproject;
import android.app.Application;
import androidx.lifecycle.LiveData;
import java.util.List;
public class UserRepository {
UserDB userDB;
LiveData<List<UserEntity>> getAll;
public UserRepository(Application application) {
userDB = UserDB.getInstance(application);
getAll = userDB.userDao().getAll();
}
void insert(final UserEntity user) {
try {
new Thread(new Runnable() {
@Override
public void run() {
userDB.userDao().insert(user);
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
}
LiveData<List<UserEntity>> getAll() {
return getAll;
}
void delete(final UserEntity user) {
try {
new Thread(new Runnable() {
@Override
public void run() {
userDB.userDao().delete(user);
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
}
void deleteAll() {
try {
new Thread(new Runnable() {
@Override
public void run() {
userDB.userDao().deleteAll();
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
UserViewModel.java
package com.jwsoft.javaproject;
import android.app.Application;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class UserViewModel extends AndroidViewModel {
UserRepository userRepository;
LiveData<List<UserEntity>> getAll;
public UserViewModel(Application application) {
super(application);
userRepository = new UserRepository(application);
getAll = userRepository.getAll();
}
public void insert(UserEntity user) {
userRepository.insert(user);
}
public LiveData<List<UserEntity>> getAll() {
return getAll;
}
public void delete(UserEntity user) {
userRepository.delete(user);
}
public void deleteAll() {
userRepository.deleteAll();
}
}
cardview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
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="100dp"
android:layout_margin="10dp"
android:elevation="10dp"
app:cardCornerRadius="5dp">
<androidx.constraintlayout.widget.ConstraintLayout
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="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCCCCC"/>
<TextView
android:id="@+id/tvAge"
android:layout_width="80dp"
android:layout_height="80dp"
android:elevation="10dp"
android:hint="30"
android:textSize="36dp"
android:textStyle="bold"
android:gravity="center"
android:background="#BBBBBB"
android:layout_marginLeft="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
app:layout_constraintLeft_toRightOf="@+id/tvAge"
app:layout_constraintRight_toRightOf="parent">
<TextView
android:id="@+id/tvName"
android:hint="James Kim"
android:textSize="30dp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvPhone"
android:hint="010-1234-5678"
android:textSize="18dp"
android:textStyle="italic"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

MyAdapter.java
package com.jwsoft.javaproject;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
List<UserEntity> users;
interface OnClickListener {
void onClick(UserEntity user);
}
interface OnLongClickListener {
void onLongClick(UserEntity user);
}
OnClickListener onClickListener;
OnLongClickListener onLongClickListener;
public MyAdapter(OnClickListener onClickListener, OnLongClickListener onLongClickListener) {
this.onClickListener = onClickListener;
this.onLongClickListener = onLongClickListener;
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView tvName;
TextView tvPhone;
TextView tvAge;
View itemView;
public MyViewHolder(View itemView) {
super(itemView);
this.itemView = itemView;
tvName = itemView.findViewById(R.id.tvName);
tvPhone = itemView.findViewById(R.id.tvPhone);
tvAge = itemView.findViewById(R.id.tvAge);
}
public void bind(final UserEntity user) {
tvName.setText(user.name);
tvPhone.setText(user.phone);
tvAge.setText(Integer.toString(user.age));
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onClickListener.onClick(user);
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
onLongClickListener.onLongClick(user);
return true;
}
});
}
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.cardview_item, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.bind(users.get(position));
}
@Override
public int getItemCount() {
if (users != null && users.size() > 0) {
return users.size();
} else {
return 0;
}
}
void setUsers(List<UserEntity> users) {
this.users = users;
notifyDataSetChanged();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvUser"
android:layout_width="match_parent"
android:layout_height="0dp"
tools:listitem="@layout/cardview_item"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@+id/btnAdd"/>
<Button
android:id="@+id/btnAdd"
android:layout_width="match_parent"
android:layout_height="100dp"
android:textAllCaps="false"
android:text="Add"
android:textSize="30dp"
android:textStyle="bold"
android:layout_margin="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java
package com.jwsoft.javaproject;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.List;
public class MainActivity extends AppCompatActivity {
UserViewModel userViewModel;
RecyclerView rvUser;
MyAdapter adapter;
Button btnAdd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeView();
MyAdapter.OnClickListener clickListener = new MyAdapter.OnClickListener() {
@Override
public void onClick(UserEntity user) {
Intent intent = new Intent(getApplicationContext(), AddActivity.class);
intent.putExtra("id", user.id);
intent.putExtra("name", user.name);
intent.putExtra("phone", user.phone);
intent.putExtra("age", user.age);
startActivity(intent);
finish();
}
};
MyAdapter.OnLongClickListener longClickListener = new MyAdapter.OnLongClickListener() {
@Override
public void onLongClick(UserEntity user) {
showAlertDialog(user);
}
};
adapter = new MyAdapter(clickListener, longClickListener);
rvUser.setAdapter(adapter);
rvUser.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));
rvUser.setHasFixedSize(true);
userViewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(UserViewModel.class);
userViewModel.getAll().observe(this, new Observer<List<UserEntity>>() {
@Override
public void onChanged(List<UserEntity> userEntities) {
adapter.setUsers(userEntities);
}
});
btnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), AddActivity.class);
startActivity(intent);
finish();
}
});
}
void initializeView() {
rvUser = findViewById(R.id.rvUser);
btnAdd = findViewById(R.id.btnAdd);
}
void showAlertDialog(final UserEntity user) {
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("Delete")
.setMessage("Do you want to delete user?")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
userViewModel.delete(user);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getApplicationContext(), "Cancel", Toast.LENGTH_SHORT).show();
}
})
.create();
alertDialog.show();
}
}
activity_add.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".MainActivity">
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:textSize="24dp"
android:layout_marginLeft="20dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/btnDone"
app:layout_constraintLeft_toLeftOf="parent" />
<TextView
android:id="@+id/tvPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Phone"
android:textSize="24dp"
android:layout_marginTop="30dp"
app:layout_constraintLeft_toLeftOf="@+id/tvName"
app:layout_constraintTop_toBottomOf="@+id/tvName"/>
<TextView
android:id="@+id/tvAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Age"
android:textSize="24dp"
android:layout_marginTop="30dp"
app:layout_constraintLeft_toLeftOf="@+id/tvName"
app:layout_constraintTop_toBottomOf="@+id/tvPhone"/>
<EditText
android:id="@+id/etName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="12"
android:layout_marginLeft="30dp"
app:layout_constraintStart_toEndOf="@+id/tvName"
app:layout_constraintTop_toTopOf="@+id/tvName"
app:layout_constraintBottom_toBottomOf="@+id/tvName" />
<EditText
android:id="@+id/etPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="12"
android:inputType="phone"
app:layout_constraintTop_toTopOf="@+id/tvPhone"
app:layout_constraintBottom_toBottomOf="@+id/tvPhone"
app:layout_constraintStart_toStartOf="@+id/etName" />
<EditText
android:id="@+id/etAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="12"
app:layout_constraintTop_toTopOf="@+id/tvAge"
app:layout_constraintBottom_toBottomOf="@+id/tvAge"
app:layout_constraintStart_toStartOf="@+id/etPhone" />
<Button
android:id="@+id/btnDone"
android:layout_width="match_parent"
android:layout_height="100dp"
android:textAllCaps="false"
android:text="Done"
android:textSize="26dp"
android:textStyle="bold"
android:layout_margin="4dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

AddActivity.java
package com.jwsoft.javaproject;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class AddActivity extends AppCompatActivity {
UserViewModel userViewModel;
EditText etName;
EditText etPhone;
EditText etAge;
Button btnDone;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
initializeView();
userViewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(UserViewModel.class);
if (getIntent().getLongExtra("id", 0) > 0) {
etName.setText(getIntent().getStringExtra("name"));
etPhone.setText(getIntent().getStringExtra("phone"));
etAge.setText(Integer.toString(getIntent().getIntExtra("age", 0)));
}
btnDone.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getIntent().getLongExtra("id", 0) > 0) {
UserEntity user = new UserEntity();
user.id = getIntent().getLongExtra("id", 0);
user.name = etName.getText().toString();
user.phone = etPhone.getText().toString();
user.age = Integer.parseInt(etAge.getText().toString());
userViewModel.insert(user);
} else {
UserEntity user = new UserEntity();
user.name = etName.getText().toString();
user.phone = etPhone.getText().toString();
user.age = Integer.parseInt(etAge.getText().toString());
userViewModel.insert(user);
}
startActivity(new Intent(getApplicationContext(), MainActivity.class));
finish();
}
});
}
void initializeView() {
etName = findViewById(R.id.etName);
etPhone = findViewById(R.id.etPhone);
etAge = findViewById(R.id.etAge);
btnDone = findViewById(R.id.btnDone);
}
}

'Android > Java' 카테고리의 다른 글
[Java] Synchronized (0) | 2020.07.27 |
---|---|
[Java] Generics (0) | 2020.07.24 |
[Java] RecyclerView + ItemClickListener + ItemLongClickListener (0) | 2020.07.21 |
[Java] AlertDialog (0) | 2020.07.21 |
[Java] Room (0) | 2020.07.20 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- recyclerview
- 자바
- XML
- ViewPager2
- JSONArray
- Livedata
- TabLayout
- activity
- Android
- MVVM
- 안드로이드
- CoordinatorLayout
- Design Pattern
- 코틀린
- 혀가 길지 않은 개발자
- coroutine
- Intent
- Architecture Pattern
- Kotlin
- JSONObject
- handler
- 안드로이드 #코틀린 #Android #Kotlin
- ViewModel
- View
- fragment
- James Kim
- Vue.js #Vue.js + javascript
- DataBinding
- java
- ArrayList
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
글 보관함