Android's writing chat interface practice

(Premise) Making Nine-Path pictures
is explained in detail in my previous section.
Make Nine-Path pictures
Effect picture

Compose a beautiful chat interface:

Since you want to write a chat interface, you must receive and send messages.
The pop.9.png we just made can be used as the background image of the received message, so there is no doubt that you need to make another pop_right.9.png as the background image of the sent message.
Once the pictures are provided, you can start coding. Since we will use RecyclerView later, we first need to add dependent libraries in app/build.gradle, as shown below:

dependencies {
    
    
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
    
    
    exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
}

Next, start writing the main interface and modify the code in activity_main.xml as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#d8e0e8">
<android.support.v7.widget.RecyclerView
    android:id="@+id/msg_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"/>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <EditText
        android:id="@+id/input_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:hint="Type something here"
        android:maxLines="2"
        />
    <Button
        android:id="@+id/send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send"/>
</LinearLayout>

</LinearLayout>

We have placed a RecyclerView in the main interface to display the content of the chat history, an EditText for inputting messages, and a Button for sending messages.
Then define the entity class of the message, create a new Msg, the code is as follows:

package net.nyist.lenovo.message_agetest;
public class Msg {
    
    
public static final int TYPE_RECEIVED = 0;
public static final int TYPE_SENT = 1;
private String content;
private int type;

public Msg(String content,int type){
    
    
    this.content = content;
    this.type = type;
}

public String getContent() {
    
    
    return content;
}

public int getType() {
    
    
    return type;
}
}

There are only two fields in the Msg class. content represents the content of the message, and type represents the type of the message. The message type has two optional values. TYPE_RECEIVED indicates that this is a received message, and TYPE_SENT indicates that this is an outgoing message.
Next, write the layout of the RecyclerView sub-items, and create a new msg_item.xml code as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
>
<LinearLayout
    android:id="@+id/left_layout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="left"
    android:background="@drawable/pop">
    <TextView
        android:id="@+id/left_msg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="10dp"
        android:textColor="#fff"
        />
</LinearLayout>
<LinearLayout
    android:id="@+id/right_layout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="right"
    android:background="@drawable/message_right"
    >
    <TextView
        android:id="@+id/right_msg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="10dp"
        />
</LinearLayout>
</LinearLayout>

Here let us align the received message to the left and the sent message to the right. And use message_left.9.png and message_right.9.png as background images respectively.
Next, you need to create an adapter class for RecycerView, a new class MsgAdapter, the code is as follows:

package net.nyist.lenovo.message_agetest;
	
	import android.support.v7.widget.RecyclerView;
	import android.view.LayoutInflater;
	import android.view.View;
	import android.view.ViewGroup;
	import android.widget.LinearLayout;
	import android.widget.TextView;
	
	import java.util.List;
	
	
	public class MsgAdapter extends RecyclerView.Adapter<MsgAdapter.ViewHolder>{
    
    
    private List<Msg> mMsgList;

    static class ViewHolder extends RecyclerView.ViewHolder{
    
    
        LinearLayout leftLayout;

        LinearLayout rightLayout;

        TextView leftMsg;

        TextView rightMsg;

        public ViewHolder(View view){
    
    
            super(view);
            leftLayout = (LinearLayout)view.findViewById(R.id.left_layout);
            rightLayout = (LinearLayout)view.findViewById(R.id.right_layout);
            leftMsg = (TextView) view.findViewById(R.id.left_msg);
            rightMsg = (TextView)view.findViewById(R.id.right_msg);
        }
        }
        public MsgAdapter(List<Msg>msgList){
    
    
            mMsgList = msgList;
        }

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

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
    
    
        Msg msg = mMsgList.get(position);
        if (msg.getType() == Msg.TYPE_RECEIVED){
    
    
            //如果收到的消息,则显示左边的消息布局,将右边的消息布局隐藏
            holder.leftLayout.setVisibility(View.VISIBLE);
            holder.rightLayout.setVisibility(View.GONE);
            holder.leftMsg.setText(msg.getContent());
        }else if (msg.getType()==Msg.TYPE_SENT){
    
    
            //如果是发出的消息,则显示右边的消息布局,将左边的消息布局隐藏
            holder.rightLayout.setVisibility(View.VISIBLE);
            holder.leftLayout.setVisibility(View.GONE);
            holder.rightMsg.setText(msg.getContent());
        }
    }

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

Finally, modify the code in MainActivity to initialize some data for RecyclerView and send it to the button to add event response. The code is as follows:

package net.nyist.lenovo.message_agetest;
	
	import android.support.v7.app.AppCompatActivity;
	import android.os.Bundle;
	import android.support.v7.widget.LinearLayoutManager;
	import android.support.v7.widget.RecyclerView;
	import android.view.View;
	import android.widget.Button;
	import android.widget.EditText;
	import android.widget.LinearLayout;
	
	import java.util.ArrayList;
	import java.util.List;
	
	public class MainActivity extends AppCompatActivity {
    
    

        private List<Msg> msgList = new ArrayList<>();

        private EditText inputText;

        private Button send;

        private RecyclerView msgRecyclerView;

        private MsgAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initMsgs();
        inputText = (EditText) findViewById(R.id.input_text);
        send = (Button) findViewById(R.id.send);
        msgRecyclerView = (RecyclerView)findViewById(R.id.msg_recycler_view);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        msgRecyclerView.setLayoutManager(layoutManager);
        adapter = new MsgAdapter(msgList);
        msgRecyclerView.setAdapter(adapter);
        send.setOnClickListener(new View.OnClickListener(){
    
    
            @Override
            public void onClick(View v) {
    
    
                String content = inputText.getText().toString();
                if (!" ".equals(content)){
    
    
                    Msg msg = new Msg(content,Msg.TYPE_SENT);
                    msgList.add(msg);
                    adapter.notifyItemInserted(msgList.size() - 1);//当有消息时,刷新ListView中的显示
                    msgRecyclerView.scrollToPosition(msgList.size() - 1);//将ListView定位到最后一行
                    inputText.setText("");
                }
            }
        });
    }
    private void initMsgs(){
    
    
        Msg msg1 = new Msg("Hello guy.",Msg.TYPE_RECEIVED);
        msgList.add(msg1);
        Msg msg2 = new Msg("Hello.Who is that?",Msg.TYPE_SENT);
        msgList.add(msg2);
        Msg msg3 = new Msg("This is Tom.Nice to meet you.",Msg.TYPE_RECEIVED );
        msgList.add(msg3);
    }
	}

In the initMsgs() method, we first initialize a few pieces of data for display in RecyclerView. Then send the button click event to get the content in EditText, if the content is not null, create a new Msg object and add it to the msgList list. Then the notifyItemInserted() method of the adapter is called to notify that the list has new data inserted, so that a new message can be displayed in the RecyclerView. Then call the scrollToPosition() method of RecyclerView to locate the displayed data to the last line to ensure that the last message sent can be seen. Finally, call EditText's setText's setText() method to clear the input content.

Guess you like

Origin blog.csdn.net/i_nclude/article/details/75449110