简体   繁体   中英

notifyDataSetChanged() not working with custom Adapter View

I have seen this question answered a few times, however none of the fixes have worked for me, so i'm reaching out.

I have built an app that features the Diolor Swipeable Cards Library ( here ) and now am trying to implement Course Card Filters.

Essentially when a user clicks a course filter we want to change the data that is being fed to the adapter.

Currently I am trying to update the data and calling notifyDataSetChanged() on the adapter, expecting the cards to refresh to show the new data set, however am finding that it is not refreshing at all.

Any help with this would be hugely appreciated.

All code below is from my Main Activity.

I declare the data set that i will be feeding to the adapter at the top of the activity:

ArrayList<CourseCardModel> courseCardModelList;

then in my onCreate() method I instantiate the adapter, attach it to the view, and call a generateCourseCards() method which populates the courseCardModelList with objects pulled from a firebase database.

// Set up and assign card adapter
    ca = new CustomCardAdapter(CardsActivity.this,     android.R.layout.simple_list_item_1, generateCourseCards());
    flingContainer.init(CardsActivity.this, ca);

generateCourseCards() method

private ArrayList<CourseCardModel> generateCourseCards() {

    Toast.makeText(getApplicationContext(), "Retrieving Courses", Toast.LENGTH_LONG).show();

    courseCardModelList = new ArrayList<CourseCardModel>();

    dbref =  FirebaseDatabase.getInstance().getReference().child("courses");



    // Retrieve the course data from Firebase db and cast as Course object
    dbref.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
            Log.e("Count " ,"" + snapshot.getChildrenCount());
            for (DataSnapshot postSnapshot: snapshot.getChildren()) {

                c = postSnapshot.getValue(Course.class);

                System.out.println(c.getCourseName());

                CourseCardModel model = new CourseCardModel();
                 model.setCourse(c);

                courseCardModelList.add(model);

            }

            Collections.shuffle(courseCardModelList);
            ca.notifyDataSetChanged();


        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e("The read failed: ", databaseError.getMessage());
        }

    });

    return courseCardModelList;

}

Attempt to update the dataset (a simple shuffle for the time being) and refresh the cards

// Shuffle the collection and refresh the cards
            Collections.shuffle(courseCardModelList);
            ca.notifyDataSetChanged();

EDIT: added adapter code

public class CustomCardAdapter extends ArrayAdapter {

private TextView courseName, uniName, entryStandards, courseDuration, studyMode, qualification,
        studentSatisfaction, gradProspects, t1, t2, t3, t4, t5, t6;

ArrayList<CourseCardModel> items;



View v;


LayoutInflater vi;

public CustomCardAdapter(Activity context, int resource, ArrayList<CourseCardModel> courses) {
    super(context, resource, courses);

    vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}


@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {

    v = convertView;
    if (v == null) {

        v = vi.inflate(R.layout.course_card_inner_template, parent , false);
    }

    CourseCardModel c = (CourseCardModel) getItem(position);

    if (c != null) {

        courseName = (TextView) v.findViewById(R.id.courseCardCourseName);
        uniName = (TextView) v.findViewById(R.id.courseCardUniName);
        entryStandards = (TextView) v.findViewById(R.id.courseCardEntryStandards);
        courseDuration = (TextView) v.findViewById(R.id.courseCardCourseDuration);
        studyMode = (TextView) v.findViewById(R.id.courseCardStudyMode);
        qualification = (TextView) v.findViewById(R.id.courseCardQualification);
        studentSatisfaction = (TextView) v.findViewById(R.id.courseCardStudentSatisfaction);
        gradProspects = (TextView) v.findViewById(R.id.courseCardGraduateProspects);


        t1 = (TextView) v.findViewById(R.id.cardTV1);
        t2 = (TextView) v.findViewById(R.id.cardTV2);
        t3 = (TextView) v.findViewById(R.id.cardTV3);
        t4 = (TextView) v.findViewById(R.id.cardTV4);
        t5 = (TextView) v.findViewById(R.id.cardTV5);
        t6 = (TextView) v.findViewById(R.id.cardTV6);

        v.setBackgroundResource(R.drawable.newcard);

        courseName.setText(c.getCourse().getCourseName());
        uniName.setText(c.getCourse().getUniversity());
        entryStandards.setText(c.getCourse().getEntryStandards());
        courseDuration.setText(c.getCourse().getCourseDuration());
        studyMode.setText(c.getCourse().getStudyMode());
        qualification.setText(c.getCourse().getQualification());
        studentSatisfaction.setText(c.getCourse().getStudentSatisfaction().toString() + " / 5");
        gradProspects.setText(c.getCourse().getGradProspects() + " / 100");



    }

    if(position ==0)
    {
        //float alpha = (float) 0.8;
        //v.setAlpha(alpha);
        courseName.setVisibility(View.VISIBLE);
    }

    else if (position == 1){

        // Prepare the View for the animation
        v.setVisibility(View.VISIBLE);

        float alpha = (float) 0.8;
        float alpha2 = (float) 0.3;
        courseName.setAlpha(alpha2);
        uniName.setAlpha(alpha2);
        entryStandards.setAlpha(alpha2);
        courseDuration.setAlpha(alpha2);
        studyMode.setAlpha(alpha2);
        qualification.setAlpha(alpha2);
        studentSatisfaction.setAlpha(alpha2);
        gradProspects.setAlpha(alpha2);
        t1.setAlpha(alpha2);
        t2.setAlpha(alpha2);
        t3.setAlpha(alpha2);
        t4.setAlpha(alpha2);
        t5.setAlpha(alpha2);
        t6.setAlpha(alpha2);
        v.setAlpha(alpha);


    }
    else {
        v.setVisibility(View.INVISIBLE);
    }

    return v ;
}


public void updateData(ArrayList<CourseCardModel> courseCardModels) {

    this.items = courseCardModels;
    notifyDataSetChanged();

}

}

Without adapter class provided my first guess would be that you messed the references up. Maybe you are shuffling the data that is not referenced from the adapter. Once you share your adapter's code, I'll update my answer.

== EDIT ==

Avoid referencing some external collection of data from adapter, and updating that referenced data. Updating adapter/list data should be done using adapter's interface and methods such as add() , addAll() or remove() It might happen that (parent) adapter makes clone/copy of your data and in that case updating external/referenced collection is not doing any good.

Problem is in this method.

public void updateData(ArrayList<CourseCardModel> courseCardModels) {
    this.items = courseCardModels;
    notifyDataSetChanged();
}

here you are giving another array reference to your adapter.

Just rewrite as below.

public void updateData(ArrayList<CourseCardModel> courseCardModels) {
    this.items.clear();
    this.items.addAll(courseCardModels);
    notifyDataSetChanged();
}

You're extending an ArrayAdapter which holds his own array of models (the array passed to the constructor). If you would like to update the items, do something like this:

ca.clear(); 
for (CourseCardModel object : courseCardModelList) {
   ca.insert(object, ca.getCount());
}

ca.notifyDataSetChanged();

Or you can override the getItem method and return an item from your items array.

And another option would be extending BaseAdapter instead of the ArrayAdapter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM