webentwicklung-frage-antwort-db.com.de

Legen Sie notifyDataSetChanged () für den Recyclerview-Adapter fest

Ich implementiere ein endloses Laden von Daten für eine RecyclerView. Wenn die Software feststellt, dass das letzte Element angezeigt wird, werden neue Elemente heruntergeladen und die Funktion loadMoreData() aufgerufen. Es werden jedoch keine neuen Datensätze angezeigt. 

Wenn ich notifyDataSetChanged() anrief, passiert nichts. 

Ich habe nur eine Lösung, in der die Ansicht aktualisiert wird, indem Sie den Adapter erneut einstellen. Das Problem ist jedoch, dass der Recycler wieder in die erste Position zurückkehrt und der Recycler dann wieder von der ersten bis zur letzten Position hochgefahren wird. 

RecyclerViewActivity.Java

    RecyclerView rv;

    DatabaseHelpr databaseHelpr;

    RVAdapter adapter;

    LocationFinder locationfinder;

    Location currentLocation;

    ArrayList<ServiceModel> childList, list;

    private int MainService_ID, city_id;

    String url2;

    ActionBar actionBar;

    JSONArray items = null;

    Utility utility;

    Double lat, longi;

    LinearLayoutManager llm;

    int counter=0;

    ProgressBar progressBar;

    private static final String TAG_ITEMS = "items";

    private static final String TAG_LOCALITY = "Locality";

    private static final String TAG_BUSINESS_ID = "Business_Id";

    private static final String TAG_LONGITUDE = "Longitude";

    private static final String TAG_BUSINESS_NAME = "Business_Name";

    private static final String TAG_LATITUDE = "Latitude";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.recyclerview_activity);

        list = new ArrayList<>();
        utility = new Utility(this);
        llm = new LinearLayoutManager(this);

        Bundle bundle=getIntent().getExtras();
        MainService_ID=bundle.getInt("service_id");
        String mainService_Name = bundle.getString("service_name");
        city_id = bundle.getInt("city_id");
        lat= bundle.getDouble("lat");
        longi=bundle.getDouble("longi");

        rv=(RecyclerView)findViewById(R.id.rv);
        rv.setLayoutManager(llm);

        actionBar = getSupportActionBar();
        assert actionBar != null;
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setTitle(mainService_Name);

           //Here city_id = 8, lat = 18.552954, longi = 73.897200, counter=0, MainService_ID = 5
           String url="https://servicedata2-dot-indiacomapi.appspot.com/_ah/api/servicedata/v1/ServiceData?city_id=";
           url2 =url+city_id+"&lat="+lat+"&lng="+longi+"&roll="+counter+"&service_id="+MainService_ID;

           AsyncHttpClient client = new AsyncHttpClient();

           progressBar=(ProgressBar) findViewById(R.id.progressBar1);
           progressBar.setVisibility(View.VISIBLE);

           client.get(url2, new AsyncHttpResponseHandler() {

               @Override
               public void onSuccess(int statusCode, Header[] headers, byte[] response) {
                   // called when response HTTP status is "200 OK"
                   String s = new String(response);

                   try {
                       JSONObject jsonObj = new JSONObject(s);

                       // Getting JSON Array node
                       items = jsonObj.getJSONArray(TAG_ITEMS);

                       // looping through All Contacts
                       for (int i = 0; i < items.length(); i++) {

                           JSONObject c = items.getJSONObject(i);
                           String locality = c.getString(TAG_LOCALITY);
                           String business_Id = c.getString(TAG_BUSINESS_ID);
                           String longitude = c.getString(TAG_LONGITUDE);
                           String latitude = c.getString(TAG_LATITUDE);
                           String business_Name = c.getString(TAG_BUSINESS_NAME);
                           locationfinder = new LocationFinder(RecyclerViewActivity.this);
                           // check if GPS enabled
                           if (locationfinder.canGetLocation()) {
                               double lat = locationfinder.getLatitude();
                               double longi = locationfinder.getLongitude();
                               currentLocation = new Location("");
                               currentLocation.setLatitude(lat);
                               currentLocation.setLongitude(longi);
                           } else {
                               locationfinder.showSettingsAlert();
                           }
                           Location savedLocation = new Location("databaseLocation");
                           savedLocation.setLatitude(Double.parseDouble(latitude));
                           savedLocation.setLongitude(Double.parseDouble(longitude));
                           Double difference = currentLocation.distanceTo(savedLocation) * (0.001);
                           difference = Double.parseDouble(new DecimalFormat("##.##").format(difference));
                           String newDifference = String.valueOf(difference) + " km";
                           ServiceModel serviceModel = new ServiceModel(business_Id, business_Name, newDifference, locality);

                           list.add(serviceModel);
                       }
                   } catch (JSONException e) {
                       e.printStackTrace();
                   }

                   progressBar.setVisibility(View.GONE);
                   adapter = new RVAdapter(RecyclerViewActivity.this, list);
                   rv.setAdapter(adapter);
                   rv.addOnScrollListener(new EndlessRecyclerOnScrollListener(llm) {

                       @Override
                       public void onLoadMore(int current_page) {
                           //  counter= counter+1;
                           loadMoreData();
                       }
                   });
               }

               @Override
               public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
                   // called when response HTTP status is "4XX" (eg. 401, 403, 404)
                   //Toast.makeText(getApplicationContext(),""+statusCode,Toast.LENGTH_LONG).show();
               }

           });

    }

    private void loadMoreData() {

        counter= counter+1;

        //Here city_id = 8, lat = 18.552954, longi = 73.897200, counter=1, MainService_ID = 5
        String url="https://servicedata2-dot-indiacomapi.appspot.com/_ah/api/servicedata/v1/ServiceData?city_id=";
        url2 =url+city_id+"&lat="+lat+"&lng="+longi+"&roll="+counter+"&service_id="+MainService_ID;

        AsyncHttpClient client = new AsyncHttpClient();

        progressBar=(ProgressBar) findViewById(R.id.progressBar1);
        progressBar.setVisibility(View.VISIBLE);

        client.get(url2, new AsyncHttpResponseHandler() {

            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] response) {
                // called when response HTTP status is "200 OK"
                String s = new String(response);

                try {
                    JSONObject jsonObj = new JSONObject(s);

                    // Getting JSON Array node
                    items = jsonObj.getJSONArray(TAG_ITEMS);
                    // looping through All Contacts
                    for (int i = 0; i < items.length(); i++) {
                        JSONObject c = items.getJSONObject(i);
                        String locality = c.getString(TAG_LOCALITY);
                        String business_Id = c.getString(TAG_BUSINESS_ID);
                        String longitude = c.getString(TAG_LONGITUDE);
                        String latitude = c.getString(TAG_LATITUDE);
                        String business_Name = c.getString(TAG_BUSINESS_NAME);
                        locationfinder = new LocationFinder(RecyclerViewActivity.this);
                        // check if GPS enabled
                        if (locationfinder.canGetLocation()) {
                            double lat = locationfinder.getLatitude();
                            double longi = locationfinder.getLongitude();
                            currentLocation = new Location("");
                            currentLocation.setLatitude(lat);
                            currentLocation.setLongitude(longi);
                        } else {
                            locationfinder.showSettingsAlert();
                        }
                        Location savedLocation = new Location("databaseLocation");
                        savedLocation.setLatitude(Double.parseDouble(latitude));
                        savedLocation.setLongitude(Double.parseDouble(longitude));
                        Double difference = currentLocation.distanceTo(savedLocation) * (0.001);
                        difference = Double.parseDouble(new DecimalFormat("##.##").format(difference));
                        String newDifference = String.valueOf(difference) + " km";
                        ServiceModel serviceModel = new ServiceModel(business_Id, business_Name, newDifference, locality);

                        list.add(serviceModel);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                progressBar.setVisibility(View.GONE);
                //adapter = new RVAdapter(RecyclerViewActivity.this, list);
                //rv.setAdapter(adapter);
                adapter.notifyDataSetChanged();
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
            }
        });

        Toast.makeText(this, "Net is present", Toast.LENGTH_SHORT).show();
    }
}  

