Closed e-hai closed 7 years ago
RecyclerView slides into the item with the same data
Sorry, I don't understand the question. Can you rephrase it maybe?
@elihart q: "Normal" item data can be changed, "img" item data is the same.
(1) Initialize the state, 'img' item outside the screen.
(2) After refresh data,why 'img' item in the screen.
I want recyclerView to refresh after still showing the first item.
1. activity
public class EpoxyActivity extends AppCompatActivity implements DemoController.AdapterCallbacks {
private RecyclerView recyclerView;
private DemoController controller;
private List<EpoxyData> dataList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_epoxy);
findViewById(R.id.refresh).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
refreshData();
}
});
recyclerView = (RecyclerView) findViewById(R.id.epoxy_rv);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
controller = new DemoController(this);
controller.setData(dataList);
recyclerView.setAdapter(controller.getAdapter());
refreshData();
}
private int j = 0;
private void refreshData() {
recyclerView.scrollToPosition(0);
dataList.clear();
int max = j + 15;
for (int i = j; i < max; i++) {
EpoxyData normalData = new EpoxyData();
normalData.setId(i);
normalData.setTxt("normal item=" + i);
normalData.setColor(Color.GRAY);
dataList.add(normalData);
j++;
}
EpoxyData imgData = new EpoxyData();
imgData.setTxt("img");
imgData.setId(1000);
imgData.setColor(Color.RED);
dataList.add(9, imgData);
controller.setData(dataList);
}
@Override
public void onAddCarouselClicked() {
}
}
2. EpoxyController
public class DemoController extends TypedEpoxyController<List<EpoxyData>> {
public interface AdapterCallbacks {
void onAddCarouselClicked();
}
private final AdapterCallbacks callbacks;
public DemoController(AdapterCallbacks callbacks) {
this.callbacks = callbacks;
}
@Override
protected void buildModels(List<EpoxyData> carousels) {
for (int i = 0; i < carousels.size(); i++) {
EpoxyData item = carousels.get(i);
add(new TextModel_()
.color(item.getColor())
.txt(item.getTxt())
.id(carousels.get(i).getId()
)
);
}
}
@Override
protected void onExceptionSwallowed(RuntimeException exception) {
// Best practice is to throw in debug so you are aware of any issues that Epoxy notices.
// Otherwise Epoxy does its best to swallow these exceptions and continue gracefully
throw exception;
}
}
3. data
public class EpoxyData {
private int id;
private String txt;
private int color;
public String getTxt() {
return txt;
}
public void setTxt(String txt) {
this.txt = txt;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof EpoxyData)) return false;
EpoxyData epoxyData = (EpoxyData) o;
if (getId() != epoxyData.getId()) return false;
if (getColor() != epoxyData.getColor()) return false;
return getTxt() != null ? getTxt().equals(epoxyData.getTxt()) : epoxyData.getTxt() == null;
}
@Override
public int hashCode() {
int result = getId();
result = 31 * result + (getTxt() != null ? getTxt().hashCode() : 0);
result = 31 * result + getColor();
return result;
}
}
4.model
@EpoxyModelClass(layout = R.layout.model_text_layout)
public abstract class TextModel extends EpoxyModel<TextContentView> {
@EpoxyAttribute
String txt;
@EpoxyAttribute
@ColorInt
int color;
@EpoxyAttribute
boolean isSelect;
@EpoxyAttribute(DoNotHash)
View.OnClickListener clickListener;
@Override
public void bind(TextContentView view) {
view.setTitle(txt);
view.setTxtBgColor(color);
}
}
5.View
public class TextContentView extends RelativeLayout {
private TextView title;
public TextContentView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
inflate(getContext(), R.layout.view_txt_content, this);
title = (TextView) findViewById(R.id.model_txt_tv);
}
public void setTitle(String txt) {
title.setText(txt);
}
public void setTxtBgColor(int color) {
title.setBackgroundColor(color);
}
}
Thanks for explaining. I think this is because of how RecyclerView processes its item change animations. I would guess that it does the removals and then insertions, and since the red item is the top item after the removals it is kept in view after the insertions.
I would think you need to configure recyclerview/layoutmanager to anchor or animate views, but I'm not sure the way to do that.
The easiest solution I can think of is to use 'scrollToPosition' after the changes to move where you want. Since models are built async you'd have to make sure to call after models are rebuilt.
Another option might be to use a custom item animator to change the animation duration or other details of the removal/insertion animation.
Maybe look into disabling setPreserveFocusAfterLayout
on the recycler view
Thanks for the answer.Because i do not need animation,so add code:
recyclerView.setItemAnimator(null);
Solved my question! :+1:
glad you got it figured out! Thanks for reporting back
I had same issue on 2.16.3
recyclerView.setItemAnimator(null);
Above codes not working on me.
But I resolve issue with this code:
epoxy_recycler_view.post { epoxy_recycler_view.scrollToPosition(position) }
mDatas.clear(); mDatas.addAll(photoList); mController.setData(mDatas);