RecyclerView Items cover entire screen

Tags: , ,



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.

Answer

In your text row item in the ConstraintLayout just change the this

android:layout_height="match_parent"

by

android:layout_height="wrap_content"



Source: stackoverflow