Android

안드로이드 5기 2017년 강의 정리 3 (오준석의 생존코딩)

 

https://www.youtube.com/watch?v=qCyHkVRZnXo&list=PLxTmPHxRH3VWSF7kMcsIaTglWUJZpWeQ9&index=56

https://github.com/suwonsmartapp/MyFirstAndroidApp5ki

MyFirstAndroidApp5ki-master.zip

 

19일차, 20일차, 24일차, 28일차 메모장, 데이터베이스, Toolbar SearchView, RecyclerView

21일차 갤러리, Glide

22일차 23일차 스레드, AsyncTask, ProgressDialog

24일차 Socket프로그래밍

25일차 채팅 수정

26일차 카톡 짝퉁

26일차 RecyclerView

 


 

19일차, 20일차, 24일차, 28일차 메모장, 데이터베이스, Toolbar SearchView, RecyclerView

 

# SQLite를 사용하여 데이터 저장 (android developers)
https://developer.android.com/training/data-storage/sqlite#java

 

# SQL Tutorial (w3schools.com)
https://www.w3schools.com/sql/

 

# MemoActivity.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/MemoActivity.java

# MemoContract.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/db/MemoContract.java

# MemoDbHelper.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/db/MemoDbHelper.java

# MemoFacade.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/db/MemoFacade.java

 

 

schema (구조)

 

SELECT Orders.OrderID, Customers.CustomerName
FROM Orders
INNER JOIN Customers
ON Orders.CustomerID = Customers.CustomerID
WHERE Customers.CustomerName LIKE 'a__%';

# Wildcards
WHERE City LIKE '[bsp]%';
WHERE City LIKE '[a-c]%';
WHERE City LIKE '[!bsp]%';
WHERE City NOT LIKE '[bsp]%';

IN operator
WHERE Country IN ('Germany''France''UK');

 


 

21일차 갤러리

 

# GalleryFragment.java

https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/fragments/GalleryFragment.java

# GalleryActivity.java

https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/GalleryActivity.java

# activity_gallery.xml

https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/layout/activity_gallery.xml

# fragment_gallery.xml

https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/layout/fragment_gallery.xml

 

 

 


 

22일차 스레드

 

# Processes and threads overview
https://developer.android.com/guide/components/processes-and-threads#java

# AsyncTask (android developers)
https://developer.android.com/reference/android/os/AsyncTask

 

# ThreadActivity.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/ThreadActivity.java

# AsyncTaskActivity.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/AsyncTaskActivity.java

# activity_thread.xml
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/layout/activity_thread.xml

# activity_async_task.xml
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/layout/activity_async_task.xml

 

# GalleryActivity.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/GalleryActivity.java

# GalleryFragment.java (Glide 사용)
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/fragments/GalleryFragment.java

# fragment_gallery.xml
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/layout/fragment_gallery.xml

# activity_gallery.xml
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/layout/activity_gallery.xml

 

 

public class ThreadActivity extends AppCompatActivity {

    private static final String TAG = ThreadActivity.class.getSimpleName();

    private TextView mTextView;
    private int mNumber = 0;

    private Handler mHandler = new Handler();

    private Handler mHandler2 = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            mTextView.setText(msg.what + "");
        }
    };

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

        mTextView = findViewById(R.id.textView);

        // 메인 스레드에서는 UI 갱신이 가능

        new Thread(new Runnable() {
            @Override
            public void run() {
                // 복잡한 오래 걸리는 처리
                for (int i = 0; i < 10; i++) {
                    mNumber++;
                    try {
                        Thread.sleep(500);
                        // 1. 스레드에서는 UI 갱신이 안 됨
                        // 2. 스레드에서 Handler를 생성할 수 없다
                        // Handler를 사용해서 UI 갱신을 해야 됨
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                // 글자 변경
                                mTextView.setText(mNumber + "");
                            }
                        });

                        // 위에 코드와 같은 코드 1
//                        mHandler2.sendEmptyMessage(mNumber);

                        // 위에 코드와 같은 코드 2
                        // 모든 View는 Handler를 가지고 있다
//                        mTextView.post(new Runnable() {
//                            @Override
//                            public void run() {
//                                mTextView.setText(mNumber + "");
//                            }
//                        });

                        // 위에 코드와 같은 코드 2
//                        runOnUiThread(new Runnable() {
//                            @Override
//                            public void run() {
//                                mTextView.setText(mNumber + "");
//                            }
//                        });

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.d(TAG, "run: " + i);
                }
            }
        }).start();
    }
}

 

 

