๋ฐ์ํ
โ 1์ฐจ ์์ฑ ๋์์
โ ์ฝ๋
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"
android:background="@color/colorPrimary"
tools:context=".MainActivity">
<ImageButton
android:id="@+id/main_btn_back"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="12dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:srcCompat="@drawable/ic_arrow_back_black_24dp"
tools:ignore="ContentDescription,RtlHardcoded,VectorDrawableCompat" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/main_lv_memo_list"
android:layout_width="match_parent"
android:layout_height="590dp"
app:layout_constraintTop_toBottomOf="@+id/main_btn_back"
android:layout_marginTop="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:scrollbarFadeDuration="0"
android:scrollbarSize="5dp"
android:scrollbarThumbVertical="@color/colorPrimaryDark"
android:scrollbars="vertical"
/>
<TextView
android:id="@+id/main_tv_count"
android:text="15"
android:textColor="@color/colorText"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="170dp"
app:layout_constraintTop_toBottomOf="@id/main_lv_memo_list"
tools:ignore="HardcodedText,RtlHardcoded"/>
<TextView
android:id="@+id/main_tv_explain"
android:text="๊ฐ์ ๋ฉ๋ชจ"
android:textColor="@color/colorText"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/main_tv_count"
app:layout_constraintTop_toBottomOf="@id/main_lv_memo_list"
android:layout_marginLeft="5dp"
tools:ignore="HardcodedText,RtlHardcoded"/>
<ImageButton
android:id="@+id/main_btn_search"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="12dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/main_btn_add_text"
app:srcCompat="@drawable/ic_search_black_24dp"
tools:ignore="ContentDescription,RtlHardcoded,VectorDrawableCompat" />
<ImageButton
android:id="@+id/main_btn_add_text"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="12dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:srcCompat="@drawable/ic_mode_edit_black_24dp"
tools:ignore="ContentDescription,RtlHardcoded,VectorDrawableCompat" />
</androidx.constraintlayout.widget.ConstraintLayout>
CustomAdapter
package com.example.rvmemoapplication;
import android.content.Context;
import android.content.Intent;
import android.text.Layout;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.w3c.dom.Text;
import java.util.ArrayList;
import java.util.List;
// CustomAdapter: ArrayList ์ ์๋ Memo ํด๋์ค ํ์
์ ๋ฐ์ดํฐ๋ฅผ RecyclerView ์ ๋ณด์ฌ์ฃผ๋ ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder>
{
// RecyclerView.Adapter ๋ฅผ ์์๋ฐ์ ์๋ก์ด ์ด๋ํฐ๋ฅผ ๋ง๋ค ๋ ์ค๋ฒ๋ผ์ด๋ ํด์ผํ๋ ํจ์
// : onCreateViewHolder : viewType ํํ์ ์์ดํ
๋ทฐ๋ฅผ ์ํ ๋ทฐ ํ๋ ๊ฐ์ฒด ์์ฑ
// : onBindViewHolder : position ์ ํด๋นํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ทฐํ๋์ ์์ดํ
๋ทฐ์ ํ์
// : getItemCount : ์ ์ฒด ์์ดํ
๊ฐฏ์ ๋ฆฌํด
private ArrayList<Memo> mList;
//(1) ์ปค์คํ
๋ฆฌ์ค๋ ์ธํฐํ์ด์ค ์ ์ - onItemClick, onItemLongClick
public interface OnItemClickListener
{
void onItemClick(View v, int pos);
}
public interface OnItemLongClickListener
{
void onItemLongClick(View v, int pos);
}
//(2) ๋ฆฌ์ค๋ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ ๋ฉ์๋์ ์ ๋ฌ๋ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ๋ณ์(mListener) ์ถ๊ฐ
private OnItemClickListener mListener =null;
private OnItemLongClickListener mLongListener = null;
public void setOnItemClickListener(OnItemClickListener listener)
{
this.mListener = listener;
}
public void setOnItemLongClickListener(OnItemLongClickListener listener)
{
this.mLongListener = listener;
}
// ์์ดํ
๋ทฐ๋ฅผ ์ ์ฅํ๋ ๋ทฐํ๋ ํด๋์ค
public class CustomViewHolder extends RecyclerView.ViewHolder
{
TextView title;
TextView contents;
public CustomViewHolder(View itemview) {
super(itemview);
// ๋ทฐ ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ
this.title = (TextView)itemview.findViewById(R.id.memo_tv_title);
this.contents = (TextView)itemview.findViewById(R.id.memo_tv_contents);
// this.like = (ImageButton)view.findViewById(R.id.memo_btn_heart);
// (3)๋ทฐํ๋๊ฐ ๋ง๋ค์ด์ง๋ ์์ ์ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํด์ผ ํ๋ค.
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//๋ฆฌ์ฌ์ดํด๋ฌ๋ทฐ์ ๋ทฐํ๋์๋ ์์ ์ ์์น๋ฅผ ํ์ธํ ์ ์๋ ์๋ ๋ฉ์๋ ์ ๊ณต
int pos = getAdapterPosition();
if(pos!= RecyclerView.NO_POSITION)
{
mListener.onItemClick(v,pos);
}
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int pos = getAdapterPosition();
if(pos != RecyclerView.NO_POSITION)
{
mLongListener.onItemLongClick(v,pos);
}
return true;
}
});
}
}
// ์์ฑ์์์ ๋ฐ์ดํฐ ๋ฆฌ์คํธ ๊ฐ์ฒด๋ฅผ ์ ๋ฌ๋ฐ๋๋ค.
public CustomAdapter(ArrayList<Memo> list)
{
this.mList = list;
}
// ์์ดํ
๋ทฐ๋ฅผ ์ํ ๋ทฐํ๋ ๊ฐ์ฒด ์์ฑํ์ฌ ๋ฆฌํดํ๋ค.
@Override
public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType)
{
Context context = viewGroup.getContext();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) ;
View view = inflater.inflate(R.layout.item_memo, viewGroup, false);
// View view = LayoutInflater.from(viewGroup.getContext())
// .inflate(R.layout.item_memo,viewGroup, false);
CustomViewHolder viewHolder = new CustomViewHolder(view);
return viewHolder;
}
// position ์ ํด๋นํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ทฐํ๋์ ์์ดํ
๋ทฐ์ ํ์
@Override
public void onBindViewHolder(@NonNull CustomViewHolder viewHolder, int position)
{
viewHolder.title.setText(mList.get(position).getTitle());
viewHolder.contents.setText(mList.get(position).getContents());
}
// ์ ์ฒด ๋ฐ์ดํฐ ๊ฐฏ์ ๋ฆฌํด
@Override
public int getItemCount() {
// mList ๋น์ด ์์ผ๋ฉด 0๋ฆฌํด, ์๋๋ฉด mList ์ฌ์ด์ฆ ๋ฆฌํด
// return (null != mList ? mList.size():0);
return mList.size();
}
}
MainActivity
package com.example.rvmemoapplication;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
ArrayList<Memo> mArrayList;
private CustomAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().hide();
}
@Override
public void onBackPressed() {
// super.onBackPressed();
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.setMessage("Do you want to quit this app?");
builder.setTitle("Exit Notification");
builder.show();
}
@Override
protected void onResume() {
super.onResume();
mArrayList =new ArrayList<>();
// [Done] ๋ฆฌ์ฌ์ดํด๋ฌ๋ทฐ์ ์ฐ๊ฒฐ
final RecyclerView mRecyclerView = (RecyclerView)findViewById(R.id.main_lv_memo_list);
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLinearLayoutManager);
mAdapter = new CustomAdapter(mArrayList);
mRecyclerView.setAdapter(mAdapter);
// [Done] DBHelper ๊ฐ์ฒด ์์ฑ
String dbName = "Memo0.db";
int dbVersion = 1;
final DBHelper dbHelper;
// [Done] db ์์ ๊ฐ ๊ฐ์ ธ์์ Memo ํด๋์ค์ ๋ด์ mArrayList ์ ๋ด๊ธฐ
dbHelper = new DBHelper(this,dbName,null,dbVersion);
final SQLiteDatabase db = dbHelper.getReadableDatabase();
String sql = "SELECT * FROM Memo0;";
Cursor cursor = db.rawQuery(sql,null);
final TextView memoCount = findViewById(R.id.main_tv_count);
// [Done] ๋ฐ์ดํฐ ๋ฐ๋๊ฑฐ ๊ฐ์ง ํ ์ ์๊ฒ๋
mAdapter.notifyDataSetChanged();
memoCount.setText(String.valueOf(cursor.getCount()));
try{
if(cursor.getCount() >0)
{
while(cursor.moveToNext())
{
// DB์ ์๋ ๊ฐ๋ค์ String ๊ฐ๋ค์ Memo ํด๋์ค ์์ฑ์์ ๋ด๊ธฐ.
Memo m = new Memo(cursor.getString(1),cursor.getString(2));
mArrayList.add(m);
}
}
}finally {
cursor.close();
}
final ImageButton backBtn = findViewById(R.id.main_btn_back);
final ImageButton searchBtn = findViewById(R.id.main_btn_search);
final ImageButton newBtn = findViewById(R.id.main_btn_add_text);
// [Done] ๋ค๋ก๊ฐ๊ธฐ ๋ฒํผ
backBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Animation anim = AnimationUtils.loadAnimation(
getApplicationContext(),
R.anim.scale_anim);
backBtn.startAnimation(anim);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.setMessage("Do you want to quit this app?");
builder.setTitle("Exit Notification");
builder.show();
}
});
String got_title_from_custom_Dialog;
// ๊ฒ์ ๋ฒํผ
searchBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Animation anim = AnimationUtils.loadAnimation(
getApplicationContext(),
R.anim.scale_anim);
searchBtn.startAnimation(anim);
Handler delayHandler = new Handler();
delayHandler.postDelayed(new Runnable() {
@Override
public void run() {
// TODO
// customDialog = new CustomDialog(this);
// customDialog.show();
//
// private View.OnClickListener searchListener = new View.OnClickListener() {
// @Override
// public void onClick(View v) {
//
// }
// }
}
}, 2000);
}
});
// [Done] ์๋ก์ด ๋ฉ๋ชจ ์ถ๊ฐ ๋ฒํผ
newBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// float deg = newBtn.getRotation() + 80F;
// newBtn.animate().rotation(deg).setInterpolator(new AccelerateDecelerateInterpolator());
Animation anim = AnimationUtils.loadAnimation(
getApplicationContext(),
R.anim.rotate_anim);
newBtn.startAnimation(anim);
Handler delayHandler = new Handler();
delayHandler.postDelayed(new Runnable() {
@Override
public void run() {
// TODO
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
startActivity(intent);
}
}, 2000);
}
});
// [Done] ๋ฆฌ์ฌ์ดํด ๋ทฐ ๋ด์ ์์ดํ
ํด๋ฆญ์ → edit
mAdapter.setOnItemClickListener(new CustomAdapter.OnItemClickListener() {
@Override
public void onItemClick(View v, int pos) {
Intent intent = new Intent(MainActivity.this, EditActivity.class);
Cursor cursor = (Cursor) dbHelper.getReadableDatabase().query("Memo0",null,null,null,null,null,null);
cursor.moveToPosition(pos);
String t_title = cursor.getString(1);
String c_contents = cursor.getString(2);
intent.putExtra("title",t_title);
intent.putExtra("contents",c_contents);
startActivity(intent);
}
});
// [Done] ๋ฆฌ์ฌ์ดํด ๋ทฐ ๋ด์ ์์ดํ
๋กฑํด๋ฆญ์ → ์ญ์ ์ฌ๋ถ
mAdapter.setOnItemLongClickListener(new CustomAdapter.OnItemLongClickListener() {
@Override
public void onItemLongClick(View v, final int pos) {
final Cursor cursor = (Cursor) dbHelper.getReadableDatabase().query("Memo0",null,null,null,null,null,null);
cursor.moveToPosition(pos);
final String t_title = cursor.getString(1);
// String c_contents = cursor.getString(2);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// ๋ฉ๋ชจ ์ญ์ ์์
String sql0 ="DELETE FROM Memo0 WHERE title = '"+ t_title +"';";
db.execSQL(sql0);
mArrayList.remove(pos);
mAdapter.notifyDataSetChanged();
memoCount.setText(String.valueOf(mArrayList.size()));
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.setMessage("Do you want to delete this memo?");
builder.setTitle("Delete Notification");
builder.show();
}
});
}
}
โ ์ฐธ๊ณ
Lottie๋ฅผ ์ด์ฉํด ํ๋ คํ ์ ๋๋ฉ์ด์ ๋ฃ๊ธฐ
lottiefiles.com/popular?page=2
postDelayed๋ฉ์๋๋ฅผ ์ด์ฉํ delay ์ฒ๋ฆฌ
์๋๋ก์ด๋ ๋ฆฌ์ฌ์ดํด๋ฌ๋ทฐ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ. (Android RecyclerView)
RecyclerView ๋ฐ์ดํฐ ์ถ๊ฐ/ ํธ์ง ์ญ์
RecyclerView ์์ดํ ํด๋ฆญ ์ด๋ฒคํธ
RecyclerView ์์
Recyclerview
developer.android.com/jetpack/androidx/releases/recyclerview
ConstraintLayout ์ฒด์ธ ์ค์ ํ๊ธฐ
๋ฐ์ํ
'Android' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Android::์ฐ๋ ๋, ํธ๋ค๋ฌ ๊ณต๋ถํ๊ธฐ + ๊ณ ์์ด ์ฐ์ ์ฃผ๊ธฐ ๊ฒ์ (0) | 2020.08.06 |
---|---|
Android::SwipeMenuList (0) | 2020.08.01 |
Android::๋ฆฌ์คํธ๋ทฐ์ฌ์ฉํด์ ๋ฉ๋ชจ์ฅ๋ง๋ค๊ธฐ (11) | 2020.07.24 |
Android::Java ๋ฌธ๋ฒ +๏ผ (0) | 2020.07.21 |
Android:: countDownTimer & Lifecycle (0) | 2020.07.21 |
๋๊ธ