RVAdapter.Java

public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder>{
    private final LayoutInflater mInflater;
    List<ServiceModel> persons ;
    private Context mContext;


    public RVAdapter(Context context,List<ServiceModel> persons){

       this.mInflater = LayoutInflater.from(context);
        this.persons = new ArrayList<>(persons);
       this.mContext = context;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
        PersonViewHolder pvh = new PersonViewHolder(v);
        return pvh;
    }

    @Override
    public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
        ServiceModel person = persons.get(i);

        personViewHolder.businessName.setOnClickListener(clickListener);
        personViewHolder.image_url.setOnClickListener(clickListenerImage);

        personViewHolder.businessName.setTag(personViewHolder);
        personViewHolder.difference.setTag(personViewHolder);
        personViewHolder.business_id.setTag(personViewHolder);
        personViewHolder.image_url.setTag(personViewHolder);
        personViewHolder.locality.setTag(personViewHolder);

        personViewHolder.businessName.setText(Html.fromHtml(person.getBusinessname()));
        String firstLetter = String.valueOf(person.getBusinessname().charAt(0));
        ColorGenerators generator = ColorGenerators.MATERIAL; // or use DEFAULT
        int color = generator.getColor(person.getBusinessname());
        TextDrawable drawable = TextDrawable.builder().buildRound(firstLetter, color); // radius in px
        personViewHolder.image_url.setImageDrawable(drawable);
        personViewHolder.difference.setText(Html.fromHtml(person.getNewDiffer()));
        personViewHolder.locality.setText(Html.fromHtml(person.getLocality()));
        personViewHolder.bind(person);
    }

    View.OnClickListener clickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            PersonViewHolder holder = (PersonViewHolder) view.getTag();
            int position = holder.getPosition();
            ServiceModel person = persons.get(position);
            String businessids = person.getBusinessid();
            Intent intent = new Intent(mContext, BusinessInfoActivity.class);
            intent.putExtra("businessids", businessids);
            mContext.startActivity(intent);
        }
    };

    View.OnClickListener clickListenerImage = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            PersonViewHolder holder = (PersonViewHolder) view.getTag();
            int position = holder.getPosition();

            ServiceModel person = persons.get(position);
            String businessids = person.getBusinessid();
            Intent intent = new Intent(mContext, BusinessInfoActivity.class);
            intent.putExtra("businessids", businessids);
            mContext.startActivity(intent);
        }
    };

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

    public void animateTo(List<ServiceModel> models) {
        applyAndAnimateRemovals(models);
        applyAndAnimateAdditions(models);
        applyAndAnimateMovedItems(models);
    }

    private void applyAndAnimateRemovals(List<ServiceModel> newModels) {
        for (int i = persons.size() - 1; i >= 0; i--) {
            final ServiceModel model = persons.get(i);
            if (!newModels.contains(model)) {
                removeItem(i);
            }
        }
    }

    private void applyAndAnimateAdditions(List<ServiceModel> newModels) {
        for (int i = 0, count = newModels.size(); i < count; i++) {
            final ServiceModel model = newModels.get(i);
            if (!persons.contains(model)) {
                addItem(i, model);
            }
        }
    }

    private void applyAndAnimateMovedItems(List<ServiceModel> newModels) {
        for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) {
            final ServiceModel model = newModels.get(toPosition);
            final int fromPosition = persons.indexOf(model);
            if (fromPosition >= 0 && fromPosition != toPosition) {
                moveItem(fromPosition, toPosition);
            }
        }
    }

    public ServiceModel removeItem(int position) {
        final ServiceModel model = persons.remove(position);
        notifyItemRemoved(position);
        return model;
    }

    public void addItem(int position, ServiceModel model) {
        persons.add(position, model);
        notifyItemInserted(position);
    }

    public void moveItem(int fromPosition, int toPosition) {
        final ServiceModel model = persons.remove(fromPosition);
        persons.add(toPosition, model);
        notifyItemMoved(fromPosition, toPosition);
    }

    public static class PersonViewHolder extends RecyclerView.ViewHolder {

        protected CardView cv;

        protected TextView businessName, difference, business_id, locality;

        protected ImageView image_url;

        public PersonViewHolder(View itemView) {
            super(itemView);
            cv = (CardView)itemView.findViewById(R.id.cv);
            businessName = (TextView)itemView.findViewById(R.id.business_name);
            difference = (TextView)itemView.findViewById(R.id.txtDifferenece);
            business_id = (TextView)itemView.findViewById(R.id.business_id);
            image_url = (ImageView)itemView.findViewById(R.id.thumbnail);
            locality= (TextView)itemView.findViewById(R.id.txtLocality);
        }

        public void bind(ServiceModel model) {
            businessName.setText(model.getBusinessname());
        }
    }
}  

Bitte helfen Sie mir, wie Sie notifyDataSetChanged() auf den Adapter einstellen. Es funktioniert nicht in meinem Code. Ich habe bereits alle Antworten geprüft, die im Stackoverflow veröffentlicht wurden. 

7
A.R.

wenn Sie die neue Liste auf den RecyclerView-Adapter setzen, legen Sie die Liste im Adapter fest:

machen Sie eine Methode setItems(list) im Adapter und rufen Sie sie auf, bevor Sie notifyDataSetChanged() und im Adapter tun 

this.persons = new ArrayList<>(persons);

in setItems

fügen Sie diese Methode im Adapter hinzu:

public void setItems(List<ServiceModel> persons) {
    this.persons = persons;
}

und nennen Sie es vor notifyDataSetChanged() so:

adapter.setItems(list);
adapter.notifyDataSetChanged();
17
Cold Fire

Ausgabe ist in diesen Zeilen .. 

     adapter = new RVAdapter(RecyclerViewActivity.this, list);
        rv.setAdapter(adapter);
        adapter.notifyDataSetChanged();

Sie initialisieren Ihren Adapter jedes Mal. Es ist nicht nötig, es erneut zu initialisieren . Aktualisieren Sie einfach Ihre arraylist, und rufen Sie adapter.notifyDataSetChanged(); auf, wird es funktionieren.

