본문 바로가기
안드로이드 자바

[Java][Android] 메모장 만들기(1. 메모 작성 및 저장)

by teamnova 2021. 2. 9.
728x90

안녕하세요.
스틱코드를 이용해서 메모장을 구현해볼 예정입니다.

 

=====================================

사용된 xml 파일은 스틱코드 포스트로 게시해두었습니다.

stickode.com/detail.html?no=1882

 

스틱코드

 

stickode.com

 

=====================================

 

1. Activity 간 이동

 첫번째로 버튼을 눌러 다른 액티비티로 이동하는 로직을 구현하도록 하겠습니다.

 

* MainActivity.class / 클릭리스너 및 인텐트

Button write_btn; //작성하기 버튼
private int REQUEST_TEST = 200;

write_btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 버튼을 눌러 이동할 액티비티를 정해준다 (ex, WriteActivity.class)
        Intent intent = new Intent(getApplicationContext(), WriteActivity.class);
        //startActivity(intent); // 해당 액티비티에 단순 값 전달과 이동이면 startActivity
        startActivityForResult(intent,REQUEST_TEST); // 메모를 작성하고 결과값을 받기 위해

    }
});

메인 화면에서 작성하기 버튼을 눌러 WriteActivity로 이동

 

 

2. 입력값 저장(SharedPreperence)

메모를 작성하여 저장하기 버튼을 눌렀을 때 SharedPreperence로 저장합니다.

 

* WriteActivity.class

public class WriteActivity extends AppCompatActivity {

    PreferenceManager pref;
    Button back_btn;
    Button save_btn;
    EditText title;
    EditText content;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_write);


        pref = new PreferenceManager();
        back_btn = findViewById(R.id.back_btn);
        save_btn = findViewById(R.id.save_btn);
        // editText 할당
        title = findViewById(R.id.memo_title_edit);
        content = findViewById(R.id.memo_content_edit);


        back_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        save_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 저장 버튼을 눌러
                // 작성한 editText를 저장
                String edit_title = title.getText().toString();
                String edit_content = content.getText().toString();
                // String 값을 JSONObject로 변환하여 사용할 수 있도록 메모의 제목과 타이틀을 JSON 형식로 저장
                String save_form = "{\"title\":\""+edit_title+"\",\"content\":\""+edit_content+"\"}";
				
                // key값이 겹치지 않도록 현재 시간으로 부여
                long now = System.currentTimeMillis();
                Date mDate = new Date(now);
                SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                String getTime = simpleDate.format(mDate).toString();

                Log.d("WriteActivity","제목 : "+edit_title+", 내용 : "+edit_content+", 현재시간 : "+getTime);
                //PreferenceManager 클래스에서 저장에 관한 메소드를 관리
                pref.setString(getApplication(),getTime,save_form);
                

				// Intent로 값을 MainActivity에 전달
                Intent intent = new Intent();
                intent.putExtra("date",getTime);
                intent.putExtra("title",edit_title);
                intent.putExtra("content",edit_content);
                setResult(RESULT_OK, intent);
                finish();

            }
        });


    }

}

 

PreferenceManager 클래스스틱코드에 있는 'sharedpreferences 간편 사용 클래스 만들기' 포스트를 가져와 사용하였고 필요하거나 없어도 되는 부분은 입맛에 맛게 커스텀해주세요.

* PreferenceManager.class

public class PreferenceManager {
    public static final String PREFERENCES_NAME = "memo_contain";

    private static final String DEFAULT_VALUE_STRING = " ";
    private static final boolean DEFAULT_VALUE_BOOLEAN = false;
    private static final int DEFAULT_VALUE_INT = -1;
    private static final long DEFAULT_VALUE_LONG = -1L;
    private static final float DEFAULT_VALUE_FLOAT = -1F;

    private static SharedPreferences getPreferences(Context context) {

        return context.getSharedPreferences(PREFERENCES_NAME, context.MODE_PRIVATE);

    }

    /* String 값 저장
       param context
       param key
       param value
     */
    public static void setString(Context context, String key, String value){
        SharedPreferences prefs = getPreferences(context);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(key, value);
        editor.apply();
    }


    /* String 값 로드
       param context
       param key
       return
     */

    public static String getString(Context context, String key){
        SharedPreferences prefs = getPreferences(context);
        String value = prefs.getString(key, DEFAULT_VALUE_STRING);
        return value;
    }


    /* 키 값 삭제
      param context
      param key
    */

    public static void removeKey(Context context, String key){
        SharedPreferences prefs = getPreferences(context);
        SharedPreferences.Editor editor = prefs.edit();
        editor.remove(key);
        editor.commit();
    }

    /* 모든 저장 데이터 삭제
      param context
    */

    public static void clear(Context context){
        SharedPreferences prefs = getPreferences(context);
        SharedPreferences.Editor editor = prefs.edit();
        editor.clear();
        editor.commit();
    }

}

 

 

3. 리사이클러뷰 적용

'리사이클러뷰 구현' 포스트를 사용하였고, 일부 메모장 앱에 사용할 수 있도록 수정했습니다.

