2016-03-26 3 views
0

У меня возникла проблема с моим recyclerview, у которого есть пользовательский адаптер. Проблема заключается в том, что при открытии активности recyclerview пуст. Когда пользователь вводит что-либо в текстовое поле SearchView, recyclerview заполняется и остается без проблем. Я попытался изменить место некоторого кода, чтобы исправить эту проблему, но не успел. Я добавил текущие и желаемые снимки состояния под кодами. Заранее спасибо.RecyclerView не заполнен до взаимодействия SearchView

AddCourseActivity:

public class AddCourseActivity extends AppCompatActivity{ 

private RecyclerView mRecyclerView; 
private AddCourseAdapter mAdapter; 
private List<AddCourseAdapter.AddCourseModel> mModels; 
SearchView mSearchView; 

@Override 
protected void onCreate(Bundle savedInstance) { 
    super.onCreate(savedInstance); 
    setContentView(R.layout.activity_add_course); 
    Kii.initialize(AppConstants.APP_ID, AppConstants.APP_KEY, 
      AppConstants.APP_SITE); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 
    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
    getSupportActionBar().setDisplayShowHomeEnabled(true); 
    mRecyclerView = (RecyclerView) findViewById(R.id.addcourseRecyclerView); 
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 
    String[] courses = new String[]{ 
      "Math119", 
      "Enve101", 
      "Chem107", 
      "Chem229", 
      "Phys105", 
      "Math120"}; 
    mModels = new ArrayList<>(); 
    mAdapter = new AddCourseAdapter(this, mModels); 
    mSearchView = (SearchView) findViewById(R.id.searchView); 
    mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 
     @Override 
     public boolean onQueryTextSubmit(String query) { 
      return false; 
     } 
     @Override 
     public boolean onQueryTextChange(String newText) { 
      final List<AddCourseAdapter.AddCourseModel> filteredModelList = filter(mModels, newText); 
      mAdapter.animateTo(filteredModelList); 
      mRecyclerView.scrollToPosition(0); 
      return true; 
     } 
    }); 
    for (String course: courses) { 
     mModels.add(new AddCourseAdapter.AddCourseModel(course)); 
     mRecyclerView.setAdapter(mAdapter); 
     mAdapter.notifyDataSetChanged(); 
    } 
} 

private List<AddCourseAdapter.AddCourseModel> filter(List<AddCourseAdapter.AddCourseModel> models, String query) { 
    query = query.toLowerCase(); 
    final List<AddCourseAdapter.AddCourseModel> filteredModelList = new ArrayList<>(); 
    for (AddCourseAdapter.AddCourseModel model: models) { 
     final String text = model.getText().toLowerCase(); 
     if (text.contains(query)) { 
      filteredModelList.add(model); 
     } 
    } 
    return filteredModelList; 
} 
} 

AddCourseAdapter:

public class AddCourseAdapter extends RecyclerView.Adapter<AddCourseAdapter.AddCourseViewHolder> { 
private final LayoutInflater mInflater; 
private final List<AddCourseModel> mModels; 
KiiUser user; 
KiiObject object; 
KiiBucket userBucket; 
Context context; 

public AddCourseAdapter(Context context, List<AddCourseModel> models) { 
    mInflater = LayoutInflater.from(context); 
    mModels = new ArrayList<>(models); 
} 

@Override 
public AddCourseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    context = parent.getContext(); 
    final View itemView = mInflater.inflate(R.layout.list_item_add_course, parent, false); 
    user = KiiUser.getCurrentUser(); 
    final String username = user.getUsername(); 
    userBucket = Kii.user().bucket(username); 
    String id = "mycourses"; 
    object = userBucket.object(id); 
    return new AddCourseViewHolder(itemView); 
} 

