RecyclerView.Adapter getItemCount()方法上的NullPointerException。初始化

时间:2018-12-21 16:23:00

标签: android android-fragments arraylist nullpointerexception recycler-adapter

这是RecyclerView.Adapter,它将Tasks(带有日期和标题)添加到“我的MainActivity”中。

public abstract class TaskAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
List<Item> items=new ArrayList<Item>();
TaskFragment taskFragment;
    TaskAdapter(TaskFragment taskFragment){
    this.taskFragment=taskFragment;
    items =new ArrayList<>();
}

//  getPosition() of lis;
    public Item getItem(int position) {
        return items.get(position);
    }
// add item to list
    public void addItem(Item item) {
        items.add(item);
        notifyItemInserted(getItemCount() - 1);
    }
// add item to list's position
    public void addItem(int location, Item item) {
        items.add(location, item);
        notifyItemInserted(location);
    }

    // NullPointerException Method
    @Override
    public int getItemCount() {
        return items.size();
    }
    // remove list's item from position

    public void removeItem(int location){
    if(location>=0 && location<=getItemCount()-1){
        items.remove(location);
        notifyItemRemoved(location);
    }
    }

    protected class TaskViewHolder extends RecyclerView.ViewHolder {
        protected TextView title;
        protected TextView date;
        protected CircleImageView priority;


        public TaskViewHolder(View itemView, TextView title, TextView date, CircleImageView priority) {
            super(itemView);
            this.title = title;
            this.date = date;
            this.priority=priority;
        }
    }

    public TaskFragment getTaskFragment() {
        return taskFragment;
    }

}

!=空检查根本没有帮助。我认为问题在于方法调用的顺序。这是有问题的片段:

public abstract class TaskFragment extends Fragment {
    protected RecyclerView recyclerView;
    protected RecyclerView.LayoutManager layoutManager;

    protected TaskAdapter adapter;


    public void addTask(ModelTask newTask) {
        int position = -1;
//this adapter.getItemCount() throws NullPointerException
        for (int i = 0; i < adapter.getItemCount(); i ++) {
            if (adapter.getItem(i).isTask()) {
                ModelTask task = (ModelTask) adapter.getItem(i);
                if (newTask.getDate() < task.getDate()) {
                    position = i;
                    break;
                }
            }
        }

        if (position != -1) {
            adapter.addItem(position, newTask);
        } else {
            adapter.addItem(newTask);
        }
    }
    public abstract void moveTask(ModelTask task);
}

也许有正确方法排序的方法?我可以避开这个例外吗?还是我的列表初始化错误?请帮我解决这个问题。

顺便说一下,这是来自堆栈跟踪的日志:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.densetsu, PID: 1871
    java.lang.NullPointerException: Attempt to invoke virtual method 'int com.example.densetsu.adapter.TaskAdapter.getItemCount()' on a null object reference
        at com.example.densetsu.fragment.TaskFragment.addTask(TaskFragment.java:20)
        at com.example.densetsu.MainActivity.onTaskAdded(MainActivity.java:151)
        at com.example.densetsu.dialog.AddingTaskDialogFragment$6.onClick(AddingTaskDialogFragment.java:182)
        at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:162)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5536)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1397)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1192)
I/Process: Sending signal. PID: 1871 SIG: 9
Disconnected from the target VM, address: 'localhost:8600', transport: 'socket'

TaskAdapter是抽象的。我有两个类,它们扩展了TaskAdapter。这是CurrentTasksAdapter代码:

public class CurrentTasksAdapter extends TaskAdapter {

    private static final int TYPE_TASK = 0;
    private static final int TYPE_SEPARATOR = 1;

    public CurrentTasksAdapter(CurrentTaskFragment taskFragment) {
        super(taskFragment);
    }





    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

