Android 添加第一个项目时回收视图项目动画崩溃

Android 添加第一个项目时回收视图项目动画崩溃,android,android-recyclerview,Android,Android Recyclerview,我正在开发一个小应用程序,用户可以在其中发布内容和评论文章。我正在使用github上的Instamaterial项目作为参考 当用户发布新评论时,有一个带有动画的评论活动。一切都很好。。。但是当我发布第一条评论时。。。应用程序正在崩溃,没有显示我花了一整天的时间尝试的评论动画(滚动到顶部)。。。但没有找到解决办法 public class CommentsActivity extends AppCompatActivity implements SendCommentButton.OnSend

我正在开发一个小应用程序,用户可以在其中发布内容和评论文章。我正在使用github上的Instamaterial项目作为参考

当用户发布新评论时,有一个带有动画的评论活动。一切都很好。。。但是当我发布第一条评论时。。。应用程序正在崩溃,没有显示我花了一整天的时间尝试的评论动画(滚动到顶部)。。。但没有找到解决办法

public class CommentsActivity extends AppCompatActivity implements SendCommentButton.OnSendClickListener {
    public static final String ARG_DRAWING_START_LOCATION = "arg_drawing_start_location";

    LinearLayout contentRoot;
    RecyclerView rvComments;
    LinearLayout llAddComment;
    EditText etComment;
    SendCommentButton btnSendComment;

    private CommentsAdapter commentsAdapter;
    private int drawingStartLocation;
    Toolbar toolbar;
    private int currentPostID;

    DatabaseHelper db;
    private PreferencesManager preferencesManager;
    ArrayList<PostResponse.PostComments> comments;

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

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        contentRoot = (LinearLayout) findViewById(R.id.contentRoot);
        rvComments = (RecyclerView) findViewById(R.id.rvComments);
        llAddComment = (LinearLayout) findViewById(R.id.llAddComment);
        etComment = (EditText) findViewById(R.id.etComment);
        btnSendComment = (SendCommentButton) findViewById(R.id.btnSendComment);

        preferencesManager = new PreferencesManager(CommentsActivity.this);
        db = new DatabaseHelper(CommentsActivity.this);

        setupToolbar();
        setupComments();
        setupSendCommentButton();

        drawingStartLocation = getIntent().getIntExtra(ARG_DRAWING_START_LOCATION, 0);
        if (savedInstanceState == null) {
            contentRoot.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    contentRoot.getViewTreeObserver().removeOnPreDrawListener(this);
                    startIntroAnimation();
                    return true;
                }
            });
        }
    }

    protected void setupToolbar() {
        if (toolbar != null) {
            setSupportActionBar(toolbar);
            getSupportActionBar().setDisplayShow
HomeEnabled(true);
            toolbar.setNavigationIcon(R.mipmap.ic_menu_cancel);
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onBackPressed();
                }
            });
        }
    }

    private void setupComments() {
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        rvComments.setLayoutManager(linearLayoutManager);
        rvComments.setHasFixedSize(true);
        currentPostID = getIntent().getIntExtra(PostResponse.KEY_ID, -1);
        comments = db.getCommentsByPostID(currentPostID);

        commentsAdapter = new CommentsAdapter(this, comments);
        rvComments.setAdapter(commentsAdapter);
        rvComments.setOverScrollMode(View.OVER_SCROLL_NEVER);
        rvComments.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
                    commentsAdapter.setAnimationsLocked(true);
                }
            }
        });
    }

    private void setupSendCommentButton() {
        btnSendComment.setOnSendClickListener(this);
    }

    private void startIntroAnimation() {
        ViewCompat.setElevation(getToolbar(), 0);
        contentRoot.setScaleY(0.1f);
        contentRoot.setPivotY(drawingStartLocation);
        llAddComment.setTranslationY(200);

        contentRoot.animate()
                .scaleY(1)
                .setDuration(200)
                .setInterpolator(new AccelerateInterpolator())
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        ViewCompat.setElevation(getToolbar(), Utils.dpToPx(8));
                        animateContent();
                    }
                })
                .start();
    }

    private void animateContent() {
        commentsAdapter.updateItems();
        llAddComment.animate().translationY(0)
                .setInterpolator(new DecelerateInterpolator())
                .setDuration(200)
                .start();
    }

    @Override
    public void onBackPressed() {
        ViewCompat.setElevation(getToolbar(), 0);

        contentRoot.postDelayed(new Runnable() {
            @Override
            public void run() {
                contentRoot.animate()
                        .translationY(Utils.getScreenHeight(CommentsActivity.this))
                        .setDuration(200)
                        .setListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationEnd(Animator animation) {
                                CommentsActivity.super.onBackPressed();
                                overridePendingTransition(0, 0);
                            }
                        })
                        .start();
            }
        }, 100);
    }

    @Override
    public void onSendClickListener(View v) {
        if (validateComment()) {
            publishComment(etComment.getText().toString());

            PostResponse.PostComments newComment = new PostResponse().new PostComments();
            newComment.user_id = Integer.parseInt(preferencesManager.getUserID());
            newComment.comment = etComment.getText().toString();
            newComment.post_id = currentPostID;

            commentsAdapter.addItem(newComment);

            commentsAdapter.setAnimationsLocked(false);
            commentsAdapter.setDelayEnterAnimation(true);
            rvComments.smoothScrollBy(0, rvComments.getChildAt(0).getHeight() * commentsAdapter.getItemCount());

            etComment.setText(null);
            btnSendComment.setCurrentState(SendCommentButton.STATE_DONE);
        }
    }


    private boolean validateComment() {
        if (TextUtils.isEmpty(etComment.getText())) {
            btnSendComment.startAnimation(AnimationUtils.loadAnimation(this, R.anim.shake_error));
            return false;
        }

        return true;
    }

    private Toolbar getToolbar(){
        return toolbar;
    }



    /************************************************
     * VOLLEY CALLS TO PUBLISH A COMMENT
     * *****************************************************/
    private void publishComment(final String comment) {
       //Code here

    }

}

