I’m trying to make a simple chat room in android studio, but for some reason each chat message covers the entire screen.
I’m trying to follow the example here on github https://github.com/android/views-widgets-samples/tree/main/RecyclerView/
I’m sure it’s just something super simple, but I don’t know what the search terms are to find it, and my search so far has been fruitless.
This is my chat room activity:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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/chatWindow"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ChatRoom">
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.Ucg.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.Ucg.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include
android:id="@+id/include"
layout="@layout/content_chat_room" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/message_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/toolbar_container"
android:layout_marginTop="0dp">
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
<EditText
android:id="@+id/editTextMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:hint="Message Text"
app:layout_anchor="@+id/relativeLayout"
app:layout_anchorGravity="bottom|center" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
And this is my text row item:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="72dp"
android:layout_margin="2dp"
android:gravity="center_vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No Data Found"/>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
I don’t know if you guys actually need the source code, but here it is regardless.
// ChatRoom.java
package com.ucg;
import android.app.Activity;
import android.app.ListActivity;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputEditText;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
public class ChatRoom extends Activity {
private final ArrayList<String> messages = new ArrayList<>();
private RecyclerAdapter adapter;
private final Timer msg_timer = new Timer();
private VolleyController cont;
private String user;
private String current_string;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_room);
cont = VolleyController.getInstance(this);
// user = LoginRepository.getInstance(null).getUsername();
user = "test";
// Setup the chat messages
adapter = new RecyclerAdapter(messages);
RecyclerView msgs = findViewById(R.id.message_list);
msgs.setAdapter(adapter);
msgs.setLayoutManager(new LinearLayoutManager(this));
TimerTask msg_refresh_task = new TimerTask() {
@Override
public void run() {
VolleyPromise<JSONObject> prom = new VolleyPromise<JSONObject>() {
@Override
public void onSuccess() {
try {
adapter.addElement("Received a response from " + result.getString("Host"));
}
catch(JSONException ignored) {
}
}
};
cont.httpGetJson("http://headers.jsontest.com", prom);
}
};
msg_timer.schedule(msg_refresh_task, 1, 5000);
EditText messageBox = findViewById(R.id.editTextMessage);
messageBox.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if((event.getAction() == KeyEvent.ACTION_UP) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
// TODO add post to volley controller
adapter.addElement(messageBox.getText().toString());
messageBox.setText("");
return true;
}
return false;
}
});
}
}
// RecyclerAdapter.java
package com.ucg;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private ArrayList<String> localDataSet;
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView textView;
public ViewHolder(View view) {
super(view);
textView = view.findViewById(R.id.textView);
}
public TextView getTextView() {
return textView;
}
}
public RecyclerAdapter(ArrayList<String> dataSet) {
localDataSet = dataSet;
}
public void addElement(String s) {
localDataSet.add(s);
notifyDataSetChanged();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.text_row_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.getTextView().setText(localDataSet.get(position));
}
@Override
public int getItemCount() {
return localDataSet.size();
}
}
// VolleyController.java
package com.ucg;
import android.content.Context;
import com.android.volley.Cache;
import com.android.volley.Network;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.BasicNetwork;
import com.android.volley.toolbox.DiskBasedCache;
import com.android.volley.toolbox.HurlStack;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;
import org.json.JSONArray;
import org.json.JSONObject;
public class VolleyController {
private static VolleyController instance = null;
private final RequestQueue queue;
private VolleyController(Context context) {
Cache cache = new DiskBasedCache(context.getCacheDir(), 1024 * 1024);
Network network = new BasicNetwork(new HurlStack());
queue = new RequestQueue(cache, network);
queue.start();
}
public static VolleyController getInstance(Context context) {
if(VolleyController.instance == null) {
VolleyController.instance = new VolleyController(context);
}
return VolleyController.instance;
}
public VolleyPromise<String> httpGet(String url, VolleyPromise<String> prom) {
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, prom, prom);
queue.add(stringRequest);
return prom;
}
public VolleyPromise<JSONObject> httpGetJson(String url, VolleyPromise<JSONObject> prom) {
JsonObjectRequest stringRequest = new JsonObjectRequest(url, null, prom, prom);
queue.add(stringRequest);
return prom;
}
public VolleyPromise<JSONArray> httpGetJsonArr(String url, VolleyPromise<JSONArray> prom) {
JsonArrayRequest stringRequest = new JsonArrayRequest(url, prom, prom);
queue.add(stringRequest);
return prom;
}
}
// VolleyPromise.java
package com.ucg;
import com.android.volley.Response;
import com.android.volley.VolleyError;
public class VolleyPromise <T> implements Response.Listener<T>, Response.ErrorListener {
private boolean success = false;
private boolean error = false;
protected T result = null;
protected VolleyError err_result = null;
public VolleyPromise() {}
public boolean isDone() { return success || error; }
public boolean isSuccess() { return success; }
public boolean isError() { return error; }
public T getResult() { return result; }
public VolleyError getError() { return err_result; }
@Override
public void onResponse(T resp) {
success = true;
result = resp;
onSuccess();
}
@Override
public void onErrorResponse(VolleyError err) {
error = true;
err_result = err;
}
public void onSuccess() {
// TODO Implement your custom callback here
}
}
There are a couple of other views that work in tandem with this one for logging into the system, but I’m pretty sure this should be easy enough to get working.
Advertisement
Answer
In your text row item in the ConstraintLayout just change the this
android:layout_height="match_parent"
by
android:layout_height="wrap_content"