【问题标题】:Return statement being skipped返回语句被跳过
【发布时间】:2017-01-25 13:54:41
【问题描述】:

我有一个 recyclerview,旨在显示交易,但按日期分隔。但是我的 getItemViewType 似乎不起作用。这是代码:

    @Override
    public int getItemViewType(int position) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
        if (mCompareDate == null || !fmt.format(mTransactions.get(mTransactionPosition).getTime()).equals(fmt.format(mCompareDate))) {
            mCompareDate = mTransactions.get(mTransactionPosition).getTime();
            return 2;
        } else {
            return 1;
        }
    }

我有一个检查值的 if 语句,但是当我运行它时,它会崩溃。我之前没有“else if”语句,但我希望它能帮助崩溃,else 语句应该可以正常工作。

不管怎样,我调试它并一步一步地观察它,程序似乎发现第一个语句是正确的,然后它会在语句中执行所有操作,包括“return 2;”但是之后它只是跳过返回 0,这会导致崩溃,如果我没有 else if 那么它会直接跳到 else 语句并返回 1,也会导致它崩溃。

编辑:修复了 else if 语句的混淆问题。

进一步编辑:因为混乱没有解决,这里是我的意思的 gif https://gyazo.com/06d2de58e7c170f0cbbf1a4e58be7ca3

【问题讨论】:

  • 您需要发布堆栈跟踪或更多代码,这很好。
  • 你需要检查 if (mTransactions == null) 和 if (mTransactions.get(mTransactionPosition) == null)
  • @DominiqueLorre 我看着调试器通过它,这些陈述都不是真的。它从字面上读取 if 语句是正确的,然后转到 return 2 行,然后继续到 else 并返回该值。
  • 你能澄清“它崩溃了”吗?
  • 嗯,它会崩溃,该语句由于某种原因返回了不正确的值,这使得程序稍后崩溃,但是该语句根本不应该返回错误的值,正如它在我的 gif 中显示的那样。

标签: java android if-statement return


【解决方案1】:

尝试使用 switch 而不是多个 if else if :反正 一旦 return 1 稍后执行,部分代码就是死代码,所以它不会执行.. 您可以使用 continue 和 break 语句来控制条件语句
添加请发布您的异常/logcat。

【讨论】:

    【解决方案2】:

    嗯,第一个问题,你没有正确理解 if else if 概念。当if条件一旦返回true,其他else if不检查。

    还有第二个问题

    一个函数只能返回一次。您在末尾明确返回return 0,这是无效的。所以,你的程序崩溃了。

    玩得开心

    【讨论】:

    • 正如我在问题中提到的,我知道如何使用 else if,我只是尝试用它来解决问题,原始代码只是 else,因为它要么是要么不是,但是它会即使 if 语句为真,也总是进入 else 语句,并且我已经看到调试器通过 if 语句进入 return 2 字段,然后进入 else。
    • 我刚刚告诉你你的代码崩溃的原因
    • 不,你没有,不管有没有 else if 语句,它都会崩溃,我已经说过两次了。 else if 只是我尝试过的,因为它正在遍历 if 代码,查看 if 代码是否正确,运行 return 2 代码,然后继续执行 else 语句和 return 1 语句。
    • @JamesGreen 你不会得到答案,因为你非常不清楚。您提到它崩溃了,但他们显然这个神秘的“崩溃”实际上并不是您要问的,您实际上是在询问与 1 与 2 有关的事情,然后您提到了代码中没有的 0,并且我们不知道您的 预期实际 结果是什么,这些其他变量在您的代码中是什么,或者您的最终目标是什么。所以,如果你想要一个有用的答案,请写一个有用的问题,而不是让每个人都感到困惑。
    【解决方案3】:

    您需要返回范围为 0 到 viewCount - 1 的视图类型 int。

        @Override
        public int getItemViewType(int position) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
        if (mCompareDate == null || !fmt.format(mTransactions.get(mTransactionPosition).getTime()).equals(fmt.format(mCompareDate))) {
            mCompareDate = mTransactions.get(mTransactionPosition).getTime();
            return 1;
        } else {
            return 0;
        }
    }
    

    编辑:另外,你没有在你的方法中使用位置。 AdapterView 需要向前和向后滚动并以它想要的任何顺序访问视图。我不确定您如何管理此方法之外的内容,但看起来您希望适配器按顺序迭代...

    另一个编辑:这将需要在适配器的其他地方进行更改:

    @Override
    public int getItemViewType(int position) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
        if (position == 0 || !fmt.format(mTransactions.get(position).getTime()
                .equals(fmt.format(mTransactions.get(position - 1).getTime())) {
            // First transaction on this date (probably want to give it a header?)
            return 1;
        else {
            // transaction on same date as previous in list
            return 0;
        }
    }
    

    最终编辑:因为您想要的 DateViews 不是列表中的元素,所以我建议完全忘记 getItemViewType()。为您的 TransactionView 提供一个与 DateView 相同的标题,并带有一个 id,这样您就可以将可见性设置为 GONE 或 VISIBLE。

    然后在onBindViewHolder()中:

    SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
    if (position == 0 || !fmt.format(mTransactions.get(position).getTime()
            .equals(fmt.format(mTransactions.get(position - 1).getTime())) {
        // First transaction on this date (probably want to give it a header?)
        holder.heading.setVisibility(View.VISIBLE);
        holder.heading.setText(fmt.format(mTransactions.get(position).getTime());
    else {
        // transaction on same date as previous in list
        holder.heading.setVisibility(View.GONE);
    }
    // Fill in other details of TransactionView here
    

    【讨论】:

    • 没用。不过谢谢。检查问题中的 gif,应该更好地解释。
    • 使用实际仓位的问题在于,它背后的想法意味着会有多个交易,并且天是分开的,所以例如如果我在 16 号做了那么会有一个DateViewHolder 会显示这个。然而,这可能会破坏基于位置的访问交易信息的系统。因此,我有一个 transactionPosition 字段,该字段仅在创建 transactionViewHolder 时才会增加。因此该位置不会弄乱 mTransactions 数组。
    • 但是当您向后滚动列表时会发生什么?
    • 所以你想要每个日期都有一行?
    • 好点,我不知道我会怎么做介意你。使用位置不会以我能想到的方式工作。假设我在不同的日子在 mTransactions 中有三个值。如果我让它通过位置来完成,那么它会期望 mTransactions 有 6 个值。
    猜你喜欢
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多