为什么RecyclerView在工具栏上膨胀?

问题描述

当我为recyclerview充气时,我的应用程序出现了问题。 在回收站视图中,有些卡片被充气,当它出现在屏幕上时,工具栏消失,并且无法使用设置按钮。 如果有人可以帮助我或给我一些可能发生的事情的提示...我将非常感激。

使用最新的SDK和库版本。

代码在下面。

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 ->在这里,我得到了用来在recyclerview上显示itnes的cardview

<?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,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,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();
    }
}

解决方法

因为您将Recyclerview的顶部与父项(ConstraintLayout)的顶部对齐,所以它覆盖了工具栏。

app:layout_constraintTop_toTopOf="parent"替换为app:layout_constraintTop_toBottomOf="@id/toolbar",以将Recyclerview的顶部与工具栏的底部对齐

将这些属性添加到工具栏:

  • app:layout_constraintBottom_toTopOf="@id/conteudoRSS"
  • app:layout_constraintTop_toTopOf="parent"
  • app:layout_constraintStart_toStartOf="parent"
  • app:layout_constraintEnd_toEndOf="parent"
<?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="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/conteudoRSS"
        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"/> <!-- replace app:layout_constraintTop_toTopOf="parent"  -->

</androidx.constraintlayout.widget.ConstraintLayout>

LinearLayout也很好,在这种情况下,它比ConstraintLayout更简单

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

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

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/conteudoRSS"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

</LinearLayout>
,

尝试一下

<?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"
        app:layout_constraintBottom_toTopOf="@id/conteudoRSS"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@+id/toolbar"
        app:layout_constraintStart_toStartOf="parent">
    </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" /><!--TODO:Edit-->
</androidx.constraintlayout.widget.ConstraintLayout>

如果这不起作用,请尝试将android:layout_marginTop="?attr/actionBarSize"添加到RecyclerView

希望这会有所帮助。随时要求澄清...

,

在Vishnu的帮助下解决了问题,Vishnu回答了这个问题。 看来问题是我在主要活动上创建了一个新的recycleview,而不是使用布局xml文件定义的recycleview。 要解决此问题,只需从主要活动中删除两行:

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

并仅维护以下内容的第一个定义:

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