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);