0
Beena

Wie @Beena erwähnt, erstellen und setzen Sie in Ihrer Erfolgsantwort immer neue Adapter.

Ein Ansatz wäre, einen Adapter zu erstellen und ihn nur zum ersten Mal auf die Recycler-Ansicht zu setzen, und dann onSuceess () Ihres api-Callbacks eine Methode Ihres Adapters aufzurufen.

Fügen Sie in dieser Adaptermethode diese neuen Daten einfach in Ihre Hauptarraylist ein, und notifyItemInserted () anstelle von notifyDataSetChanged. Auf diese Weise wird auch die Standardanimationsanimation von recyclerView angezeigt.

0
Ritesh

Ich habe dies mit einer zusätzlichen Methode in RVAdapter gelöst, die notifyDataSetChanged () aufruft.

Einfach im RVAdapter:

public void refreshList(){
    notifyDataSetChanged();
}

und rufen Sie diese Methode bei Bedarf in MainActivity auf:

rVAdapter.refreshList ();

0

wenn Sie alle Ihre Liste aufrufen, rufen Sie die Methode unten auf.

if (adapter != null) // it works second time and later
   adapter.notifyDataSetChanged();
else { // it works first time
  adapter = new AdapterClass(context,list);
  listView.setAdapter(adapter);

}

0
Kadir altınok