public class AsyncTaskActivity extends AppCompatActivity {

    private TextView mTextView;

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

        mTextView = (TextView) findViewById(R.id.text_view);

        // 제약사항
        // 1. AsyncTask 클래스는 반드시 UI 스레드에서 로드 해야 된다
        // 2. AsyncTask 인스턴스는 반드시 UI 스레드에서 생성해야 된다
        // 3. execute() 도 반드시 UI 스레드에서 호출해야 된다
        // 4. 모든 콜백들은 직접 호출하면 안된다
        // 5. 태스크 인스턴스는 한번만 실행할 수 있다.
        MyAsyncTask task = new MyAsyncTask();
        task.execute(0);
        task.cancel(true);

//        // 일반적인 사용법
//        // 순차적으로 실행
//        new MyAsyncTask().execute(0);
//        new MyAsyncTask().execute(0);
//        new MyAsyncTask().execute(0);
//
//        // 병렬로 수행되는 AsyncTask
//        new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 0);
//        new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 0);
    }

    public void progressClick(View view) {
//        new ProgressTask(this).execute();
        DownloadDialogFragment fragment =
                DownloadDialogFragment.newInstance("처리 중 입니다");

        fragment.show(getSupportFragmentManager(), "download");

    }

    public void downloadClick(View view) {
        new DownloadTask(this).execute();
    }

    public static class DownloadDialogFragment extends DialogFragment {

        public static DownloadDialogFragment newInstance(String message) {
            DownloadDialogFragment fragment = new DownloadDialogFragment();
            Bundle bundle = new Bundle();
            bundle.putString("message", message);
            fragment.setArguments(bundle);
            return fragment;
        }

        @NonNull
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            String message = getArguments().getString("message");

            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setMessage(message);
            return builder.create();
        }
    }

    private class DownloadTask extends AsyncTask<Void, Integer, Void> {
        private final Context mContext;
        private ProgressDialog mDialog;

        public DownloadTask(Context context) {
            mContext = context;
        }

        @Override
        protected void onPreExecute() {
            // 다이얼로그 보이기
            mDialog = new ProgressDialog(mContext);
            mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            mDialog.setMessage("처리 중 입니다 ...");
            mDialog.create();
            mDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            try {
                for (int i = 0; i <= 100; i++) {
                    Thread.sleep(100);

                    // UI 갱신
                    publishProgress(i);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            mDialog.setProgress(values[0]);
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            // 다이얼로그 숨기기
            if (mDialog != null) {
                mDialog.dismiss();
            }
        }
    }

    private class ProgressTask extends AsyncTask<Void, Void, Void> {
        private final Context mContext;
        private ProgressDialog mDialog;

        public ProgressTask(Context context) {
            mContext = context;
        }

        @Override
        protected void onPreExecute() {
            // 다이얼로그 보이기
            mDialog = new ProgressDialog(mContext);
            mDialog.setMessage("처리 중 입니다 ...");
            mDialog.create();
            mDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            // 다이얼로그 숨기기
            mDialog.dismiss();
        }
    }

    private class MyAsyncTask extends AsyncTask<Integer, Integer, Integer> {

        @Override
        protected void onPreExecute() {
            // 최초 실행 되는 부분
        }

        @WorkerThread  // 의미 전달 위해
        @Override
        protected Integer doInBackground(Integer... params) {
            // 오래 걸리는 처리
            int number = params[0];
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                number++;

                // UI 갱신
                publishProgress(number);    // onProgressUpdate로 넘어감
            }
            return number;  // onPostExecute로 넘어감
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            // UI 갱신
            mTextView.setText(values[0] + "");
        }

        @Override
        protected void onPostExecute(Integer integer) {
            // 오래걸리는 처리가 끝난 후 호출
            Log.d("AsyncTask", "onPostExecute: " + integer);
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();

            // 취소 처리
        }
    }
}

 

