【问题标题】:Android - App crashes if there are not a lot of itemsAndroid - 如果项目不多,应用程序会崩溃
【发布时间】:2020-05-03 00:30:03
【问题描述】:

我正在使用回收器适配器在帖子上显示 cmets。代码设置为在单击编辑文本以及当前用户发布新评论时将回收站视图滚动到底部。

如果显示了键盘并且回收站视图仍然没有接触到键盘(显示了大约 2 到 4 个 cmets),则在发布评论时应用程序会崩溃。如果有很多项目(足以进入键盘下方),recyclerview 会滚动并且没有任何崩溃。

这是我的代码:

button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            // some code
            scrollToBottom = true; // this is initially false
            loadComments();

        }
    });

    private void loadComments () {

        Query query = firebaseFirestore.collection...;

        FirestoreRecyclerOptions<Model> options = new FirestoreRecyclerOptions.Builder<Model>()
                .setLifecycleOwner(this)
                .setQuery(query, Model.class)
                .build();

        adapter = new Adapter(options, this);

        recyclerview.setHasFixedSize(true);
        recyclerview.setLayoutManager(new LinearLayoutManager(this));
        recyclerview.setAdapter(adapter);

        if (scrollToBottom) {
            scrollToBottom = false;
            scrollToTheBottom();
        }

    }

    private void scrollToTheBottom() {

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                recyclerview.smoothScrollToPosition(adapter.getItemCount());
            }
        }, 600);

    }

适配器代码:

public class Adapter extends FirestoreRecyclerAdapter<Model, Adapter.ViewHolder> {

Context context;
TimeAgo timeAgo;

public Adapter(@NonNull FirestoreRecyclerOptions<Model> options, Context context) {
    super(options);
    this.context = context;
}

@Override
protected void onBindViewHolder(@NonNull final ViewHolder holder, int position, @NonNull Model model) {

    final String userID = model.getUser_id();
    String image = model.getImage();
    String username = model.getUsername();
    String comment = model.getComment();
    Timestamp commentTimeAgo = model.getTimestamp();

    String timestampString = String.valueOf(commentTimeAgo);
    String[] noOpeningParentheses = timestampString.split("\\(");
    String[] noClosingParentheses = noOpeningParentheses[1].split("\\)");
    String[] noCommaAndSpace = noClosingParentheses[0].split(", ");
    String[] secondsFromTimestamp = noCommaAndSpace[0].split("seconds=");
    String[] nanosecondsFromTimestamp = noCommaAndSpace[1].split("nanoseconds=");
    long millis = TimeUnit.SECONDS.toMillis(Long.parseLong(secondsFromTimestamp[1])) + TimeUnit.NANOSECONDS.toMillis(Long.parseLong(nanosecondsFromTimestamp[1]));

    // Applying
    if (image.equals("default")) {
        holder.userImage.setImageResource(R.mipmap.no_image);
    } else {
        Glide.with(context).load(image).into(holder.userImage);
    }
    holder.userUsername.setText(username);
    holder.comment.setText(String.valueOf(comment));
    holder.commentTimeAgo.setText(timeAgo.getTimeAgo(context, millis));

}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem, parent, false);
    context = parent.getContext();
    timeAgo = new TimeAgo();
    return new ViewHolder(view);

}

public class ViewHolder extends RecyclerView.ViewHolder {

    CircleImageView userImage;
    TextView userUsername, comment, commentTimeAgo;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);

        userImage = itemView.findViewById(R.id.userimage);
        userUsername = itemView.findViewById(R.id.userUsername);
        comment = itemView.findViewById(R.id.comment);
        commentTimeAgo = itemView.findViewById(R.id.timeago);

    }

}

}

查看logcat时,第3行报错:

String timestampString = String.valueOf(timestamp);
String[] noOpeningParentheses = timestampString.split("\\(");
String[] noClosingParentheses = noOpeningParentheses[1].split("\\)"); // error here
String[] noCommaAndSpace = noClosingParentheses[0].split(", ");
String[] secondsFromTimestamp = noCommaAndSpace[0].split("seconds=");
String[] nanosecondsFromTimestamp = noCommaAndSpace[1].split("nanoseconds=");
long millis = TimeUnit.SECONDS.toMillis(Long.parseLong(secondsFromTimestamp[1])) + TimeUnit.NANOSECONDS.toMillis(Long.parseLong(nanosecondsFromTimestamp[1]));

这是我为将 Firebase Firestore 时间戳字段转换为毫秒而编写的代码。

我在 logcat 中得到的类似于 java.lang.ArrayIndexOutOfBoundsException: length=1; index=1

我不知道如何解决这个问题。有什么帮助吗?

【问题讨论】:

  • 请发布您的适配器
  • @tendai 完成。你可以检查一下
  • 你确定数组 timestampString.split("\(") 有 2 个值吗?但由于它只会在你滚动浏览很多项目后崩溃,它可能与 smoothScroll 有关
  • @tendai 当有几个项目时它会崩溃,而不是如果有很多项目。
  • @tendai 我尝试打印用于转换时间戳的每一行代码。发布评论时,应用程序崩溃,打印时我收到一条消息 null。如果项目在编辑文本后面,我可以清楚地看到 recyclerview 滚动并且没有崩溃。但是如果项目是 2 或 3 并且仍然不在编辑文本后面,这就是应用程序崩溃的地方。

标签: android google-cloud-firestore android-recyclerview logcat


【解决方案1】:

替换:

recyclerview.smoothScrollToPosition(adapter.getItemCount());

与:

int lastIndex = adapter.getItemCount()-1;
if(lastIndex!=-1)
{recyclerview.smoothScrollToPosition(lastIndex);}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 2013-03-26
    相关资源
    最近更新 更多