IndexOutOfBoundsException:检测到不一致

时间:2017-04-17 23:56:34

标签: android android-recyclerview

我正在使用recyclelerView并将数据加载为arrayList。如果arrayList少于7个项目,则不会崩溃。

否则,我有这个致命的错误:

  

java.lang.IndexOutOfBoundsException:检测到不一致。无效的视图持有者适配器positionViewHolder {3b1755be position = 7 id = -1,oldPos = -1,pLpos:-1 no parent}

有人可以帮忙吗?

DiagnosticAdapter.java

public class DiagnosticAdapter extends RecyclerView.Adapter<DiagnosticAdapter.ViewHolder> implements Filterable {
    public static ArrayList<Diagnostic> diagnostics;
    private ArrayList<Diagnostic> mFilteredDiagnosticArray;


    public DiagnosticAdapter(ArrayList<Diagnostic> diagnostics) {
        this.diagnostics = diagnostics;

    }

    @Override
    public DiagnosticAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_row, viewGroup, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(DiagnosticAdapter.ViewHolder viewHolder, int i) {

        viewHolder.parameter.setText(diagnostics.get(i).getParameter());
        viewHolder.value.setText(diagnostics.get(i).getValue());
    }

    @Override
    public Filter getFilter() {

        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {

                String charString = charSequence.toString();

                if (charString.isEmpty()) {

                    mFilteredDiagnosticArray = diagnostics;
                } else {
                    ArrayList<Diagnostic> filteredList = new ArrayList<>();

                    for (Diagnostic diagnostic : diagnostics) {

                        if (diagnostic.getParameter().toLowerCase().contains(charString) || diagnostic.getValue().toLowerCase().contains(charString)) {

                            filteredList.add(diagnostic);
                        }
                    }

                    mFilteredDiagnosticArray = filteredList;

                }

                FilterResults filterResults = new FilterResults();
                filterResults.values = mFilteredDiagnosticArray;
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                mFilteredDiagnosticArray = (ArrayList<Diagnostic>) filterResults.values;
                notifyDataSetChanged();
            }
        };
    }

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

}

ViewHolder.java

public class ViewHolder extends RecyclerView.ViewHolder{
    private TextView parameter, value;
    public ViewHolder(View view) {
        super(view);
        parameter = (TextView)view.findViewById(R.id.parameter);
        value = (TextView)view.findViewById(R.id.value);
    }
}

Fragment1.java

