gpt4 book ai didi

android - RecyclerView 和 ItemTouchHelper 滑动以删除问题

转载 作者:太空狗 更新时间:2023-10-29 15:35:54 28 4
gpt4 key购买 nike

我正在尝试通过 RecyclerView 和 ItemTouchHelper 实现“滑动以删除”功能。我有一个奇怪的问题,我一辈子都找不到问题所在。我从顶部滑动一个项目(不是第一个),它消失了,到目前为止一切顺利。当我滚动离开并返回时,在扫过的项目上方的行中有一个 Artifact 。看起来该行未绘制(或者 x 是否已翻译?)。视频显示了问题。

视频步骤:

  1. 我扫掉第 2 项
  2. 向下滚动到底部
  3. 回来
  4. 项目 1 不再可见
  5. 我再次向下滚动到底部
  6. 我向上滚动
  7. 现在一切都很好
  8. 同样,但是从顶部开始有第三个(不是第二个)项目,同样的问题
  9. 同样,对于第一项,没问题

enter image description here

相关代码:(整个github示例应用here)

public class MainActivity extends AppCompatActivity {

RecyclerView mRecyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(new TestAdapter());
setUpItemTouchHelper();

}

private void setUpItemTouchHelper() {
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
int swipedPosition = viewHolder.getAdapterPosition();
TestAdapter adapter = (TestAdapter)mRecyclerView.getAdapter();
adapter.remove(swipedPosition);
}

};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(mRecyclerView);
}

static class TestAdapter extends RecyclerView.Adapter {

List<String> items;

public TestAdapter() {
items = new ArrayList<>();
// this should give us a couple of screens worth
for (int i=1; i<= 15; i++) {
items.add("Item " + i);
}
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new TestViewHolder(parent);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
TestViewHolder viewHolder = (TestViewHolder)holder;
String item = items.get(position);
viewHolder.titleTextView.setText(item);
}

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

public void remove(int position) {
if (position < 0 || position >= items.size()) {
return;
}
items.remove(position);
notifyItemRemoved(position);
}
}

static class TestViewHolder extends RecyclerView.ViewHolder {

TextView titleTextView;

public TestViewHolder(ViewGroup parent) {
super(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_view, parent, false));
titleTextView = (TextView) itemView.findViewById(R.id.title_text_view);
}

}

}

编辑:

我有一个技巧可以消除这个故障,但我仍然想知道原因以及如何才能真正解决这个问题。黑客正在调用 notifyDataSetChanged() 但在动画完成后(否则动画将终止)。基本上我添加了一个 ItemDecorator 并确定动画结束了。

mRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {

boolean running;

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (parent.getItemAnimator().isRunning()) {
running = true;
}
if (running == true && !parent.getItemAnimator().isRunning()) {
// first time it's not running
running = false;
parent.getAdapter().notifyDataSetChanged();
}
super.onDraw(c, parent, state);
}
});

最佳答案

尝试在您的删除方法中添加 notifyDataSetChanged()

public void remove(int position) {
if (position < 0 || position >= items.size()) {
return;
}
items.remove(position);
notifyItemRemoved(position);
notifyDataSetChanged();
}

notifyItemRemoved(position) 通知 RecyclerView Adapter 适配器中的数据已在特定位置被删除。

notifyDataSetChanged() 通知附加的观察者底层数据已更改,任何反射(reflect)数据集的 View 都应自行刷新。

更新

尝试在 notifyItemRemoved(position); 之前添加 mRecyclerView.removeViewAt(position); 这不会弄乱动画。

public class MainActivity extends AppCompatActivity {

RecyclerView mRecyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(new TestAdapter());
setUpItemTouchHelper();

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_item_add_5_items) {
((TestAdapter)mRecyclerView.getAdapter()).addItems(5);
}
return super.onOptionsItemSelected(item);
}

private void setUpItemTouchHelper() {
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
int swipedPosition = viewHolder.getAdapterPosition();
TestAdapter adapter = (TestAdapter)mRecyclerView.getAdapter();
adapter.remove(swipedPosition);
}

};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(mRecyclerView);
}

class TestAdapter extends RecyclerView.Adapter {

List<String> items;
int lastInsertedIndex;

public TestAdapter() {
items = new ArrayList<>();
lastInsertedIndex = 15;
// this should give us a couple of screens worth
for (int i=1; i<= lastInsertedIndex; i++) {
items.add("Item " + i);
}
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new TestViewHolder(parent);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
TestViewHolder viewHolder = (TestViewHolder)holder;
String item = items.get(position);
viewHolder.titleTextView.setText(item);
}

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

public void addItems(int howMany){
if (howMany > 0) {
for (int i = lastInsertedIndex + 1; i <= lastInsertedIndex + howMany; i++) {
items.add("Item " + i);
notifyItemInserted(items.size() - 1);
}
lastInsertedIndex = lastInsertedIndex + howMany;
}
}

public void remove(int position) {
if (position < 0 || position >= items.size()) {
return;
}
items.remove(position);
mRecyclerView.removeViewAt(position);
notifyItemRemoved(position);
}
}

static class TestViewHolder extends RecyclerView.ViewHolder {

TextView titleTextView;

public TestViewHolder(ViewGroup parent) {
super(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_view, parent, false));
titleTextView = (TextView) itemView.findViewById(R.id.title_text_view);
}

}

}

关于android - RecyclerView 和 ItemTouchHelper 滑动以删除问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34735297/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com