@Override 
public void onBindViewHolder(final AddCourseViewHolder holder, int position) { 
    final AddCourseModel model = mModels.get(position); 
    holder.bind(model); 
    holder.addButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      final String value = holder.mTextView.getText().toString(); 
      object.refresh(new KiiObjectCallBack() { 
       @Override 
       public void onRefreshCompleted(int token, @NonNull KiiObject object, Exception exception) { 
        object.set(value, true); 
        object.saveAllFields(new KiiObjectCallBack() { 
         @Override 
         public void onSaveCompleted(int token, KiiObject object, Exception exception) { 
          Toast.makeText(context, 
            "Added: " + value, 
            Toast.LENGTH_SHORT) 
            .show(); 
         } 
        }, false); 
       } 
      }); 
      holder.addButton.setVisibility(View.GONE); 
      holder.removeButton.setVisibility(View.VISIBLE); 
     } 
    }); 
    holder.removeButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(final View v) { 
      final String value = holder.mTextView.getText().toString(); 
      object.refresh(new KiiObjectCallBack() { 
       @Override 
       public void onRefreshCompleted(int token, @NonNull KiiObject object, Exception exception) { 
        object.set(value, false); 
        object.saveAllFields(new KiiObjectCallBack() { 
         @Override 
         public void onSaveCompleted(int token, @NonNull KiiObject object, Exception exception) { 
          Toast.makeText(context, 
            "Removed: " + value, 
            Toast.LENGTH_SHORT) 
            .show(); 
         } 
        }, false); 
       } 
      }); 

      holder.addButton.setVisibility(View.VISIBLE); 
      holder.removeButton.setVisibility(View.GONE); 
     } 
    }); 
} 

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

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

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

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

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

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

public void addItem(int position, AddCourseModel model) { 
    mModels.add(position, model); 
    notifyItemInserted(position); 
} 

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

public class AddCourseViewHolder extends RecyclerView.ViewHolder { 
    private final TextView mTextView; 
    private final ImageButton addButton; 
    private final ImageButton removeButton; 

    public AddCourseViewHolder(View itemView) { 
     super(itemView); 
     mTextView = (TextView) itemView.findViewById(R.id.addCourseTV); 
     addButton = (ImageButton) itemView.findViewById(R.id.addButton); 
     removeButton = (ImageButton) itemView.findViewById(R.id.removeButton); 
    } 

    public void bind(AddCourseModel model) { 
     mTextView.setText(model.getText()); 
    } 
} 

public static class AddCourseModel { 
    private final String mText; 

    public AddCourseModel(String text) { 
     this.mText = text; 
    } 

    public String getText() { 
     return mText; 
    } 
} 
} 

Текущий Исходное состояние:

Желаемая Исходное состояние:

ответ

1

Дело в конструкторе адаптера

public AddCourseAdapter(Context context, List<AddCourseModel> models) { 
    mInflater = LayoutInflater.from(context); 
    mModels = new ArrayList<>(models); 
} 

Вы создаете новый ArrayList, который первоначально заселен из списка моделей (который пуст в этот момент). Позже вы заполняете начальные модели arraylist, а не тот, который создан в адаптере.

Вы можете:

а) переместить

for (String course: courses) { 
     mModels.add(new AddCourseAdapter.AddCourseModel(course)); 
     mRecyclerView.setAdapter(mAdapter); 
     mAdapter.notifyDataSetChanged(); 
    } 

между этими линиями

mModels = new ArrayList<>(); 
mAdapter = new AddCourseAdapter(this, mModels); 

решений в поиске, как этот

mModels = new ArrayList<>(); 

for (String course: courses) { 
    mModels.add(new AddCourseAdapter.AddCourseModel(course)); 
} 
mAdapter = new AddCourseAdapter(this, mModels); 
mRecyclerView.setAdapter(mAdapter); 

ИЛИ

б) переписать конструктор адаптера для

public AddCourseAdapter(Context context, List<AddCourseModel> models) { 
     mInflater = LayoutInflater.from(context); 
     mModels = models; 
    } 
+0

О, вы ответили только тогда, когда я вышел из дома. Я дам вам знать позже сегодня, спасибо –

+0

Оба решения делают эту работу. Ценить это. Как примечание, какое, по вашему мнению, лучшее решение, стабилизация и производительность? Я чувствую, что решение b лучше, потому что причины больше работают. Это даже имеет значение? –

+0

Не имеет значения. Просто нужно быть осторожным в решении B, если вы сохраните ссылку на список mModels и планируете внести изменения в него вне адаптера. Если вы это сделаете, вы ВСЕГДА должны сообщить адаптеру об изменениях (поскольку это тот же экземпляр списка). – aelimill

Смежные вопросы