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"