support library v23.1.1 で以下のコードを実行すると落ちます。
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 0(offset:20).state:20
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4405)
...
- public class RecyclerViewGoneActivity extends AppCompatActivity {
- private TextAdapter textAdapter;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_recycler_view_gone);
- final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
- recyclerView.setLayoutManager(new LinearLayoutManager(this));
- // 1. 初期状態がGONE
- recyclerView.setVisibility(View.GONE);
- // 2. setHasFixedSize(true);
- recyclerView.setHasFixedSize(true);
- textAdapter = new TextAdapter();
- recyclerView.setAdapter(textAdapter);
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- ArrayList<String> data = new ArrayList<>();
- for (int i = 0; i < 20; i++) {
- data.add("data : " + i);
- }
- // 3. notifyItemRangeInserted(); を呼ぶ
- textAdapter.addAll(data);
- // 4. visibility を VISIBLE にする
- recyclerView.setVisibility(View.VISIBLE);
- }
- }, 1000);
- }
- private static class TextAdapter extends RecyclerView.Adapter<ViewHolder> {
- private final ArrayList<String> data = new ArrayList<>();
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- LayoutInflater inflater = LayoutInflater.from(parent.getContext());
- return new ViewHolder(inflater.inflate(ViewHolder.LAYOUT_ID, parent, false));
- }
- @Override
- public void onBindViewHolder(ViewHolder holder, int position) {
- holder.textView.setText(data.get(position));
- }
- @Override
- public int getItemCount() {
- return data.size();
- }
- public void add(String s) {
- final int positionStart = getItemCount();
- data.add(s);
- notifyItemInserted(positionStart);
- }
- public void addAll(ArrayList<String> d) {
- final int positionStart = getItemCount();
- final int itemCount = d.size();
- data.addAll(d);
- notifyItemRangeInserted(positionStart, itemCount);
- }
- public void clear() {
- final int itemCount = getItemCount();
- data.clear();
- notifyItemRangeRemoved(0, itemCount);
- }
- }
- private static class ViewHolder extends RecyclerView.ViewHolder {
- public static final int LAYOUT_ID = android.R.layout.simple_list_item_1;
- final TextView textView;
- public ViewHolder(View itemView) {
- super(itemView);
- this.textView = (TextView) itemView.findViewById(android.R.id.text1);
- }
- }
- }
落ちなくする方法がいくつかあります。
- 1. setHasFixedSize(true); を呼ばないようにする(ただしその分パフォーマンスに影響する)
- 2. あらかじめデータを入れておいて VISIBLE にする前に消す
- textAdapter = new TextAdapter();
- recyclerView.setAdapter(textAdapter);
- textAdapter.add("dummy"); // これを追加
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- textAdapter.clear(); // これを追加
- ArrayList<String> data = new ArrayList<>();
- for (int i = 0; i < 20; i++) {
- data.add("data : " + i);
- }
- textAdapter.addAll(data);
- recyclerView.setVisibility(View.VISIBLE);
- }
- }, 1000);
0 件のコメント:
コメントを投稿