본문 바로가기

Android

안드로이드 채팅앱 만들기 (ListView, Adapter)

안드로이드 채팅앱 만들기 (ListView, Adapter)

우리가 생각하는 카카오톡같은 채팅앱을 구현하기 위해서는 Adapter와 ListView를 사용해야 한다. 

(ListView는 AdapterView에, AdapterView는 다시 ViewGroup에 속해 있다)


프리뷰


요약하자면 액티비티에 ListView를 추가하고 ListView의 아이템에 대한 Layout(모양, 구성)을 설정한 후
Adapter 클래스를 이용해 ListView에 아이템을 추가하는 과정이다.


1 ListView가 표시될 위치를 결정한다.



2 각 아이템에 대한 Layout 구성을 위해, 간단한 레이아웃을 만들 것이다. 



지금은 카톡처럼 프로필사진, 시간 등을 구성하지 않고 텍스트 하나만 나오게 구성해볼 생각이다.
Root element를 TextView로 설정한다.





3 ListView에 들어갈 아이템 데이터에 대한 클래스를 정의한다.
간단한 예를 위해 ArrayList에 이름을 넣었다.

public class MainActivity extends AppCompatActivity {
ArrayList<String> array = new ArrayList<>();

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

array.add("안영만");
array.add("조지영");
array.add("박경도");
array.add("임송하");
array.add("김희정");
array.add("홍성은");
array.add("박태주");
array.add("김병우");
array.add("윤지호");
array.add("강새힘");
array.add("박찬울");
array.add("이은비");
array.add("윤다솔");
array.add("강준희");

4 Adapter 클래스 상속 및 구현(현재 생략)

ArrayAdapter객체를 생성 후 ListView에 지정한다. 우리가 추가해놓았던 ArrayList의 값들이 ListView에 하나씩 보여지게 된다.
lv = (ListView) findViewById(R.id.listView);


//현재화면정보, 어떤 모양으로 들어갈지, 데이터
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.simplelist, array);
lv.setAdapter(adapter);

버튼과 에딧텍스트 추가후, 
이름을 입력하고 보내기를 누르면 ListView에 올라가게 한다. 
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

array.add(edt.getText().toString()); //버튼을 클릭하면 array에 추가
adapter.notifyDataSetChanged(); //어댑터 새로고침
edt.setText("");
}
});

transcriptMode 속성을 alwaysScroll로 변경하면

내용에 따라 스크롤이 자동으로 생성된다.




채팅앱에서 각 채팅마다 경계선이 있는 경우는 보지 못했다.

divider와 dividerHeight 속성을 통해 ListView의 각각의 아이템마다 그어져있는 줄을 없앤다.




길게 누르면 해당 내용을 삭제할수있게 하는 기능을 추가한다.

lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { // view:클릭한 뷰 position:index id:position이랑 일반적으로 같다
return false;//true하면 일반클릭과 롱클릭 둘다 먹고 false하면 롱클릭만 먹는다
}
});

예/아니오까지 추가했다.
//길게누르면 다이얼로그 띄우기
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int i, long id) { // view:클릭한 뷰 position: id:position이랑 일반적으로 같다
final int position = i;

AlertDialog.Builder builder= new AlertDialog.Builder(getApplicationContext());
//builder에게 옵션주기
builder.setTitle("삭제하기");
builder.setMessage("이 메시지를 삭제할까요?");

//3개 가능/ 메시지, 일어나야하는일
builder.setPositiveButton("네", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {
array.remove(position);
adapter.notifyDataSetChanged();//새로고침
}
});
//취소
builder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})

builder.show();

return false;//true하면 일반클릭과 롱클릭 둘다 먹고 false하면 롱클릭만 먹는다
}
});



채팅을 하려면 사용자가 있어야하지 않겠는가?

로그인페이지를 만들었다.



가입 같은건 생략했다.

LoginActivity.java
package com.example.pc_20.chatting;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class LoginActivity extends AppCompatActivity {

EditText login_id;
EditText login_pw;
Button btn_login;

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

login_id = findViewById(R.id.login_id);
login_pw = findViewById(R.id.login_pw);
btn_login = findViewById(R.id.btn_login);

btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(login_id.getText().toString().equals("연상") && login_pw.getText().toString().equals("1234")){
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra("id", login_id.getText().toString());
startActivity(intent);
finish();
}else{
Toast.makeText(getApplicationContext(), "로그인에 실패했어요.", Toast.LENGTH_LONG).show();
}
}
});

}
}

로그인한 아이디 얻어와서 
//로그인한 아이디
id = getIntent().getStringExtra("id");

