聊天界面的实现(参考郭神第一行代码)
效果图如下:
控件图片素材直接用了网上的,仅供学习哈
我们看到,这个布局里有聊天的头像,分布在左右的聊天消息框,各个聊天消息的时间。这里便来实现这个界面
需要自行在build.gradle里添加recyclerView的依赖和圆形图片控件的依赖
圆形图片控件依赖
//CircleImageView
implementation 'de.hdodenhof:circleimageview:2.1.0'
这个聊天部分的界面名字就定为chat_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2018-9-21 11:11:11"
android:layout_gravity="center_horizontal"
/>
<LinearLayout
android:id="@+id/left_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="10dp"
android:src="@drawable/robot_logo" />
<TextView
android:id="@+id/tv_left_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@drawable/chat_bg_cloud"
android:gravity="center_vertical"
android:padding="20dp"
android:text="你好,我叫小可爱"
android:textColor="@android:color/white" />
</LinearLayout>
<LinearLayout
android:id="@+id/right_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right">
<TextView
android:id="@+id/tv_right_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:background="@drawable/chat_bg_user"
android:gravity="center_vertical"
android:padding="20sp"
android:text="你好,你会些什么啊"
android:textColor="@android:color/white" />
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginRight="10dp"
android:src="@drawable/user_logo" />
</LinearLayout>
</LinearLayout>
预览是这样的:
界面就写好了,这里看到一个item就包含了接收和发送的消息,在后面的适配器会根据是接收到的消息还是发送的消息,来进行隐藏对应的消息,比如说,接收到了消息,就隐藏发送的消息那一块布局,所看到的item就只显示接收到的消息的消息框了。
接下来我们需要写一个对话列表的实体类chat.class
/**
* 描述: 聊天消息实体类,这个不是根据json数据来的
* 实体类有两个属性,用来标识是左边接受消息布局(TYPE_RECEIVED)还是右边布局的的type属性(TYPE_SENT)
*/
public class Chat {
public static final int TYPE_RECEIVED = 0;//接收的数据
public static final int TYPE_SENT = 1;//发送的数据
// 对话文本
private String text;
// 标示
private int type;
private String time;
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public Chat(String text, int type,String time) {
this.text = text;
this.type = type;
this.time=time;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
然后创建RecyclerView的适配器类,新建RecyclerViewAdapter.class
/**
* 描述: 聊天布局适配器,参考郭神第一行代码
*/
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
// 上下文
private Context context;
// 对话列表
private List<Chat> mlist;//创建集合mList,用来存储聊天数据
//构造函数,因为在实例化一个类的时候 会执行构造函数里面的代码
public RecyclerViewAdapter(Context context, List<Chat> list) {
this.context = context;
this.mlist = list;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {//加载基本布局
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {//这里主要用于数据、事件绑定
Chat chat = mlist.get(position);
if (chat.getType() == Chat.TYPE_RECEIVED) {
// 如果收的的数据是左边,就显示左边的消息布局,将右边的消息布局隐藏
holder.leftLayout.setVisibility(View.VISIBLE);
holder.rightLayout.setVisibility(View.GONE);
holder.leftChat.setText(chat.getText());//接收到的文本信息
if (!"".equals(chat.getTime())){
holder.Time.setVisibility(View .VISIBLE);
holder.Time.setText(chat.getTime());//接收到消息时的时间
}else {
holder.Time.setVisibility(View .GONE);
}
//
} else if (chat.getType() == chat.TYPE_SENT) {
// 如果发出的消息是右边,就显示右边的消息布局,将左边的消息布局隐藏
holder.rightLayout.setVisibility(View.VISIBLE);
holder.leftLayout.setVisibility(View.GONE);
holder.rightChat.setText(chat.getText());//发送的文本信息
if (!"".equals(chat.getTime())){
holder.Time.setVisibility(View.VISIBLE);
holder.Time.setText(chat.getTime());//发送消息的时间
}else {
holder.Time.setVisibility(View.GONE);
}
}
}
@Override
public int getItemCount() {
return mlist.size();
}
/**
* 声明控件,自定义ViewHolder
*/
class ViewHolder extends RecyclerView.ViewHolder {
LinearLayout leftLayout;
LinearLayout rightLayout;
TextView leftChat;
TextView rightChat;
TextView Time;
public ViewHolder(View itemView) {
super(itemView);
leftLayout = itemView.findViewById(R.id.left_layout);
rightLayout = itemView.findViewById(R.id.right_layout);
leftChat = itemView.findViewById(R.id.tv_left_text);
rightChat = itemView.findViewById(R.id.tv_right_text);
Time=itemView.findViewById(R.id.timer);//消息的时间
}
}
}
接下来就就在MainActivity.class里为recyclerView初始化数据
只贴关键代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
// 聊天消息列表
private RecyclerView recyclerView;
// 对话信息集合
private List<Chat> list = new ArrayList<>();//声明一个集合list来存储我们的聊天数据
// 适配器
private RecyclerViewAdapter recyclerViewAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化数据
initView();
// 加载数据
initData();
// 设置RecyclerView的布局管理器
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerViewAdapter = new RecyclerViewAdapter(this, list);//将集合数据填充到适配器中
recyclerView.setAdapter(recyclerViewAdapter);
}
/**
* @return 获取聊天的当前时间
*/
public String getCurrentTime() {
//long currentTime = System.currentTimeMillis();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//把日期格式化
Date curDate = new Date();
String time = format.format(curDate);
return time;//返回时间给调用该函数的哥们
}
/**
* 加载列表布局数据
*/
private void initData() {
Chat c1 = new Chat("你好,我叫小可爱,你可以跟我聊天,也可以说:打开某某应用,打电话给某人", Chat.TYPE_RECEIVED,getCurrentTime());
list.add(c1);
speakText("你好,我叫小可爱,你可以跟我聊天,也可以说:打开某某应用,打电话给某人");
/* Chat c2 = new Chat("你好,你现在会些什么呢?", Chat.TYPE_SENT);
list.add(c2);*/
}
/**
* 初始化控件
*/
private void initView() {
recyclerView = findViewById(R.id.recycler);
//这里你所需要初始化的控件
}
/**
* 通过传递进来的test和type创建数据实体类,添加到聊天数据集合list中
* @param text
* @param type
*/
public void addData(String text, int type,String time) {
Chat c = new Chat(text, type,getCurrentTime());
list.add(c);//写入text到聊天界面
//当有新消息时,刷新显示
recyclerViewAdapter.notifyItemInserted(list.size() - 1);
//定位的最后一行
recyclerView.scrollToPosition(list.size() - 1);
}
}