我知道有很多关于nullpointexeception的问题,但如果我能找到错误的地方,我不会在这里问这个问题。所以当我到达列表底部并尝试使用方法加载更多数据时,我收到此错误。我正在使用recyclerview这样做。所以第一次加载所有数据,但是当我尝试加载更多时,我会在标题中提到错误。这是代码:
public class ProfileUserFragment extends Fragment implements OnBackPressedListener {
private ResideMenu resideMenu;
private SmoothRecyclerView mRecyclerView;
private PostListAdapter mAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View parentView = inflater.inflate(R.layout.fragment_profile, container, false);
setUpViews(parentView);
initList(parentView);
return parentView;
}
private void initList(View view) {
bindData();
mRecyclerView = (SmoothRecyclerView) view.findViewById(R.id.list);
mRecyclerView.setHasFixedSize(true);
LinearLayoutManager manager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(manager);
mRecyclerView.addItemDecoration(new HorizontalDividerItemDecoration(getActivity()));
mAdapter = new PostListAdapter(getActivity());
mRecyclerView.setAdapter(mAdapter);
// Load more data when user reach bottom
mAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
// add null , so the adapter will check view_type and show progress bar at bottom
mPosts.add(null);
mAdapter.notifyItemInserted(mPosts.size() - 1);
// Load data
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
// Remove loading item
mPosts.remove(mPosts.size() - 1);
mAdapter.notifyItemRemoved(mPosts.size());
// Load data
int start = mPosts.size();
int end = start + 20;
for (int i = start + 1; i <= end; i++) {
Post post = new Post();
post.setTitle("Title ");
post.setDesc("Desc ");
post.setTimestamp("Time ");
mPosts.add(post);
}
mAdapter.setLoaded();
mAdapter.notifyDataSetChanged();
}
}, 2000);
}
});
}
private void setUpViews(View view) {
HomeActivity parentActivity = (HomeActivity) getActivity();
resideMenu = parentActivity.getResideMenu();
ImageButton imageButton = (ImageButton) view.findViewById(R.id.drawer_menu);
imageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
resideMenu.openMenu(ResideMenu.DIRECTION_LEFT);
}
});
}
private void bindData() {
mPosts.clear();
for (int i = 1; i <= 20; i++) {
Post post = new Post();
post.setTitle("Title " + i);
post.setDesc("Desc " + i);
post.setTimestamp("Time " + i);
mPosts.add(post);
}
}
@Override
public void onBackPressed() {
resideMenu.openMenu(ResideMenu.DIRECTION_LEFT);
}
private List<Post> mPosts = new ArrayList<>();
public class PostListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private OnLoadMoreListener mOnLoadMoreListener;
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
private boolean isLoading;
private int visibleThreshold = 2;
private int lastVisibleItem, totalItemCount;
public PostListAdapter(Context context) {
this.mContext = context;
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if (!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
// End has been reached
// Do something
if (mOnLoadMoreListener != null) {
mOnLoadMoreListener.onLoadMore();
}
isLoading = true;
}
}
});
}
public void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {
this.mOnLoadMoreListener = mOnLoadMoreListener;
}
@Override
public int getItemViewType(int position) {
return mPosts == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder vh = null;
if (viewType == VIEW_TYPE_ITEM) {
View view = LayoutInflater.from(mContext).inflate(
R.layout.post_list_item,
parent,
false);
vh = new PostHolder(view);
} else if (viewType == VIEW_TYPE_LOADING){
View view = LayoutInflater.from(mContext).inflate(
R.layout.progress_bar,
parent,
false);
vh = new LoadingHolder(view);
}
return vh;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof PostHolder) {
PostHolder postHolder = (PostHolder) holder;
Post post = mPosts.get(position);
postHolder.tvPostTitle.setText(post.getTitle());
postHolder.tvPostDesc.setText(post.getDesc());
postHolder.tvPostTimestamp.setText(post.getTimestamp());
} else if (holder instanceof LoadingHolder) {
LoadingHolder loadingHolder = (LoadingHolder) holder;
loadingHolder.mProgressBar.setIndeterminate(true);
}
}
@Override
public int getItemCount() {
return mPosts == null ? 0 : mPosts.size();
}
public class PostHolder extends RecyclerView.ViewHolder {
MyTextView tvPostTitle;
MySecondTextView tvPostTimestamp, tvPostDesc;
public PostHolder(View view) {
super(view);
tvPostTitle = (MyTextView) view.findViewById(R.id.tv_post_title);
tvPostDesc = (MySecondTextView) view.findViewById(R.id.tv_post_desc);
tvPostTimestamp = (MySecondTextView) view.findViewById(R.id.tv_created_at);
}
}
public class LoadingHolder extends RecyclerView.ViewHolder {
ProgressBar mProgressBar;
public LoadingHolder(View view) {
super(view);
mProgressBar = (ProgressBar) view.findViewById(R.id.progressBar1);
}
}
public void setLoaded() {
isLoading = false;
}
}
}
这是我遇到的错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.solaris.timster.model.Post.getTitle()' on a null object reference
at com.solaris.timster.fragments.ProfileUserFragment$PostListAdapter.onBindViewHolder(ProfileUserFragment.java:191)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5471)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5504)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4741)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4617)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1994)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1390)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1353)
at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1180)
at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1031)
at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:4061)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:920)
at android.view.Choreographer.doCallbacks(Choreographer.java:695)
at android.view.Choreographer.doFrame(Choreographer.java:628)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:906)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
答案 0 :(得分:2)
更新getItemViewType如下
@Override
public int getItemViewType(int position) {
return mPosts.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
}
这样您就可以检查位置上的项目是否为空。之前您正在检查整个列表是否为空,因此在onBindViewHolder中获取了不正确的视图持有者类型。
答案 1 :(得分:1)
您在mPosts.add(null);
中看到了onLoadMore()
的来电?也就是说,当空值插入到项目列表中,然后当您在post.getTitle()
中调用onBindViewHolder()
时,它将导致NullPointerException
。
您可以做的一件事是检查post
中的null
是否为onBincViewHolder()
,如果只是返回。
或者你可以在第一时间不将空值添加到列表中。
P.S :您正在致电mAdapter.notifyItemRemoved(mPosts.size());
,不应该是mAdapter.notifyItemRemoved(mPosts.size()-1);
吗?