retrait RecyclerView éléments

J'ai un RecyclerView qui est de l'ajout d'éléments de chaque période. Lors de l'ajout d'objets, si les éléments de la liste sont plus de (disons) 500, puis les premiers éléments seront supprimés et les nouveaux éléments seront ajoutés.

Si le RecyclerView impossible de faire défiler plus !recyclerView.canScrollVertically(1); puis, après l'ajout de nouveaux éléments de la RecyclerView sera smoothScroolToPosition() à la dernière position.

Où est le problème?
Ok, si ReyclerView, qui est au milieu (pas de bas, pas en haut) lors de la suppression d'éléments anciens, il va soudainement sauter certains postes. Je veux le RecyclerView de ne pas sauter de la position et de rester là où il était lors de la suppression d'éléments en haut

J'ai essayé d'utiliser layoutManager.setStackFromEnd(true); mais pas de chance

Des suggestions?

Un peu de code (sans code est supprimé). Mon problème peut être reproduit lors de la RecyclerView montre les éléments de la liste à partir du milieu et de la presse VOLUME_UP:

public class ActivityMain extends ActionBarActivity {
public static final int MAX_LOG_ITEMS = 500;
private RecyclerView mRecyclerView;
private AdapterLog mRecyclerAdapter;
private boolean mAutoScroll = true;
private DataReceiver mDataReceiver;
private Handler mLogHandler = new Handler() {
@Override public void handleMessage(Message msg) {
switch (msg.what){
case DataReceiver.CAT_LOGS:
List<Log> catLogs = (List<Log>) msg.obj;
updateLogs(catLogs);
break;
case DataReceiver .CLEAR_LOGS:
if (mRecyclerAdapter.getItemCount() > MAX_LOG_ITEMS)
mRecyclerAdapter.removeFirstItems(mRecyclerAdapter.getItemCount() - MAX_LOG_ITEMS);
break;
case Logcat.REMOVE_LOGS:
mRecyclerAdapter.clear();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true);
mRecyclerAdapter = new AdapterLog();
mRecyclerView = (RecyclerView) findViewById(R.id.activity_main_recyclerview);
mRecyclerView.setHasFixedSize(true);        
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mRecyclerAdapter);
mRecyclerView.setOnScrollListener(new UIUtils.ScrollManager(toolbarContainer != null ?
toolbarContainer : toolbar){
@Override public void onScrolled(RecyclerView r, int dx, int dy) {
super.onScrolled(r, dx, dy);
mAutoScroll = !r.canScrollVertically(1);
}
});
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch(keyCode){
case KeyEvent.KEYCODE_VOLUME_UP:
//               mAutoScroll = false;
//               mRecyclerView.scrollToPosition(0);
//               if (mRecyclerAdapter.getItemCount() > MAX_LOG_ITEMS)
mRecyclerAdapter.removeFirstItems(mRecyclerAdapter.getItemCount() - 50);
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
mAutoScroll = true;
mRecyclerView.scrollToPosition(mRecyclerAdapter.getItemCount() -1);
return true;
}
return false;
}
private void updateLogs(final List<Log> logList) {
final boolean scroll = mAutoScroll;
mRecyclerAdapter.addAll(logList);
if (scroll) mRecyclerView.smoothScrollToPosition(mRecyclerAdapter.getItemCount() - 1);
}
}

La RecyclerAdapter:

public class AdapterLog extends RecyclerView.Adapter<AdapterLog.ViewHolder> {
private final List<Log> mLogList;
public AdapterLog() {
this.mLogList = new ArrayList<Log>();
}
@Override
public AdapterLog.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.listitem_log, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTextView.setText(getItem(position).getMessage());
holder.mTextView.setTextColor(getItem(position).getLevel().getColor());
}
@Override
public int getItemCount() {
return mLogList.size();
}
public Log getItem(int position) {
return mLogList.get(position);
}
public void addAll(List<Log> logList) {
mLogList.addAll(logList);
notifyDataSetChanged();
}
public void removeFirstItems(int count) {
for (int i=0; i<count; i++) mLogList.remove(0);
notifyDataSetChanged();
}
public void clear() {
mLogList.clear();
notifyDataSetChanged();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public ViewHolder(View v) {
super(v);
mTextView = (TextView) v.findViewById(R.id.listitem_log_textview);
}
}
}
Êtes-vous en faveur notififyDataSetChanged?
oui, à partir de l'adaptateur lors de l'appel d'ajouter ou de supprimer. - Je mettre à jour le code
Changement notifyDataSetChanged(); sur votre removeFirstItems à notifyItemRangeRemoved(0,count) pour de meilleures performances
votre solution c'est le travail, maintenant, les RecyclerView ne saute pas tout d'un coup... Poster une réponse afin que je puisse l'accepter et d'augmenter votre rep 🙂

OriginalL'auteur BamsBamx | 2015-03-04