        switch (viewType) {
            case TYPE_TASK:
                View v = LayoutInflater.from(viewGroup.getContext())
                        .inflate(R.layout.model_task, viewGroup, false);
                TextView title = (TextView) v.findViewById(R.id.tvTaskTitle);
                TextView date = (TextView) v.findViewById(R.id.tvTaskDate);
                CircleImageView priority=(CircleImageView) v.findViewById(R.id.cvTaskPriority);

                return new TaskViewHolder(v, title, date,priority);
            default:
                return null;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
        Item item = items.get(position);

        if (item.isTask()) {
            viewHolder.itemView.setEnabled(true);
            final ModelTask task = (ModelTask) item;
            final TaskViewHolder taskViewHolder = (TaskViewHolder) viewHolder;
            final View itemView=taskViewHolder.itemView;
            final Resources resources=itemView.getResources();


            taskViewHolder.title.setText(task.getTitle());
            if (task.getDate() != 0) {
                taskViewHolder.date.setText(Utils.getFullDate(task.getDate()));
            }
            else {
                taskViewHolder.date.setText(null);
            }
            itemView.setVisibility(View.VISIBLE);

// some code for setting color of text + animation of CircleImageView
}

CurrentTaskFragment,它扩展了TaskFragment:

public class CurrentTaskFragment extends TaskFragment {


    OnTaskDoneListener onTaskDoneListener;

    public CurrentTaskFragment() {
        // Required empty public constructor
    }

    public interface OnTaskDoneListener {
        void onTaskDone(ModelTask task);
    }


    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            onTaskDoneListener = (OnTaskDoneListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnTaskDoneListener");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_current_task, container, false);

        recyclerView = (RecyclerView) rootView.findViewById(R.id.rv_current_tasks);

        layoutManager = new LinearLayoutManager(getActivity());

        recyclerView.setLayoutManager(layoutManager);

        adapter = new CurrentTasksAdapter(this);
        recyclerView.setAdapter(adapter);

        // Inflate the layout for this fragment
        return rootView;
    }


    @Override
    public void moveTask(ModelTask task) {
        onTaskDoneListener.onTaskDone(task);
    }
}

在AddingTaskDialogFragment中,我有一个带有2个方法的接口:

public interface AddingTaskListener {
        void onTaskAdded(ModelTask newTask);
        void onTaskAddingCancel();
    }

在MainActivity中,我先创建CurrentTaskFragment,然后重写接口的onTaskAdded方法:

TaskFragment currentTaskFragment;
@Override
    public void onTaskAdded(ModelTask newTask) {
        currentTaskFragment.addTask(newTask);
    }

    @Override
    public void onTaskAddingCancel() {
        Toast.makeText(this, "Task adding cancel", Toast.LENGTH_LONG).show();

    }

即首先,我调用带有nullPointerException的addItem,由于链式反应(该方法获得空引用),因此下一个方法也将其引发nullPointerException

我在MainActivity中分配currentTaskFragment:

public class MainActivity extends AppCompatActivity
        implements AddingTaskDialogFragment.AddingTaskListener,
        CurrentTaskFragment.OnTaskDoneListener, DoneTaskFragment.OnTaskRestoreListener {

    FragmentManager fragmentManager;

    PreferenceHelper preferenceHelper;
    TabAdapter tabAdapter;
//here
    TaskFragment currentTaskFragment;
    TaskFragment doneTaskFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PreferenceHelper.getInstance().init(getApplicationContext());
        preferenceHelper = PreferenceHelper.getInstance();

        fragmentManager = getFragmentManager();

        runSplash();

        setUI();
    }
private void setUI() {
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        tabLayout.addTab(tabLayout.newTab().setText(R.string.current_task));
        tabLayout.addTab(tabLayout.newTab().setText(R.string.done_task));

        final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
        tabAdapter = new TabAdapter(fragmentManager, 2);

        viewPager.setAdapter(tabAdapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }



        });
//here
        currentTaskFragment = (CurrentTaskFragment) tabAdapter.getItem(TabAdapter.CURRENT_TASK_FRAGMENT_POSITION);
        doneTaskFragment = (DoneTaskFragment) tabAdapter.getItem(TabAdapter.DONE_TASK_FRAGMENT_POSITION);


        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DialogFragment addingTaskDialogFragment = new AddingTaskDialogFragment();
                addingTaskDialogFragment.show(fragmentManager, "AddingTaskDialogFragment");
            }
        });
    }
//two those methods
    @Override
    public void onTaskAdded(ModelTask newTask) {
        currentTaskFragment.addTask(newTask);
    }

    @Override
    public void onTaskAddingCancel() {
        Toast.makeText(this, "Task adding cancel", Toast.LENGTH_LONG).show();

    }

    @Override
    public void onTaskDone(ModelTask task) {
        doneTaskFragment.addTask(task);
    }

    @Override
    public void onTaskRestore(ModelTask task) {
        currentTaskFragment.addTask(task);
    }
}

问题已解决! 我的TabAdapter错误:

public class TabAdapter extends FragmentStatePagerAdapter {

    private int numberOfTabs;

    public static final int CURRENT_TASK_FRAGMENT_POSITION = 0;
    public static final int DONE_TASK_FRAGMENT_POSITION = 1;

    private CurrentTaskFragment currentTaskFragment;
    private DoneTaskFragment doneTaskFragment;

    public TabAdapter(FragmentManager fm, int numberOfTabs) {
        super(fm);
        this.numberOfTabs = numberOfTabs;
        currentTaskFragment = new CurrentTaskFragment();
        doneTaskFragment = new DoneTaskFragment();
    }

    @Override
    public Fragment getItem(int i) {

        switch (i) {
            case 0:
                // here i had "return new CurrentTaskFragment". It set currentTaskFragment to null
                return currentTaskFragment;
            case 1:
                //the same with doneTaskFragment
                return doneTaskFragment;
            default:
                return null;
        }
    }

感谢您的帮助!非常感谢<3:D

0 个答案:

没有答案