티스토리 뷰

Android/Java

[Java]  MVVM

혀가 길지 않은 개발자 2020. 7. 23. 00:15

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>

cardview_item.xml

 

 

 

 

 

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>

activity_main.xml

 

 

 

 

 

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>

activity_add.xml

 

 

 

 

 

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
링크
«   2024/05   »
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
글 보관함