Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用SwiperFresh布局获取重复的CardView_Java_Android_Xml_Android Recyclerview_Swiperefreshlayout - Fatal编程技术网

Java 使用SwiperFresh布局获取重复的CardView

Java 使用SwiperFresh布局获取重复的CardView,java,android,xml,android-recyclerview,swiperefreshlayout,Java,Android,Xml,Android Recyclerview,Swiperefreshlayout,这就是我的问题,我得到了一个API,它提供了许多来源的最新消息。它们中的每一个都带有一个cardwiew。这里的问题是,当我使用swipeRefresh时,它会在相同的新闻中复制cardwiews,就像如果我有10条新闻,它会在相同的新闻中复制到20条。 这是我应用swipeRefresh的代码: package com.example.newsapp4; import androidx.appcompat.app.AppCompatActivity; import androidx.rec

这就是我的问题,我得到了一个API,它提供了许多来源的最新消息。它们中的每一个都带有一个
cardwiew
。这里的问题是,当我使用
swipeRefresh
时,它会在相同的新闻中复制
cardwiews
,就像如果我有10条新闻,它会在相同的新闻中复制到20条。 这是我应用
swipeRefresh
的代码:


package com.example.newsapp4;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import com.example.newsapp4.Model.Articles;
import com.example.newsapp4.Model.Headlines;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class bbcnews extends AppCompatActivity {
    Adapter adapter;
    Intent intencion;
    RecyclerView recyclerView;
    public static String source = "My Source";
    public static String API_KEY = "My API Key";
    SwipeRefreshLayout srl;

    List<Articles> articles = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bbcnews);

        srl = findViewById(R.id.swipeRefresh);
        srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                retrieveJson(source, API_KEY);
            }
        });


        recyclerView = findViewById(R.id.recyclerView1);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));


        adapter = new Adapter(bbcnews.this,articles);
        recyclerView.setAdapter(adapter);
        retrieveJson(source, API_KEY);

    }

    public void retrieveJson(String source, String apiKey){

        srl.setRefreshing(true);
        Call<Headlines> call = ApiClient.getInstance().getApi().getHeadlines(source, apiKey);
        call.enqueue(new Callback<Headlines>() {
            @Override
            public void onResponse(Call<Headlines> call, Response<Headlines> response) {
                if(response.isSuccessful() && response.body().getArticles() != null){
                    srl.setRefreshing(false);
                    articles.clear();
                    articles = response.body().getArticles();
                    adapter.setArticles(articles);
                }
            }


            @Override
            public void onFailure(Call<Headlines> call, Throwable t) {
                srl.setRefreshing(false);
                Toast.makeText(bbcnews.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    public String getCountry(){
        Locale locale = Locale.getDefault();
        String country = locale.getCountry();
        return country.toLowerCase();

    }

    public void aPerfil(View vista){
        intencion = new Intent(this, profile_activity.class);
        startActivity(intencion);
    }
}

这里是
recyclerView
中带有
swipeRefresh
的一个:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        app:cardElevation="4dp"
        android:id="@+id/cardView"
        app:cardCornerRadius="10dp">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="200dp">

            <ProgressBar
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:id="@+id/loader"/>


            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/image"
                android:scaleType="centerCrop"
                android:src="@drawable/img"/>

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/gradient" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="TITLE"
                android:textSize="20dp"
                android:padding="10dp"
                android:fontFamily="@font/g_bold"
                android:textColor="@color/white"
                android:id="@+id/tvTitle"/>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Source"
                    android:textSize="16dp"
                    android:padding="10dp"
                    android:ems="15"
                    android:fontFamily="@font/g_light"
                    android:textColor="@color/white"
                    android:id="@+id/tvSource"/>
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:fontFamily="@font/g_light"
                    android:gravity="right"
                    android:text="Date"
                    android:textColor="@color/white"
                    android:padding="10dp"
                    android:textSize="16dp"
                    android:id="@+id/tvDate"/>




            </LinearLayout>
        </FrameLayout>

    </androidx.cardview.widget.CardView>



</LinearLayout>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/white"
    tools:context=".bbcnews">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="DINGO BBC NEWS"
        android:textColor="@color/black"
        android:textSize="20sp"
        android:fontFamily="@font/g_bold"
        android:background="@color/white"
        android:padding="10dp"
        android:textAlignment="center"/>



    <GridLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:columnCount="2"
        android:paddingLeft="20dp"
        android:paddingRight="5dp"
        android:background="@drawable/black_background"
        android:rowCount="2">

        <EditText
            android:id="@+id/editTextTextPersonName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="Search"
            android:textColor="@color/grey"
            android:textColorHint="@color/grey"
            android:padding="5dp"
            android:layout_column="0"
            android:background="@drawable/black_background"
            android:layout_row="0"
            android:layout_columnWeight="1"
            android:inputType="textPersonName" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingRight="20dp"
            android:background="@drawable/black_background"
            android:drawableRight="@drawable/ic_baseline_search_24"
            android:layout_column="1"
            android:layout_row="0"/>

    </GridLayout>


    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/swipeRefresh">

        <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="5dp"
            android:id="@+id/recyclerView1"/>

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>


</LinearLayout>

谢谢你的时间

据我所知,你的代码是关于刷刷新后API调用成功的,这是这里的部分

articles.clear();
articles=response.body().getArticles();
adapter.setArticles(条款);
您在这里清除活动中的文章,但事情在适配器中已经有另一个文章列表,您没有清除它们

然后当您创建
适配器.setArticles(articles)时
call,在下面的函数中,您的文章被添加到已经存在的文章列表中,从而添加到重复列表中

public-void-setArticles(列出文章){
this.articles.addAll(articles);
int count=getItemCount();
notifyItemRangeInserted(计数,计数+articles.size());
}
要解决此问题,可以对函数进行以下修改

public void setArticles(列表项目,布尔clearAll){
if(clearAll){this.articles.clear();}
this.articles.addAll(articles);
notifyDataSetChanged();
}
然后修改函数调用,如下所示

adapter.setArticles(articles,true);
这样,当布尔值为true时,它将清除现有列表。另外,我建议您将insert调用替换为data set change调用。否则,您可以一起创建一个单独的函数,用于添加元素和清除现有元素。

//在添加到列表之前清除适配器列表。
   // Clear adapter list before add to list.

  public void setArticles(List<Articles> articles) {
        
                   if(this.articles!=null && this.articles.size()>0)
                      this.articles.clear();
        
                this.articles.addAll(articles);
                int count = getItemCount();
                notifyItemRangeInserted(count, count + articles.size());
            }
公共物品(列出物品){ if(this.articles!=null&&this.articles.size()>0) this.articles.clear(); this.articles.addAll(articles); int count=getItemCount(); notifyItemRangeInserted(计数,计数+articles.size()); }
能否为适配器添加代码以供参考?完成后,我更新了该部分。刷新时您的确切要求是:是否需要用新数据替换所有以前的数据,还是比较现有数据和新数据,只添加不存在的数据?我的确切要求是,刷新数据时,数据将显示为新数据,替换旧的,但在这种情况下,我有重要的新闻,所以即使我刷新它也会出现在那里。我只想显示10条新闻,即使我刷新了,仍然是一样的,但我得到了20条新闻,可能有一些不同,但20条不是我的API所说的10条,因为许多API链接都有大量的新闻要显示,比如10条甚至100条。希望你能理解我。这个简单的代码对我来说真的很有用,非常感谢!不客气@塞尔吉奥坎波斯拉库娃
   // Clear adapter list before add to list.

  public void setArticles(List<Articles> articles) {
        
                   if(this.articles!=null && this.articles.size()>0)
                      this.articles.clear();
        
                this.articles.addAll(articles);
                int count = getItemCount();
                notifyItemRangeInserted(count, count + articles.size());
            }