在Recyclerview适配器

时间:2016-02-02 07:29:52

标签: android android-recyclerview recycler-adapter notifydatasetchanged endlessscroll

我正在为RecyclerView实现无休止的数据加载。当软件检测到将显示最后一个项目时,它会下载新项目并调用loadMoreData()函数,但不会显示新数据集。

当我打电话给notifyDataSetChanged()时,没有任何事情可以发生。

我只有一个刷新视图的解决方案是再次设置适配器,但问题是recyclerview返回到第一个位置然后再次从另一个位置向上滚动Recyclerview。

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

请帮助我,如何将notifyDataSetChanged()设置为适配器。它在我的代码中不起作用。我已经检查了stackoverflow上发布的所有答案。

5 个答案:

答案 0 :(得分:18)

您要将新列表设置为RecyclerView适配器,请在适配器中设置列表:

在适配器中创建方法setItems(list)并在notifyDataSetChanged()之前和适配器中调用

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

中的

在适配器中添加此方法:

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

并在notifyDataSetChanged()之前调用它:

adapter.setItems(list);
adapter.notifyDataSetChanged();

答案 1 :(得分:0)

问题出在这些方面......

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

您每次都在初始化适配器。无需重新初始化它。 只需更新您的arraylist,然后调用adapter.notifyDataSetChanged();即可使其正常运行。

答案 2 :(得分:0)

与@Beena提到的一样,您在成功响应中随时创建和设置新适配器。

一种方法是创建一个适配器并仅在第一次将其设置为recycleler视图,然后再调用api回调的onSuceess(),调用适配器的方法。

在他们的适配器方法中,只需在主arraylist中添加新数据并执行notifyItemInserted()而不是notifyDataSetChanged,这样您还将看到recyclerView的默认添加动画。

答案 3 :(得分:0)

  

当你每个人填写下面的方法列表时。

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

}

答案 4 :(得分:0)

我通过在RVAdapter中添加了调用notifyDataSetChanged()的方法来解决了这个问题。

仅在RVAdapter中:

public void refreshList(){
    notifyDataSetChanged();
}

并在需要时在MainActivity中调用此方法:

rVAdapter.refreshList();