2017-02-07 8 views
0

Я видел этот вопрос несколько раз, однако ни один из исправлений не работал для меня, поэтому я обращаюсь к нему.notifyDataSetChanged() не работает с пользовательским видом адаптера

Я создал приложение, в котором представлена ​​библиотека Dillor Swipeable Cards (here), и теперь я пытаюсь внедрить фильтры карт курса.

По существу, когда пользователь нажимает фильтр курса, мы хотим изменить данные, которые подаются на адаптер.

В настоящее время я пытаюсь обновить данные и вызывать notifyDataSetChanged() на адаптере, ожидая обновления карт, чтобы показать новый набор данных, однако я обнаружил, что он не освежает вообще.

Любая помощь с этим была бы чрезвычайно оценена.

Весь код ниже из моей основной деятельности.

Объявляет набор данных, который я буду питающим к адаптеру в верхней части деятельности:

ArrayList<CourseCardModel> courseCardModelList;

тогда в моем onCreate() методы я создаю экземпляр адаптера, прикрепить его к виду, и вызовите метод generateCourseCards(), который заполняет courseCardModelList объектами, вытащенными из базы данных firebase.

// 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() метод

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; 

} 

Попытка обновления набора данных (простой перетасовать для поры до времени) и обновите карточки

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

EDIT: добавленный код адаптера

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

} 

}

+0

Обновите свой вопрос вместе со своим классом адаптера. –

+0

Если вы используете BaseAdapter в своем CustomAdapter, вы будете использовать notifyDataSetInvalidated(); метод –

ответ

0

Без класса адаптера при условии, моя первая догадка будет то, что вы испортили ссылки вверх. Возможно, вы перетасовываете данные, на которые не ссылаются адаптер. Когда вы поделитесь кодом вашего адаптера, я обновлю свой ответ.

== EDIT ==

Избегайте ссылки на некоторые внешние сбор данных от адаптера и обновления, которые ссылаются данные. Обновление данных адаптера/списка должно выполняться с использованием интерфейса адаптера и методов, таких как add(), addAll() или remove() Возможно, что (родительский) адаптер делает клонирование/копию ваших данных, и в этом случае обновление внешней/ссылочной коллекции не приносит пользы.

+0

Добавлен код адаптера - спасибо за ваш ответ! – freshwaterjoe

+0

@freshwaterjoe, как вы реализовали этот код Collections.shuffle (courseCardModelList); ca.notifyDataSetChanged(); не достижимо. Вы перетасовываете и уведомляете адаптер, который оба не используется для обновления кода. Notifiying dataSetChanged по тому же методу, где вы на самом деле инициализируете адаптер. –

+0

Я изменил код, чтобы использовать 'ca.clear()', за которым следует 'ca.addAll (courseCardModelList)' и 'ca.notifyDataSetChange'. Когда я тестировал это, он просто заставляет карты исчезать. Есть предположения? – freshwaterjoe

0

Проблема в этом методе.

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

Здесь вы даете ссылку на другой массив для вашего адаптера.

Просто перепишите, как показано ниже.

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

Привет, Пратик, спасибо за ваш ответ. Я никогда не называл этот метод, но теперь я изменил код на вашу рекомендацию и вызвал внутри своей основной деятельности - передав его «courseCardModelList», который был перетасован, и теперь карты исчезают из активности, но не появляются снова. Есть предположения? – freshwaterjoe

+0

вы можете загрузить полный код вместе с основным видом деятельности? –

+0

Я добавил полный код для основной деятельности. Основной бит для просмотра - это onClickListeners, прикрепленные к кнопкам в методе 'openFilterDialog'. Я не могу понять, как существенно «обновить» карты. Поэтому в 'dialogRandomButton' onClickListener все, что я хочу сделать, это« перетасовать »карты и снова показать их. – freshwaterjoe

0

Вы расширяете ArrayAdapter, который содержит свой собственный массив моделей (массив передается конструктору). Если вы хотите обновить элементы, сделать что-то вроде этого:

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

ca.notifyDataSetChanged(); 

Или вы можете переопределить метод GetItem и возвращает элемент из вашего массива элементов.

И еще один вариант будет расширять BaseAdapter вместо ArrayAdapter.

+0

Привет, спасибо за ваш ответ. Я просто попробовал это, но обнаружил, что он все еще не работает. Когда я запустил этот код, вид карты просто замерзал некоторое время, а затем исчез. – freshwaterjoe