메시지 앞에 아이디를 추가한다.
아이디가 '연상'이므로 [ 연상 : 안녕? ] 과 같은 형태로 출력될 것이다.
array.add(id+" : "+ edt.getText().toString()); //버튼을 클릭하면 array에 추가


이제 기본적인 기능이 구현되었으니 ListView를 카톡모양으로 커스텀할 것이다.
Activity를 생성하고(ChatActivity), 지금까지 작업했던 main의 xml을 그대로 붙여넣는다. 이전 Activity는 삭제해도 무방하다.
마찬가지로 리소스파일을 생성하고, 상대의 채팅은 왼쪽에, 내 채팅은 오른쪽에 나오도록 구현할 것이다.

위에서는 데이터가 String 하나였기 때문에 ArrayAdapter를 썼는데,
이제는 들어갈 데이터가 많기 때문에 커스텀어댑터를 만든다.
아래와 같이 클래스를 생성한다.


추상클래스이기때문에 만들고 아래 메소드들을 오버라이드한다. (ALT+INSERT)

ChatAdapter.java
package com.example.pc_20.chatting;

import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

/**
* Created by pc-20 on 2017-12-13.
*/

public class ChatAdapter extends BaseAdapter {
@Override
public int getCount() {
return 0;
}

@Override
public Object getItem(int position) {
return null;
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
}

ChatActivity.java
ChatAdapter adapter = new ChatAdapter(getApplicationContext(), R.layout.talklist, list);
((ListView)findViewById(R.id.listView)).setAdapter(adapter);

생성자를 만들어 오류를 해결한다.

ChatAdapter.java
private Context context;
private int layout;
private ArrayList<ChatVO> chatData;


public ChatAdapter(Context applicationContext, int talklist, ArrayList<ChatVO> list) {
this.context = applicationContext;
this.layout = talklist;
this.chatData = list;
}


(id만 알고있는) 레아이웃을 눈에 보이는 뷰로 바꾸는걸 inflate라고 하는데 그걸 하는놈을 inflater 라고 한다. 
inflate 작업은 activity만 할 수 있어 chatAdapter는 inflate가 불가하기 때문에, 생성자에 있는 applicationContext에서 inflater를 추출할 것이다.
private Context context;
private int layout;
private ArrayList<ChatVO> chatData;
private LayoutInflater inflater;


public ChatAdapter(Context applicationContext, int talklist, ArrayList<ChatVO> list) {
this.context = applicationContext;
this.layout = talklist;
this.chatData = list;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
 

@Override
public int getCount() { // 전체 데이터 개수
return chatData.size();
}

@Override
public Object getItem(int position) { // position번째 아이템
return chatData.get(position);
}

@Override
public long getItemId(int position) { // position번째 항목의 id인데 보통 position
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
//항목의 index, 전에 inflate 되어있는 view, listView
//첫항목을 그릴때만 inflate 함 다음거부터는 매개변수로 넘겨줌 (느리기때문) : recycle이라고 함

if(convertView == null){
//어떤 레이아웃을 만들어 줄 것인지, 속할 컨테이너, 자식뷰가 될 것인지
convertView = inflater.inflate(layout, parent, false); //아이디를 가지고 view를 만든다
}

ImageView img = (ImageView) convertView.findViewById(R.id.iv_profile);
img.setImageResource(chatData.get(position).getImageID()); // 해당 사람의 프사 가져옴
TextView tv_msg = (TextView) convertView.findViewById(R.id.tv_content);
tv_msg.setText(chatData.get(position).getContent());
TextView tv_time = (TextView)convertView.findViewById(R.id.tv_time);
tv_time.setText(chatData.get(position).getTime());
TextView tv_name = (TextView)convertView.findViewById(R.id.tv_id);
tv_name.setText(chatData.get(position).getId());


return convertView;
}
}


뷰홀더패턴을 이용해 findViewById를 한번만 하게 했다. 
@Override
public View getView(int position, View convertView, ViewGroup parent) { //항목의 index, 전에 inflate 되어있는 view, listView

//첫항목을 그릴때만 inflate 함 다음거부터는 매개변수로 넘겨줌 (느리기때문) : recycle이라고 함
ViewHolder holder;

if(convertView == null){
//어떤 레이아웃을 만들어 줄 것인지, 속할 컨테이너, 자식뷰가 될 것인지
convertView = inflater.inflate(layout, parent, false); //아이디를 가지고 view를 만든다
holder = new ViewHolder();
holder.img= (ImageView)convertView.findViewById(R.id.iv_profile);
holder.tv_msg = (TextView)convertView.findViewById(R.id.tv_content);
holder.tv_name = (TextView)convertView.findViewById(R.id.tv_id);
holder.tv_time = (TextView)convertView.findViewById(R.id.tv_time);

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

holder.img.setImageResource(chatData.get(position).getImageID()); // 해당 사람의 프사 가져옴
holder.tv_msg.setText(chatData.get(position).getContent());
holder.tv_time.setText(chatData.get(position).getTime());
holder.tv_name.setText(chatData.get(position).getId());

return convertView;
}

//뷰홀더패턴
public class ViewHolder{
ImageView img;
TextView tv_msg;
TextView tv_time;
TextView tv_name;
}

보내기버튼 누르면 내용 추가
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

Date today = new Date();
SimpleDateFormat timeNow = new SimpleDateFormat("a K:mm");
StringBuffer sb = new StringBuffer(edt.getText().toString());
if (sb.length() >= 15) {
for (int i = 1; i <= sb.length() / 15; i++) {

sb.insert(15 * i, "\n");
}
}
list.add(new ChatVO(R.drawable.profile1, id, sb.toString(), timeNow.format(today)));
adapter.notifyDataSetChanged();
edt.setText("");
}
});

내 채팅 수정.
final ChatAdapter adapter = new ChatAdapter(getApplicationContext(), R.layout.talklist, list, id);

생성자도 수정한다.
public class ChatAdapter extends BaseAdapter {

private Context context;
private int layout;
private ArrayList<ChatVO> chatData;
private LayoutInflater inflater;
private String id;


public ChatAdapter(Context applicationContext, int talklist, ArrayList<ChatVO> list, String id) {
this.context = applicationContext;
this.layout = talklist;
this.chatData = list;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.id= id;
}


최종 Adapter 코드.
내가 보낸 채팅인지, 상대가 보낸 채팅인지 판별하고 Visible로 제어한다.

chatAdapter.java
package com.example.pc_20.chatting;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

/**
* Created by pc-20 on 2017-12-13.
*/

public class ChatAdapter extends BaseAdapter {

private Context context;
private int layout;
private ArrayList<ChatVO> chatData;
private LayoutInflater inflater;
private String id;


public ChatAdapter(Context applicationContext, int talklist, ArrayList<ChatVO> list, String id) {
this.context = applicationContext;
this.layout = talklist;
this.chatData = list;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.id= id;
}

@Override
public int getCount() { // 전체 데이터 개수
return chatData.size();
}

@Override
public Object getItem(int position) { // position번째 아이템
return chatData.get(position);
}

@Override
public long getItemId(int position) { // position번째 항목의 id인데 보통 position
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) { //항목의 index, 전에 inflate 되어있는 view, listView

//첫항목을 그릴때만 inflate 함 다음거부터는 매개변수로 넘겨줌 (느리기때문) : recycle이라고 함
ViewHolder holder;

if(convertView == null){
//어떤 레이아웃을 만들어 줄 것인지, 속할 컨테이너, 자식뷰가 될 것인지
convertView = inflater.inflate(layout, parent, false); //아이디를 가지고 view를 만든다
holder = new ViewHolder();
holder.img= (ImageView)convertView.findViewById(R.id.iv_profile);
holder.tv_msg = (TextView)convertView.findViewById(R.id.tv_content);
holder.tv_name = (TextView)convertView.findViewById(R.id.tv_id);
holder.tv_time = (TextView)convertView.findViewById(R.id.tv_time);
holder.my_msg = (TextView)convertView.findViewById(R.id.my_msg);
holder.my_time = (TextView)convertView.findViewById(R.id.my_time);

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

//누군지 판별
if(chatData.get(position).getId().equals(id)){
holder.tv_time.setVisibility(View.GONE);
holder.tv_name.setVisibility(View.GONE);
holder.tv_msg.setVisibility(View.GONE);
holder.img.setVisibility(View.GONE);

holder.my_msg.setVisibility(View.VISIBLE);
holder.my_time.setVisibility(View.VISIBLE);

holder.my_time.setText(chatData.get(position).getTime());
holder.my_msg.setText(chatData.get(position).getContent());
}else{
holder.tv_time.setVisibility(View.VISIBLE);
holder.tv_name.setVisibility(View.VISIBLE);
holder.tv_msg.setVisibility(View.VISIBLE);
holder.img.setVisibility(View.VISIBLE);

holder.my_msg.setVisibility(View.GONE);
holder.my_time.setVisibility(View.GONE);

holder.img.setImageResource(chatData.get(position).getImageID()); // 해당 사람의 프사 가져옴
holder.tv_msg.setText(chatData.get(position).getContent());
holder.tv_time.setText(chatData.get(position).getTime());
holder.tv_name.setText(chatData.get(position).getId());
}

return convertView;
}

//뷰홀더패턴
public class ViewHolder{
ImageView img;
TextView tv_msg;
TextView tv_time;
TextView tv_name;
TextView my_time;
TextView my_msg;
}

}


상대와 채팅하고 채팅내역 저장을 위해 파이어베이스를 사용할 것이다.
Tools - Firebase 클릭.


에서 Realtime Database 클릭하고 순서대로 하면 된다.



3 누구나 접근할 수 있게 함.
공캐코드복사해서 내코드로 간다음
Database - get started - RULES - 코드추가

4 올릴 데이터를 추가한다.
// Write a message to the database
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("message");
myRef.setValue("Hello, World!");

ChatVO.java에 디폴트생성자를 추가한다.
public ChatVO(){};

보내기버튼을 누르면 
myRef.setValue(new ChatVO(R.drawable.profile1, id, sb.toString(), timeNow.format(today)));

채팅내역이 업로드된 것을 확인할 수 있다.

그런데 아마 채팅을 보낼 때마다 덮어쓰기가 될텐데, 코드를 아래와 같이 변경하면 
myRef.push().setValue(new ChatVO(R.drawable.profile1, id, sb.toString(), timeNow.format(today)));

채팅 하나마다 따로 저장된다.



5 Oncreate 아래 코드추가 
새로운 밸류가 추가되면 호출되는 메소드 onDataChange), onCancelled() 오버라이드.
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = dataSnapshot.getValue(String.class);
}