* MemoAdapter.class

public class MemoAdapter extends RecyclerView.Adapter<MemoAdapter.ViewHolder>{


    private Activity mcontext;
	
    // Memo 객체를 담을 MemoItem / 작성일/제목/내용 이 담긴다
    private ArrayList<MemoItem> items = new ArrayList<>();


    public MemoAdapter(Activity context) {
        mcontext = context;
    }
	
    // 리사이클러뷰에 데이터 추가 메소드
    public void addItem(MemoItem item) {
        items.add(item);
    }

    @NonNull
    @Override
    public MemoAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) ;
		
        // 미리 만들어 놓은 item_rv_memo.xml 기입
        View view = inflater.inflate(R.layout.item_rv_memo, parent, false) ;
        MemoAdapter.ViewHolder vh = new MemoAdapter.ViewHolder(view) ;

        return vh;
    }

    @Override
    public int getItemCount() {
        return items.size() ;
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onBindViewHolder(@NonNull final MemoAdapter.ViewHolder holder, final int position) {
        MemoItem item = items.get(position);
        // 메모 아이템 xml상에 메모 데이터가 적용되도록 세팅
        holder.setItem(item);
		
        // 메모 아이템 안에 있는 보기 버튼을 클릭하여 상세보기(ViewActivity)로 이동
        holder.view_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(mcontext, ViewActivity.class);
                intent.putExtra("key",holder.date.getText().toString());
                mcontext.startActivity(intent);
            }
        });


    }

	// 커스텀 뷰 홀더가 아님
    public class ViewHolder extends RecyclerView.ViewHolder{
        TextView date;
        TextView title;
        Button view_btn;
        Button delete_btn;

        ViewHolder(View itemView){
            super(itemView);
            
            //뷰홀더에 필요한 아이템데이터 findview
            date = itemView.findViewById(R.id.date_contain);//아이템에 들어갈 텍스트
            title = itemView.findViewById(R.id.title_contain);//아이템에 들어갈 텍스트
            view_btn = itemView.findViewById(R.id.view_btn);
            delete_btn = itemView.findViewById(R.id.delete_btn);
        }
        //아이템뷰에 binding할 데이터
        public void setItem(MemoItem item) {
            date.setText(item.getDate());
            title.setText(item.getTitle());

        }
    }

}

* MemoItem.class

public class MemoItem {
    String date;
    String title;
    String content;

    public MemoItem(String date, String title, String content) {
        this.date = date;
        this.title = title;
        this.content = content;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

 

 

리사이클러뷰 클래스를 만들었으니 다시 MainActivity로 돌아가 리사이클러뷰를 적용하자.

 

 

*MainActivity.class / 리사이클러뷰 및 SharedPreference 데이터 불러오기

RecyclerView recyclerView;
MemoAdapter memoAdapter;


//onCreate
//리사이클러뷰 세팅
LinearLayoutManager linearLayoutManager;
recyclerView = findViewById(R.id.memo_rv);//리사이클러뷰 findView
linearLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);

memoAdapter = new MemoAdapter(MainActivity.this);
recyclerView.setLayoutManager(linearLayoutManager);//linearlayout 세팅
recyclerView.setAdapter(memoAdapter);//adapter 세팅


 //쉐어드 모든 키 벨류 가져오기
SharedPreferences prefb =getSharedPreferences("memo_contain", MODE_PRIVATE);
Collection<?> col_val =  prefb.getAll().values();
Iterator<?> it_val = col_val.iterator();
Collection<?> col_key = prefb.getAll().keySet();
Iterator<?> it_key = col_key.iterator();


while(it_val.hasNext() && it_key.hasNext()) {
    String key = (String) it_key.next();
    String value = (String) it_val.next();
    
    // value 값은 다음과 같이 저장되어있다
    // "{\"title\":\"hi title\",\"content\":\"hi content\"}"
    try {
    	// String으로 된 value를 JSONObject로 변환하여 key-value로 데이터 추출
        JSONObject jsonObject = new JSONObject(value);
        String title = (String) jsonObject.getString("title");
        String content = (String) jsonObject.getString("content");
        // 리사이클러뷰 어뎁터 addItem으로 목록 추가
        memoAdapter.addItem(new MemoItem(key, title, content));
    } catch (JSONException e) {

    }
	
    // 목록 갱신하여 뷰에 띄어줌
    memoAdapter.notifyDataSetChanged();

}

 

*MainActivity.class / 메모 작성 액티비티에서 작성한 데이터를 받아 리사이클러뷰 목록에 적용 코드

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_TEST) {
            if (resultCode == RESULT_OK) {
				// 전달 받은 값
                Intent intent = getIntent();
                String get_date = data.getStringExtra("date");
                String get_title = data.getStringExtra("title");
                String get_content = data.getStringExtra("content");
				// 리사이클러뷰 목록에 추가
                memoAdapter.addItem(new MemoItem(get_date,get_title,get_content));
                // 목록 갱신
                memoAdapter.notifyDataSetChanged();
                Toast.makeText(MainActivity.this, "작성 되었습니다", Toast.LENGTH_SHORT).show();
            } else {   // RESULT_CANCEL
                Toast.makeText(MainActivity.this, "저장 되지 않음", Toast.LENGTH_SHORT).show();
            }

        }
    }

