2016-06-24 14 views
0

Ich weiß, dass es viele Fragen über Nullpointexeception gibt, aber wenn ich wo finden könnte ist ein Fehler, ich würde diese Frage hier nicht stellen. So bekomme ich diesen Fehler, wenn ich am Ende der Liste komme und versuche, Methode laden mehr Daten zu verwenden. Ich mache das mit Recyclerview. Beim ersten Mal werden alle Daten geladen, aber wenn ich versuche, mehr zu laden, bekomme ich einen Fehler im Titel. Hier ist der Code:java.lang.NullPointerException: Versuch, virtuelle Methode aufzurufen 'java.lang.String com.solaris.timster.model.Post.getTitle()'

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; 
    } 
} 
} 

Hier wird ein Fehler ich erhalte:

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) 

Antwort

1

Sie sehen, wo Sie mPosts.add(null); in onLoadMore() nennen? Das ist, wenn der Nullwert in der Elementliste eingefügt wird, und wenn Sie dann post.getTitle() in onBindViewHolder() aufrufen, wird es NullPointerException verursachen.

Eine Sache, die Sie tun können, ist zu überprüfen, ob die postnull in onBincViewHolder() ist, wenn es dann einfach zurückkommt.

Oder Sie können einfach nicht den Nullwert der Liste an erster Stelle hinzufügen.

S.S: Sie rufen mAdapter.notifyItemRemoved(mPosts.size());, sollte es nicht mAdapter.notifyItemRemoved(mPosts.size()-1); sein?

1

Update getItemViewType wie folgt

@Override 
public int getItemViewType(int position) { 
    return mPosts.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM; 
} 

Auf diese Weise kann die Überprüfung werden, wenn das Element an Position null ist. Zuvor haben Sie überprüft, ob die gesamte Liste null war und daher inOnBindViewHolder einen falschen Ansichtshalter eingibt.

Verwandte Themen