我知道你知道这是因为这句话-(你在评论中告诉我)

但是你知道这是方法调用吗<代码>rvComments.getChildAt(0.getHeight()

我的想法是,如果recyleView是空的,那么调用
rvComments.getChildAt(0)
是对Null引用的引用,它是空的 因此,您可以
NPE
,但如果已经添加了第一条注释,则列表大小为1,因此此行
rvComments.getChildAt(0).getHeight()
实际上引用了一个视图对象地址

因此,我想你的解决方案是_,因为你知道它的首选高度查看或选择一个首选高度,然后硬编码并使用它。或者,如果您确实坚持使用视图高度,请在前进之前检查列表大小

...
  commentsAdapter.setAnimationsLocked(false);
  commentsAdapter.setDelayEnterAnimation(true);
  if(rvComments.getChildCount() > 0){
  //i guess you will have do rvComments.getChildAt(
  //rvComments.getChildCount()-1) rather than below
  rvComments.smoothScrollBy(0, rvComments.getChildAt(0).getHeight()
            * commentsAdapter.getItemCount());
  }else{
  //do something else or find something to do to get the height you want
  //and multiply. In short it means the first item.
...

显示代码,而且您的问题是,在您的onlick侦听器中,某些内容具有空引用。已更新问题以包含代码。为方便起见,先生,请将我指向第214行。您可以看到rvComments.smoothScrollBy(0,rvComments.getChildAt(0.getHeight()*commentsAdapter.getItemCount());这是添加第一条注释时创建空指针的行。我通常会检查……添加第一条注释后,rvComments.getChildAt(0)的值为144。我试着硬编码来查看。应用程序没有崩溃,但我看不到立即添加到回收视图的第一条评论。@VishalKumar,您是否能够避免@Elltz提到的崩溃?您现在的问题是它没有显示在recyclerview中,对吗?正是。。。但是在这通电话之前。。。我称之为->PostResponse.PostComments newComment=new PostResponse().new PostComments();newComment.user_id=Integer.parseInt(preferencesManager.getUserID());newComment.comment=etComment.getText().toString();newComment.post_id=currentposted;评论附加条款(新成员);它应该向recycleview添加一个项目(即第一条注释),我正在通知适配器中的更改。还是!!!您是否调用了
notifyDataSetChanged
或刷新列表的内容@VishalKumarYes!!!adapter的addItem()在行前执行此操作…这是导致问题的原因。目前正在处理其他社交功能,如/不喜欢、报告垃圾邮件…全部完成。。。仍然没有找到任何解决方案…尝试@VishalKumar是这一行
notifyItemInserted(mItems.size()-1)另外,当我发布我的答案时,它已经在那里了吗?还是你编辑的?
java.lang.NullPointerException
at com.test.abc.CommentsActivity.onSendClickListener(CommentsActivity.java:214)
at com.test.abc.views.SendCommentButton.onClick(SendCommentButton.java:80)
at android.view.View.performClick(View.java:4463)
at android.view.View$PerformClick.run(View.java:18770)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
rvComments.smoothScrollBy(0, rvComments.getChildAt(0).getHeight() *
          commentsAdapter.getItemCount());
...
  commentsAdapter.setAnimationsLocked(false);
  commentsAdapter.setDelayEnterAnimation(true);
  if(rvComments.getChildCount() > 0){
  //i guess you will have do rvComments.getChildAt(
  //rvComments.getChildCount()-1) rather than below
  rvComments.smoothScrollBy(0, rvComments.getChildAt(0).getHeight()
            * commentsAdapter.getItemCount());
  }else{
  //do something else or find something to do to get the height you want
  //and multiply. In short it means the first item.
...