@Override
public void onCancelled(DatabaseError error) {
}
});

보내기버튼을 누르면 새로운 밸류가 추가되고, 이 밸류를 꺼내와 리스트에 추가한 뒤 어댑터를 새로고침하여 채팅창에 나타나게 한다.
//새로운 밸류가 추가되면 호출되는 메소드
myRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
ChatVO value = dataSnapshot.getValue(ChatVO.class); // 괄호 안 : 꺼낼 자료 형태
list.add(value);
adapter.notifyDataSetChanged();
}

@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {

}

@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {

}

@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {

}

@Override
public void onCancelled(DatabaseError databaseError) {

}
});


완성된 앱의 모습. (구리다고 극딜당하는 중)








전체코드:

LoginActivity.java
package com.example.pc_20.chatting;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

public class LoginActivity extends AppCompatActivity {

EditText login_id;
EditText login_pw;
Button btn_login;

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

login_id = findViewById(R.id.login_id);
login_pw = findViewById(R.id.login_pw);
btn_login = findViewById(R.id.btn_login);

btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(login_id.getText().toString().equals(login_pw.getText().toString())){
Intent intent = new Intent(LoginActivity.this, ChatActivity.class);
intent.putExtra("id", login_id.getText().toString());
startActivity(intent);
finish();
}else{
Toast.makeText(getApplicationContext(), "로그인에 실패했어요.", Toast.LENGTH_LONG).show();
}
}
});

}
}


ChatAdapter.java
package com.example.pc_20.chatting;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

/**
* Created by pc-20 on 2017-12-13.
*/