*MainActivity.class / 전체

public class MainActivity extends AppCompatActivity {
    private int REQUEST_TEST = 200;

    Button write_btn;
    PreferenceManager pref;
    RecyclerView recyclerView;
    MemoAdapter memoAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pref = new PreferenceManager();
        write_btn = findViewById(R.id.write_btn);
        write_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(), WriteActivity.class);
                startActivityForResult(intent,REQUEST_TEST);
            }
        });

        //리사이클러뷰 세팅
        LinearLayoutManager linearLayoutManager;
        recyclerView = findViewById(R.id.memo_rv);//리사이클러뷰 findView
        linearLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);

        memoAdapter = new MemoAdapter(MainActivity.this);
        recyclerView.setLayoutManager(linearLayoutManager);//linearlayout 세팅
        recyclerView.setAdapter(memoAdapter);//adapter 세팅


        //쉐어드 모든 키 벨류 가져오기
        SharedPreferences prefb =getSharedPreferences("memo_contain", MODE_PRIVATE);
        Collection<?> col_val =  prefb.getAll().values();
        Iterator<?> it_val = col_val.iterator();
        Collection<?> col_key = prefb.getAll().keySet();
        Iterator<?> it_key = col_key.iterator();

        while(it_val.hasNext() && it_key.hasNext()) {
            String key = (String) it_key.next();
            String value = (String) it_val.next();
            try {
                JSONObject jsonObject = new JSONObject(value);
                String title = (String) jsonObject.getString("title");
                String content = (String) jsonObject.getString("content");
                memoAdapter.addItem(new MemoItem(key, title, content));
            } catch (JSONException e) {
				Log.d("MainActivity","JSONObject : "+e)
            }

            memoAdapter.notifyDataSetChanged();

        }
        //pref.clear(MainActivity.this);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_TEST) {
            if (resultCode == RESULT_OK) {

                Intent intent = getIntent();
                String get_date = data.getStringExtra("date");
                String get_title = data.getStringExtra("title");
                String get_content = data.getStringExtra("content");

                memoAdapter.addItem(new MemoItem(get_date,get_title,get_content));
                memoAdapter.notifyDataSetChanged();
                Toast.makeText(MainActivity.this, "작성 되었습니다", Toast.LENGTH_SHORT).show();

            } else {   // RESULT_CANCEL
                Toast.makeText(MainActivity.this, "저장 되지 않음", Toast.LENGTH_SHORT).show();
            }

        }
    }
}

 

 

 

 

4. 메모 상세보기

'MemoAdapter' 중간 onBindViewHolder 부분에 있는 메모 상세보기 버튼 클릭리스너가 있다.

SharedPreference로 저장된 Key(작성일)을 호출하여 상세 페이지에 데이터를 표기 한다.

 

* ViewActivity.class

public class ViewActivity extends AppCompatActivity {
    PreferenceManager pref;
    TextView view_title;
    TextView view_content;
    Button back_list_btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view);

        pref = new PreferenceManager();
        view_title = findViewById(R.id.view_title);
        view_content = findViewById(R.id.view_content);
        back_list_btn = findViewById(R.id.back_list_btn);
		
        // 인텐트로 리사이클러뷰 목록 하나의 키값을 받는다
        Intent intent = getIntent();
        String key = intent.getStringExtra("key");

        String value = pref.getString(getApplication(),key);
        try {
            JSONObject jsonObject = new JSONObject(value);
            String title = (String) jsonObject.getString("title");
            String content = (String) jsonObject.getString("content");
            view_title.setText(title);
            view_content.setText(content);

        } catch (JSONException e) {
            e.printStackTrace();
        }

        back_list_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

    }
}

 

지금까지 스틱코드를 이용하여 메모장 어플을 만들어 보았습니다.

다음 포스트에는 이어서 메모 수정과 삭제를 올릴 예정입니다.

 

 

스틱코드 참고 포스트

 

* 팀노바 기초 _ 안드로이드 자주쓰는 메소드

stickode.com/detail.html?no=1193

 

스틱코드

 

stickode.com

* 팀노바_기초_안드로이드 setOnClickListener

 

stickode.com/detail.html?no=1351

 

스틱코드

 

stickode.com

* sharedpreferences 간편 사용 클래스 만들기

stickode.com/detail.html?no=1548

 

스틱코드

 

stickode.com

* 안드로이드 FindView, Button, BackPressed, Dialog, PoPup 등 기타

stickode.com/detail.html?no=1845

 

스틱코드

 

stickode.com

*리사이클러뷰 구현

stickode.com/detail.html?no=1504

 

스틱코드

 

stickode.com

* SharedPreference 모든 키벨류 불러오기

stickode.com/detail.html?no=1881

 

스틱코드

 

stickode.com

* 안드로이드 레이아웃 테두리 넣기

stickode.com/detail.html?no=1171

 

스틱코드

 

stickode.com