Skip to content
Advertisement

Why is the RecyclerView inflating over the ToolBar?

I’m having an issue with my app when I inflate an recyclerview. Inside the recyclerview, some cards are inflated and when it comes out to the screen, the toolbar disappears and the settings button can’t be used.

Using the latest SDK and libraries versions.

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:minHeight="?attr/actionBarSize"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:ignore="MissingConstraints">
    </androidx.appcompat.widget.Toolbar>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/conteudoRSS"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar" />
</androidx.constraintlayout.widget.ConstraintLayout>

linha.xml -> here I get the cardview which I use to show the items on the recyclerview

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    style="@style/CardView.Light"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp">

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="5dp">

        <TextView
            android:id="@+id/titulo"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:textAppearance="@style/TextAppearance.AppCompat.Title"
            android:textColor="#000000"
            tools:text="Titulo Noticia"
            app:layout_constraintEnd_toStartOf="@+id/imagem"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/dataPublicacao"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"
            android:textColor="#8A000000"
            tools:text="18 Setembro 2020"
            app:layout_constraintEnd_toStartOf="@+id/imagem"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/titulo" />

        <ImageView
            android:id="@+id/imagem"
            android:layout_width="140dp"
            android:layout_height="140dp"
            android:layout_margin="12dp"
            tools:background="@color/colorAccent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/url"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:visibility="invisible"
            tools:ignore="MissingConstraints"
            app:layout_constraintTop_toBottomOf="@+id/dataPublicacao" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

MainActivity.java

package br.ufpe.cin.android.rss;

import androidx.appcompat.app.AppCompatActivity;
package br.ufpe.cin.android.rss;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;

import com.prof.rssparser.Article;
import com.prof.rssparser.Channel;
import com.prof.rssparser.OnTaskCompleted;
import com.prof.rssparser.Parser;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private String urlFeed;
    private Toolbar mTopToolbar;
    RecyclerView conteudoRSS;
    List<Article> noticias;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        conteudoRSS = findViewById(R.id.conteudoRSS);
        mTopToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mTopToolbar);
        SharedPreferences preferences = getSharedPreferences
                ("user_preferences", MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString("feed1", getString(R.string.feed1));
        editor.putString("feed2", getString(R.string.feed2));
        editor.putString("feed3", getString(R.string.feed3));
        editor.apply();

        if(preferences.contains("rssfeed")){
            urlFeed = preferences.getString("rssfeed", getString(R.string.feed_padrao));
        } else {
            editor.putString("rssfeed", getString(R.string.feed_padrao));
            editor.apply();
            urlFeed = preferences.getString("rssfeed", getString(R.string.feed_padrao));
        }
        
        conteudoRSS = new RecyclerView(this);
        conteudoRSS.setLayoutManager(new LinearLayoutManager(this));
        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.action_settings) {
            startActivity(new Intent(
                    this, PreferenciasActivity.class));
            return true;
        } else {
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        Parser p = new Parser.Builder().build();
        p.onFinish(
                new OnTaskCompleted() {
                    @Override
                    public void onTaskCompleted(Channel channel) {
                        noticias = channel.getArticles();
                        runOnUiThread(
                                () -> {
                                    RssAdapter adapter = new RssAdapter(
                                            getApplicationContext(),
                                            noticias
                                    );
                                    conteudoRSS.setAdapter(adapter);
                                    setContentView(conteudoRSS);
                                }
                        );
                    }
                    @Override
                    public void onError(Exception e) {
                        Log.e("RSS_APP",e.getMessage());
                    }
                }
        );
        p.execute(urlFeed);
    }
    protected void onResume() {
        super.onResume();
    }

    private String getRssFeed(String feed) throws IOException {
        InputStream in = null;
        String rssFeed;
        try {
            URL url = new URL(feed);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            in = conn.getInputStream();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            for (int count; (count = in.read(buffer)) != -1; ) {
                out.write(buffer, 0, count);
            }
            byte[] response = out.toByteArray();
            rssFeed = new String(response, StandardCharsets.UTF_8);
        } finally {
            if (in != null) {
                in.close();
            }
        }
        return rssFeed;
    }
}
        conteudoRSS = new RecyclerView(this);
        conteudoRSS.setLayoutManager(new LinearLayoutManager(this));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.action_settings) {
            startActivity(new Intent(
                    this, PreferenciasActivity.class));
            return true;
        } else {
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        Parser p = new Parser.Builder().build();
        p.onFinish(
                new OnTaskCompleted() {
                    @Override
                    public void onTaskCompleted(Channel channel) {
                        noticias = channel.getArticles();
                        runOnUiThread(
                                () -> {
                                    RssAdapter adapter = new RssAdapter(
                                            getApplicationContext(),
                                            noticias
                                    );
                                    conteudoRSS.setAdapter(adapter);
                                    setContentView(conteudoRSS);
                                }
                        );
                    }
                    @Override
                    public void onError(Exception e) {
                        Log.e("RSS_APP",e.getMessage());
                    }
                }
        );
        p.execute(urlFeed);
    }
    protected void onResume() {
        super.onResume();
    }

    private String getRssFeed(String feed) throws IOException {
        InputStream in = null;
        String rssFeed;
        try {
            URL url = new URL(feed);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            in = conn.getInputStream();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            for (int count; (count = in.read(buffer)) != -1; ) {
                out.write(buffer, 0, count);
            }
            byte[] response = out.toByteArray();
            rssFeed = new String(response, StandardCharsets.UTF_8);
        } finally {
            if (in != null) {
                in.close();
            }
        }
        return rssFeed;
    }
}