# activity_thread.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_thread"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:textSize="32dp"
        android:text="0" />
</RelativeLayout>

 

# activity_async_task.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_async_task"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0"
        android:textSize="32dp" />

    <Button
        android:onClick="progressClick"
        android:id="@+id/progress_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="처리중" />

    <Button
        android:onClick="downloadClick"
        android:id="@+id/download_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="다운로드중" />

</LinearLayout>

 


 

23일차 ProgressDialog

 

# DialogFragment (android developer)
https://developer.android.com/reference/android/app/DialogFragment

 

# Android AsyncTasks during a screen rotation, Part I
https://fattybeagle.com/2011/02/14/android-asynctasks-during-a-screen-rotation-part-i/

 

# ProgressDialog (android developer)
https://developer.android.com/reference/android/app/ProgressDialog

 

 


 

24일차 Socket프로그래밍

 

# Java 소켓 통신 예제
https://gist.github.com/junsuk5/f0ff2298e17853dc48e89f2dfc7bd985

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * 1 대 1 소켓 통신 클라이언트 예제
 */
public class Client {

    private Socket mSocket;

    private BufferedReader mIn;
    private PrintWriter mOut;

    public Client(String ip, int port) {
        try {
            // 서버에 요청 보내기
            mSocket = new Socket(ip, port);
            System.out.println(ip + " 연결됨");

            // 통로 뚫기
            mIn = new BufferedReader(
                    new InputStreamReader(mSocket.getInputStream()));
            mOut = new PrintWriter(mSocket.getOutputStream());

            // 메세지 전달
            mOut.println("응답하라!!");
            mOut.flush();

            // 응답 출력
            System.out.println(mIn.readLine());

        } catch (IOException e) {
            System.out.println(e.getMessage());
        } finally {
            // 소켓 닫기 (연결 끊기)
            try {
                mSocket.close();
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
    }

    public static void main(String[] args) {

        String ip = "192.168.0.10";
        int port = 5555;
        
        new Client(ip, port);
    }
}

 

 

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 1 대 1 소켓 통신 서버 예제
 */
public class Server {
    private ServerSocket mServerSocket;
    private Socket mSocket;

    private BufferedReader mIn;    // 들어오는 통로
    private PrintWriter mOut;  // 나가는 통로

    public Server() {
        try {
            mServerSocket = new ServerSocket(5555);
            System.out.println("서버 시작!!!");
            // 스레드가 멈춰 있고

            // 연결 요청이 들어오면 연결
            mSocket = mServerSocket.accept();
            System.out.println("클라이언트와 연결 됨");

            mIn = new BufferedReader(
                    new InputStreamReader(mSocket.getInputStream()));

            mOut = new PrintWriter(mSocket.getOutputStream());

            // 클라이언트에서 보낸 문자열 출력
            System.out.println(mIn.readLine());

            // 클라이언트에 문자열 전송
            mOut.println("전송 잘 되었음");
            mOut.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 소켓 닫기 (연결 끊기)
            try {
                mSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                mServerSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Server server = new Server();
    }
}

 

 


 

25일차 채팅 수정

 

# ArrayList 스레드 세이프
List<String> synchronizedList = Collections.synchronizedList(new ArrayList<String>());

https://madplay.github.io/post/java-collection-synchronize

 

 


 

26일차 카톡 짝퉁

ListView 에서
divider 와
transcriptMode=”alwaysScroll”

 

# ChatActivity.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/ChatActivity.java

 

 

public class ChatActivity extends AppCompatActivity implements View.OnClickListener, ReceiverThread.OnReceiveListener {

    public static final String NAME = "채팅남2";
    private ListView mMessageListView;
    private EditText mMessageEditText;
    private SenderThread mThread1;

    private Socket mSocket = null;
    private ChatAdapter mAdapter;
    private ArrayList<Chat> mChatDataList;

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

        mMessageListView = (ListView) findViewById(R.id.list_view);
        mMessageEditText = (EditText) findViewById(R.id.message_edit);
        findViewById(R.id.send_button).setOnClickListener(this);

        mChatDataList = new ArrayList<>();
        mAdapter = new ChatAdapter(mChatDataList);
        mMessageListView.setAdapter(mAdapter);

        new Thread(new Runnable() {
            @Override
            public void run() {

                // 일단은 테스트 용으로 본인의 아이피를 입력해서 진행하겠습니다.
                try {
                    mSocket = new Socket("192.168.0.10", 7777);
                    // 두번째 파라메터 로는 본인의 닉네임을 적어줍니다.
                    mThread1 = new SenderThread(mSocket, NAME);
                    ReceiverThread thread2 = new ReceiverThread(mSocket);

                    thread2.setOnReceiveListener(ChatActivity.this);

                    mThread1.start();
                    thread2.start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }

    @Override
    public void onClick(View v) {
        mThread1.sendMessage(mMessageEditText.getText().toString());
        mMessageEditText.setText("");
    }

    @Override
    @WorkerThread
    public void onReceive(final String message) {

        String[] split = message.split(">");

        // ~~가 입장하셨습니다 처리 무시
        if (split.length < 2) {
            return;
        }

        String nickname = split[0];
        String msg = split[1];

        final Chat chat = new Chat();
        if (NAME.equals(nickname)) {
            // 나
            chat.isMe = true;
        } else {
            // 남
            chat.isMe = false;
        }
        chat.nickname = nickname;
        chat.message = msg;

        // UI 스레드로 실행
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // 메세지 갱신
                mChatDataList.add(chat);
                mAdapter.notifyDataSetChanged();
            }
        });
    }

    @Override
    protected void onDestroy() {
        try {
            mSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }

    public static class Chat {
        public String message;
        public String nickname;
        public boolean isMe;
    }

    private static class ChatAdapter extends BaseAdapter {

        private final List<Chat> mData;

        public ChatAdapter(List<Chat> list) {
            mData = list;
        }

        @Override
        public int getCount() {
            return mData.size();
        }

        @Override
        public Object getItem(int position) {
            return mData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if (convertView == null) {
                viewHolder = new ViewHolder();

                convertView = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.item_chat, parent, false);

                viewHolder.layoutMe = (LinearLayout) convertView.findViewById(R.id.layout_me);
                viewHolder.layoutYou = (LinearLayout) convertView.findViewById(R.id.layout_you);
                viewHolder.nickname = (TextView) convertView.findViewById(R.id.nickname_text);
                viewHolder.bubbleYou = (TextView) convertView.findViewById(R.id.bubble_you_text);
                viewHolder.bubbleMe = (TextView) convertView.findViewById(R.id. bubble_me_text);

                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }

            Chat chat = mData.get(position);

            if (chat.isMe) {
                viewHolder.bubbleMe.setText(chat.message);

                viewHolder.layoutMe.setVisibility(View.VISIBLE);
                viewHolder.layoutYou.setVisibility(View.GONE);
            } else {
                viewHolder.bubbleYou.setText(chat.message);
                viewHolder.nickname.setText(chat.nickname);

                viewHolder.layoutMe.setVisibility(View.GONE);
                viewHolder.layoutYou.setVisibility(View.VISIBLE);
            }

            convertView.setEnabled(false);

            return convertView;
        }
    }

    private static class ViewHolder {
        LinearLayout layoutMe;
        LinearLayout layoutYou;
        TextView nickname;
        TextView bubbleYou;
        TextView bubbleMe;
    }
}

class ReceiverThread extends Thread {

    interface OnReceiveListener {
        void onReceive(String message);
    }

    OnReceiveListener mListener;

    public void setOnReceiveListener(OnReceiveListener listener) {
        mListener = listener;
    }

    Socket socket;

    public ReceiverThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            Log.d("receiver", "run: ");
            while (true) {
                String str = reader.readLine();

                if (mListener != null) {
                    mListener.onReceive(str);
                }
            }

        } catch (Exception e) {
            Log.e("chat", "run: " + e.getMessage());
        }
    }

}

/**
 * 메시지의 발신을 담당하는 스레드 입니다.
 */

class SenderThread extends Thread {
    Socket socket;
    String name;
    private PrintWriter mWriter;

    public SenderThread(Socket socket, String name) {
        this.socket = socket;
        this.name = name;
    }

    public void close() {
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(final String message) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                mWriter.println(message);
                mWriter.flush();
            }
        }).start();
    }

    @Override
    public void run() {

        try {
//            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            mWriter = new PrintWriter(socket.getOutputStream());

            // 제일 먼저 서버로 대화명을 송신합니다.
            mWriter.println(name);
            mWriter.flush();

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }


    }

}

 