public class Fragment1 extends Fragment   {
    private PtrClassicFrameLayout mPtrFrame;
    private RecyclerView recyclerView;
    private ArrayList<Diagnostic> data;
    public static DiagnosticAdapter adapter;
    private  OkHttpClient client;
    private  Handler handler;
    public static String constVar;
    private String method;
    public Fragment1() {

    }
    private Boolean mIsRefreshing = false;
    private String ipAddress;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        return inflater.inflate(R.layout.fragment_1, container, false);
    }

    @Override
    public void onViewCreated(final View view, @Nullable final Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        recyclerView = (RecyclerView) view.findViewById(R.id.recycler_viewDiag);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new WrapContentLinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
        Log.i("mIsRefreshing",mIsRefreshing.toString());
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            method = getArguments().getString("method");
            Log.i("METHOD",method);

            loadJSON();

        }else{
        }
    }

    private void loadJSON(){
       // Log.i("Fragment1",ipAddress);
        Retrofit retrofit = new Retrofit.Builder()
                //.baseUrl("http://"+ipAddress+":8000")
               .baseUrl("http://10.206.208.92"+":8000")
                .addConverterFactory(GsonConverterFactory.create())
                .build();


        RequestInterface request = retrofit.create(RequestInterface.class);
        Call<JSONResponse> call ;
        switch (method){
            case "identification":
                call = request.getIdentification();
                break;
            case "memory":
                call = request.getMemory();
                break;
            case "sysInfo":
                call = request.getSysInfo();
                break;
            case "conditionalAccess":
                call = request.getConditionalAccess();
                break;
            case "network":
                call = request.getNetwork();
                break;
            case "software":
                call = request.getSoftware();
                break;
            case "loader":
                call = request.getLoader();
                break;
            default:
                call = request.getJSON();
                break;
        }

        call.enqueue(new Callback<JSONResponse>() {
            @Override
            public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
                JSONResponse jsonResponse = response.body();
                switch (method){
                    case "identification":
                        data = new ArrayList<>(Arrays.asList(jsonResponse.getIdentification()));
                        break;
                    case "memory":
                        data = new ArrayList<>(Arrays.asList(jsonResponse.getMemory()));
                        break;
                    case "sysInfo":
                        data = new ArrayList<>(Arrays.asList(jsonResponse.getSysInfo()));
                        break;
                    case "conditionalAccess":
                        data = new ArrayList<>(Arrays.asList(jsonResponse.getConditionalAccess()));
                        break;
                    case "network":
                        data = new ArrayList<>(Arrays.asList(jsonResponse.getNetwork()));
                        break;
                    case "software":
                        data = new ArrayList<>(Arrays.asList(jsonResponse.getSoftware()));
                        break;
                    case "loader":
                        data = new ArrayList<>(Arrays.asList(jsonResponse.getLoader()));
                        break;
                    default:
                        data = new ArrayList<>(Arrays.asList(jsonResponse.getDiagnostics()));
                        break;

                }
                //data = new ArrayList<>(Arrays.asList(jsonResponse.getDiagnostics()));
                //Toast.makeText(getContext(), data.size(), Toast.LENGTH_LONG).show();
                adapter = new DiagnosticAdapter(data);
                recyclerView.setAdapter(adapter);
                adapter.notifyDataSetChanged();
                mIsRefreshing = true;
                Log.i("mIsRefreshing",mIsRefreshing.toString());


                //  mPtrFrame.refreshComplete();

            }
            @Override
            public void onFailure(Call<JSONResponse> call, Throwable t) {
              //  mPtrFrame.refreshComplete();
                try {
                    adapter.diagnostics.clear();
                    adapter.notifyDataSetChanged();
                } catch (Exception e) {
                    Log.e("ERROR", "showProgressDialog", e);
            }
                Snackbar.make(getView(), "Unable to fetch json: " + t.getMessage(), Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }
}

DemoActivity.java

public class DemoActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        final ViewPager viewPager = (ViewPager) findViewById(R.id.viewpagerDemo);
        // final ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        SmartTabLayout viewPagerTab = (SmartTabLayout)
        findViewById(R.id.viewpagertab);


        TabsAdapter adapter = new TabsAdapter(getSupportFragmentManager());
        adapter.addFrag(new Fragment1(), "memory");
        adapter.addFrag(new Fragment1(), "identification");
        adapter.addFrag(new Fragment1(), "loader");
        viewPager.setAdapter(adapter);
        viewPagerTab.setViewPager(viewPager);
    }
}

TabsAdapter.java

public class TabsAdapter extends FragmentPagerAdapter {
    private final List<android.support.v4.app.Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();
    public TabsAdapter(FragmentManager fm) {
      super(fm);
    }
    public void addFrag(android.support.v4.app.Fragment fragment, String title){
      Bundle bundle = new Bundle();
      bundle.putString("method", title);
      fragment.setArguments(bundle);

      mFragmentList.add(fragment);
      mFragmentTitleList.add(title);
    }
    @Override
    public android.support.v4.app.Fragment getItem(int position) {
      return mFragmentList.get(position);
    }
    @Override
    public int getCount() {
      return mFragmentList.size();
    }
    @Override
    public CharSequence getPageTitle(int position) {
      return mFragmentTitleList.get(position);
    }
}

1 个答案:

答案 0 :(得分:1)

您可以尝试在适配器中使用数据副本吗?

private ArrayList<Diagnostic> diagnostics = new ArrayList<>();
public DiagnosticAdapter(ArrayList<Diagnostic> diagnostics) {
  this.diagnostics.addAll(diagnostics);
}

清除这样的数据:

public void clearData() {
  this.diagnostics.clear();
  notifyDataSetChanged();
}

设置如下新数据:

public void setData(List<Diagnostics> data) {
  clearData();
  this.diagnostics.addAll(data);
  notifyDataSetChanged();
}

如果您想使用动画或具有更好的演奏效果,您可以使用其他通知...功能,而不是使用notifyDataSetChanged()

希望这有效......