ItemRssViewHolder.java

package br.ufpe.cin.android.rss;

import android.content.Intent;
import android.net.Uri;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

public class ItemRssViewHolder extends RecyclerView.ViewHolder {
    TextView titulo = null;
    ImageView image = null;
    TextView data = null;
    TextView url = null;

    public ItemRssViewHolder(View itemCard) {
        super(itemCard);
        this.titulo = itemCard.findViewById(R.id.titulo);
        this.image = itemCard.findViewById(R.id.imagem);
        this.data = itemCard.findViewById(R.id.dataPublicacao);
        this.url = itemCard.findViewById(R.id.url);
        itemCard.setOnClickListener(
                v -> {
                    String uri = url.getText().toString();
                    Intent intent = new Intent(Intent.ACTION_VIEW,
                            Uri.parse(uri));
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    itemCard.getContext().startActivity(intent);

                }
        );
    }
}

RssAdapter.java

package br.ufpe.cin.android.rss;

import android.content.Context;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.prof.rssparser.Article;
import com.squareup.picasso.Picasso;

import java.util.List;

import static br.ufpe.cin.android.rss.R.layout.linha;

public class RssAdapter extends RecyclerView.Adapter <ItemRssViewHolder> {

    List<Article> noticias;
    Context context;

    public RssAdapter(Context c, List<Article> noticias) {
        this.noticias = noticias;
        this.context = c;
    }

    public int getCount() {
        return noticias.size();
    }

    public Object getItem(int i) {
        return noticias.get(i);
    }

    @NonNull
    @Override
    public ItemRssViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View v = inflater.inflate(R.layout.linha, parent, false);
        ItemRssViewHolder viewHolder = new ItemRssViewHolder(v);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ItemRssViewHolder viewHolder, int i) {
        Article noticia = noticias.get(i);
        viewHolder.titulo.setText(noticia.getTitle());
        viewHolder.data.setText("Publicado em: " + noticia.getPubDate().substring(0, 22));
        viewHolder.url.setText(noticia.getLink());
        String url = noticias.get(i).getImage();
        Picasso.with(context)
                .load(url)
                .into(viewHolder.image);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

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

Advertisement

Answer

Issue fixed with the help of Vishnu, who’s answered this question. It seems the problem was that I was creating a new recycleview on the main activity instead of using the recycleview defined by the layout xml file. To fix that, it was only necessary to remove two lines from the main activity:

conteudoRSS = new RecyclerView(this);
setContentView(conteudoRSS);

And maintain only the first definition of the recycleview, as follows:

RecyclerView conteudoRSS;
conteudoRSS = findViewById(R.id.conteudoRSS);
Advertisement