代码之家  ›  专栏  ›  技术社区  ›  nimi0112

安卓所容纳之物res.Resources$NotFoundException:找不到资源ID

  •  2
  • nimi0112  · 技术社区  · 7 年前

    在我的RecyclerView中,我需要将项目的一部分替换为片段。 我跟踪了 this answer by Victor Cruz 我能够实现我想要的。

    一切正常,但我面临一个严重的问题,即 Resources$NotFoundException Unable to find resource ID 仅在我的RecyclerView的最后一个项目中,请注意,此问题仅在最后一个项目中出现,其他项目工作正常。

    我尝试过的步骤:

    1. 我试着寻找 resource ID 在R.java文件中,但都是徒劳的。

    2. 我尝试过减少和增加RecyclerView中的项目数量,但问题仍然是一样的。

    3. 搜索了其他相关答案,如将相同的id分配给父布局,并传入替换片段。
    4. 尝试捕获异常,但失败了,因为我认为只有在最后一项的情况下,才能在创建时找到布局文件。
    5. 检查是否由于任何类型转换错误而发生。

    请给出我哪里做错了的建议。我很乐意提供任何其他相关细节。

    发布问题5天后 (为此挣扎了一周), 我想不出这个问题。 我制作了一个执行此特定任务的小示例应用程序,您可以 download the code from here.

    请帮我解决这个问题。

    编辑:过帐代码:

    private void flipcard(final RecyclerView.ViewHolder holder)
    {
        final MyHolder myHolderflipcard= (MyHolder) holder;
                // Delete old fragment
                int containerId = myHolderflipcard.container.getId();// Get container id
                Fragment oldFragment = ((FragmentActivity) context).getFragmentManager().findFragmentById(containerId);
                if(oldFragment != null)
                {
                    ((FragmentActivity) context).getFragmentManager().beginTransaction().remove(oldFragment).commit();
                }
                int newContainerId = getUniqueId();
                // Set the new Id to our know fragment container
                myHolderflipcard.container.setId(newContainerId);
                // Just for Testing we are going to create a new fragment according
                // if the view position is pair one fragment type is created, if not
                // a different one is used.
                {
                    Fragment f;
                    f = new CardBackFragment();
                    // Then just replace the recycler view fragment as usually
                    ((FragmentActivity) context).getFragmentManager().beginTransaction()
                            .setCustomAnimations(
                                    R.animator.card_flip_right_in,
                                    R.animator.card_flip_right_out,
                                    R.animator.card_flip_left_in,
                                    R.animator.card_flip_left_out)
                            .addToBackStack(null)
                            .replace(newContainerId, f).commit();
    
                    myHolderflipcard.cardView.setVisibility(View.GONE);
                }
    }
    // Method that could us an unique id
    private int getUniqueId(){
        return (int)
                SystemClock.currentThreadTimeMillis();
    }
    

    这是我的日志,如果有用的话。

    E/UncaughtException: android.content.res.Resources$NotFoundException: Unable to find resource ID #0x1678
                                                                                  at android.content.res.Resources.getResourceName(Resources.java:2209)
                                                                                  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:886)
                                                                                  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
                                                                                  at android.app.BackStackRecord.run(BackStackRecord.java:834)
                                                                                  at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452)
                                                                                  at android.app.FragmentManagerImpl$1.run(FragmentManager.java:447)
                                                                                  at android.os.Handler.handleCallback(Handler.java:739)
                                                                                  at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                  at android.os.Looper.loop(Looper.java:135)
                                                                                  at android.app.ActivityThread.main(ActivityThread.java:5292)
                                                                                  at java.lang.reflect.Method.invoke(Native Method)
                                                                                  at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
                                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
    
    E/AndroidRuntime: FATAL EXCEPTION: main
                                                                           Process: **app package name //intentionally written**, PID: 3136
                                                                           android.content.res.Resources$NotFoundException: Unable to find resource ID #0x1678
                                                                               at android.content.res.Resources.getResourceName(Resources.java:2209)
                                                                               at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:886)
                                                                               at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
                                                                               at android.app.BackStackRecord.run(BackStackRecord.java:834)
                                                                               at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452)
                                                                               at android.app.FragmentManagerImpl$1.run(FragmentManager.java:447)
                                                                               at android.os.Handler.handleCallback(Handler.java:739)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                               at android.os.Looper.loop(Looper.java:135)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5292)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at java.lang.reflect.Method.invoke(Method.java:372)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
    
    2 回复  |  直到 7 年前
        1
  •  6
  •   VÅ© Thành Tâm    7 年前

    这个问题很有趣。在调试示例应用程序一段时间后,我发现:

    • 这个 resource id 缺少的是所创建片段的id- CardBackFragment .
    • 这个 资源id 在替换和提交片段后动态提供

    对于我刚才所说的教授,这里是我调试你的应用程序时的屏幕截图,请注意 身份证件 如图所示: enter image description here 这是调试器告诉它丢失的缺少的id: enter image description here

    要明确的是 newContainerId 翻译为 十六进制id 就是这里(抱歉我的英语不好)

    那么这里发生了什么?

    答案在于代码执行行的方式: myHolderflipcard.cardView.setVisibility(View.GONE); 这是在提交要显示的片段后触发的。

    发生的情况如下: 当您告诉卡片视图消失时,最后一项将从ui中删除->因为它已从ui中删除,并且是回收器视图上的最后一项->的高度 recycler view 缩短以最小化 view . 最后一项出现错误,因为 回收器视图 了解 row layout 保留问题的选项为空,并且是最后一项->最后一项改为转移到上面的问题行。同时,插入 fragment 进入您的 framelayout 未完成。所以当它完成后,它会试图找到 containerid ,它找不到它。因此,坠机。

    所以解决这个问题的方法是 等待帧完全添加 然后 您删除了问题

    以下是修复方法:

    • 去除 我的持卡人信用卡。cardView。设置可见性(View.GONE); 您的 flipcard 方法

    • 在外部创建: private MyHolder curHolder;

    • 创建runnable以隐藏CardView:

      private Handler handler = new Handler();
      
      private Runnable runnable = new Runnable() {
          @Override
          public void run() {
             Log.d("mId", String.valueOf(curHolder.container.getId()));
              curHolder.cardView.setVisibility(View.GONE);
      

      //处理程序。postDelayed(此,500); } };

    • 提交完成后发布:

              Fragment f;
              f = new CardBackFragment();
              // Then just replace the recycler view fragment as usually
              ((FragmentActivity) context).getFragmentManager().beginTransaction()
                      .setCustomAnimations(
                              R.animator.card_flip_right_in,
                              R.animator.card_flip_right_out,
                              R.animator.card_flip_left_in,
                              R.animator.card_flip_left_out)
                      .addToBackStack(null)
                      .replace(newContainerId, f).commit();
              // Once all fragment replacement is done we can show the hidden container
              handler.post(runnable);
      

    虽然发生得很快。您可以使用 handler.postDelayed(runnable, 100); 如果您想确保在任何情况下都能成功替换片段,请改为

    这是完整的代码(因为我英语很差,所以我把它贴出来以防万一)

        private void flipcard(final RecyclerView.ViewHolder holder)
        {
            final MyHolder myHolderflipcard= (MyHolder) holder;
    
            String nim=mysr_id.get(Integer.parseInt(mpref.getradio_button_value()));
            Pattern pattern = Pattern.compile("[0-9]+");
            Matcher matcher = pattern.matcher(nim);
            if (matcher.find())
            {
                currentsrid=Integer.parseInt(matcher.group(0));
    
                if (currentsrid!=flag)
                {
                    flag = Integer.parseInt(matcher.group(0));
                    // Delete old fragment
                    int containerId = myHolderflipcard.container.getId();// Get container id
                    Fragment oldFragment = ((FragmentActivity) context).getFragmentManager().findFragmentById(containerId);
                    if(oldFragment != null)
                    {
                        ((FragmentActivity) context).getFragmentManager().beginTransaction().remove(oldFragment).commit();
                    }
                    int newContainerId = 0;
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                        newContainerId = View.generateViewId();
                    }
    
                    // Set the new Id to our know fragment container
    
                    myHolderflipcard.container.setId(newContainerId);
    
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                        curHolder = myHolderflipcard;
                    }
    
    
                    // Just for Testing we are going to create a new fragment according
                    // if the view position is pair one fragment type is created, if not
                    // a different one is used.
    
    
                    {
                        Fragment f;
                        f = new CardBackFragment();
                        // Then just replace the recycler view fragment as usually
                        ((FragmentActivity) context).getFragmentManager().beginTransaction()
                                .setCustomAnimations(
                                        R.animator.card_flip_right_in,
                                        R.animator.card_flip_right_out,
                                        R.animator.card_flip_left_in,
                                        R.animator.card_flip_left_out)
                                .addToBackStack(null)
                                .replace(newContainerId, f).commit();
                        // Once all fragment replacement is done we can show the hidden container
                        handler.post(runnable);
    
                        //myHolderflipcard.container.setVisibility(View.VISIBLE);
                        //myHolderflipcard.radioGroup.setVisibility(View.GONE);
                        //myHolderflipcard.tvQuestion.setVisibility(View.GONE);
    //                    myHolderflipcard.cardView.setVisibility(View.GONE);
                    }
    
                }else
                {
                   // backtoorignal=false;
                    // ((FragmentActivity)context). getFragmentManager().popBackStack();
                }
    
            }
    
        }
    
        private MyHolder curHolder;
        private Handler handler = new Handler();
    
        private Runnable runnable = new Runnable() {
            @Override
            public void run() {
               Log.d("mId", String.valueOf(curHolder.container.getId()));
                curHolder.cardView.setVisibility(View.GONE);
            }
        };
    
        2
  •  1
  •   Soo Chun Jung    7 年前

    检查一下小东西。
    这可能不是原因,但通常是在文本视图上设置文本时使用整数(number)时发生的。
    像贝娄

    int a = 999;    
    myTextView.setText(a);`
    

    所以我假设您使用setText调用,其中包含数字 卡片背面碎片