public class ChatAdapter extends BaseAdapter {

private Context context;
private int layout;
private ArrayList<ChatVO> chatData;
private LayoutInflater inflater;
private String id;


public ChatAdapter(Context applicationContext, int talklist, ArrayList<ChatVO> list, String id) {
this.context = applicationContext;
this.layout = talklist;
this.chatData = list;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.id= id;
}

@Override
public int getCount() { // 전체 데이터 개수
return chatData.size();
}

@Override
public Object getItem(int position) { // position번째 아이템
return chatData.get(position);
}

@Override
public long getItemId(int position) { // position번째 항목의 id인데 보통 position
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) { //항목의 index, 전에 inflate 되어있는 view, listView

//첫항목을 그릴때만 inflate 함 다음거부터는 매개변수로 넘겨줌 (느리기때문) : recycle이라고 함
ViewHolder holder;

if(convertView == null){
//어떤 레이아웃을 만들어 줄 것인지, 속할 컨테이너, 자식뷰가 될 것인지
convertView = inflater.inflate(layout, parent, false); //아이디를 가지고 view를 만든다
holder = new ViewHolder();
holder.img= (ImageView)convertView.findViewById(R.id.iv_profile);
holder.tv_msg = (TextView)convertView.findViewById(R.id.tv_content);
holder.tv_name = (TextView)convertView.findViewById(R.id.tv_id);
holder.tv_time = (TextView)convertView.findViewById(R.id.tv_time);
holder.my_msg = (TextView)convertView.findViewById(R.id.my_msg);
holder.my_time = (TextView)convertView.findViewById(R.id.my_time);

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

//누군지 판별
if(chatData.get(position).getId().equals(id)){
holder.tv_time.setVisibility(View.GONE);
holder.tv_name.setVisibility(View.GONE);
holder.tv_msg.setVisibility(View.GONE);
holder.img.setVisibility(View.GONE);

holder.my_msg.setVisibility(View.VISIBLE);
holder.my_time.setVisibility(View.VISIBLE);

holder.my_time.setText(chatData.get(position).getTime());
holder.my_msg.setText(chatData.get(position).getContent());
}else{
holder.tv_time.setVisibility(View.VISIBLE);
holder.tv_name.setVisibility(View.VISIBLE);
holder.tv_msg.setVisibility(View.VISIBLE);
holder.img.setVisibility(View.VISIBLE);

holder.my_msg.setVisibility(View.GONE);
holder.my_time.setVisibility(View.GONE);

holder.img.setImageResource(chatData.get(position).getImageID()); // 해당 사람의 프사 가져옴
holder.tv_msg.setText(chatData.get(position).getContent());
holder.tv_time.setText(chatData.get(position).getTime());
holder.tv_name.setText(chatData.get(position).getId());
}


return convertView;
}

//뷰홀더패턴
public class ViewHolder{
ImageView img;
TextView tv_msg;
TextView tv_time;
TextView tv_name;
TextView my_time;
TextView my_msg;
}

}

ChatVO.java
package com.example.pc_20.chatting;

/**
* Created by pc-20 on 2017-12-13.
*/

public class ChatVO {

private int imageID ;
private String id;
private String content;
private String time;

public ChatVO(){}

public ChatVO(int imageID, String id, String content, String time) {
this.imageID = imageID;
this.id = id;
this.content = content;
this.time = time;
}

public int getImageID() {
return imageID;
}

public String getId() {
return id;
}

public String getContent() {
return content;
}

public String getTime() {
return time;
}
}


ChatActivity.java
package com.example.pc_20.chatting;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

public class ChatActivity extends AppCompatActivity {

ArrayList<ChatVO> list = new ArrayList<>();
ListView lv;
Button btn;
EditText edt;
int[] imageID = {R.drawable.profile1, R.drawable.profile2, R.drawable.profile3};

String id = "";

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

/* 텍스트뷰만 있을때만 쓸수있어
ArrayAdapter<ChatVO> adapter = new ArrayAdapter<ChatVO>(getApplicationContext(), R.layout.talklist, list);*/

lv = findViewById(R.id.listView);
edt = findViewById(R.id.editText);
btn = findViewById(R.id.bnt_send);

// Write a message to the database
FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myRef = database.getReference("message");


//로그인한 아이디
id = getIntent().getStringExtra("id");
//lv.setAdapter(adapter);

//list.add(new ChatVO(R.drawable.profile3, "찡찡이", "안녕", "오후 4:42"));

final ChatAdapter adapter = new ChatAdapter(getApplicationContext(), R.layout.talklist, list, id);
((ListView) findViewById(R.id.listView)).setAdapter(adapter);

btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

if (edt.getText().toString().equals("")) {
Toast.makeText(getApplicationContext(), "내용을 입력하세요.", Toast.LENGTH_LONG).show();
} else {
Date today = new Date();
SimpleDateFormat timeNow = new SimpleDateFormat("a K:mm");

StringBuffer sb = new StringBuffer(edt.getText().toString());
if (sb.length() >= 15) {
for (int i = 1; i <= sb.length() / 15; i++) {
sb.insert(15 * i, "\n");
}
}

//list.add(new ChatVO(R.drawable.profile1, id, sb.toString(), timeNow.format(today)));
//adapter.notifyDataSetChanged();

myRef.push().setValue(new ChatVO(R.drawable.profile1, id, sb.toString(), timeNow.format(today)));
edt.setText("");

}
}
});

myRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
ChatVO value = dataSnapshot.getValue(ChatVO.class); // 괄호 안 : 꺼낼 자료 형태
list.add(value);
adapter.notifyDataSetChanged();
}

@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {

}

@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {

}

@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {

}

@Override
public void onCancelled(DatabaseError databaseError) {

}
});

}
}