# activity_chat.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_chat"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.myapplication.activities.ChatActivity">

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#00e5ff"
        android:divider="@android:color/transparent"
        android:transcriptMode="alwaysScroll" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/message_edit"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="메세지를 입력하세요" />

        <Button
            android:id="@+id/send_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="보내기" />
    </LinearLayout>

</LinearLayout>

 

 


 

26일차 RecyclerView

 

# EventBus (콜백 전달)
https://github.com/greenrobot/EventBus

# RecyclerView로 목록 만들기
https://developer.android.com/guide/topics/ui/layout/recyclerview#java

 

# RecyclerViewActivity.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/RecyclerViewActivity.java

# activity_recycler_view.xml
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/layout/activity_recycler_view.xml

# item_text.xml
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/layout/item_text.xml

 

 

public class RecyclerViewActivity extends AppCompatActivity {

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

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);

        List<String> data = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            data.add("data " + i);
        }

        MyRecyclerAdapter adapter = new MyRecyclerAdapter(data);

        recyclerView.setAdapter(adapter);
    }

    /**
     * EventBus 에서 보내는 이벤트 수신하는 콜백 메서드
     * @param event
     */
    @Subscribe
    public void onItemClick(ItemClickEvent event) {
        Toast.makeText(this, "" + event.position, Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onStart() {
        super.onStart();
        // EventBus에 구독자로 현재 액티비티 추가
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // EventBus에 구독자에서 제거
        EventBus.getDefault().unregister(this);
    }

    /**
     * EventBus 에서 발송할 이벤트
     */
    private static class ItemClickEvent {
        View view;
        int position;
    }

    private static class ViewHolder extends RecyclerView.ViewHolder {

        TextView textView;

        public ViewHolder(View itemView) {
            super(itemView);

            textView = itemView.findViewById(R.id.text_text);
        }
    }

    private static class MyRecyclerAdapter extends RecyclerView.Adapter<ViewHolder> {

        private final List<String> mData;

        public MyRecyclerAdapter(List<String> dataList) {
            mData = dataList;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View convertView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_text, parent, false);
            return new ViewHolder(convertView);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
            holder.textView.setText(mData.get(position));

            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // EventBus를 통해 이벤트 발송
                    // RecyclerViewActivity#onItemClick
                    ItemClickEvent event = new ItemClickEvent();
                    event.view = holder.itemView;
                    event.position = position;
                    EventBus.getDefault().post(event);
                }

            });
        }

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

 

# activity_recycler_view.xml

<RelativeLayout 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:id="@+id/activity_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
        app:spanCount="2" />

</RelativeLayout>

 

# item_text.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:background="?android:attr/selectableItemBackground"
    android:orientation="vertical">

    <TextView
        android:text="ddd"
        android:id="@+id/text_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

Related posts

Leave a Comment