android.content.res.Resources $ NotFoundException:无法找到资源ID [英] android.content.res.Resources$NotFoundException: Unable to find resource ID

查看:117
本文介绍了android.content.res.Resources $ NotFoundException:无法找到资源ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的RecyclerView中,我需要将部分物品替换​​为片段. 我遵循了维克多·克鲁兹(Victor Cruz)的答案,我能够实现我想要的.

In my RecyclerView I need replace part of my item to my fragment. I have followed this answer by Victor Cruz and I am able to achieve what I wanted.

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

Everything is working fine but I am facing one serious problem i.e I am getting Resources$NotFoundException Unable to find resource ID only in the last item of my RecyclerView, note that this problem is occurring only in the last item rest others are working fine.

我尝试过的步骤:

  1. 我试图在R.java文件中寻找resource ID,但徒劳无功.

我尝试减少和增加RecyclerView中的项目数量,但问题仍然相同.

I have tried reducing and increasing the number of items in RecyclerView but the problem is still the same.

请提出建议,我在哪里做错了.我很乐意提供其他相关细节.

Please give suggestions where am I doing wrong. I will be happy to provide any other relevant details.

发布问题5天后(并为此苦苦了一周),我无法解决问题. 我已经制作了一个小示例应用程序来执行此特定任务,您可以下载代码从这里开始.

After 5 days of posting the Question (and struggling with this for a week), I am not able to figure problem out. I have made a small sample app performing this particular task, You can 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();
}

如果可以用的话,这是我的logcat.

Here is my logcat if it can be of any use.

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)

推荐答案

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

This problem is interesting. After debugging your sample app for a while this is my finding:

  • 缺少的resource id是已创建片段的ID- CardBackFragment.
  • resource id是在替换并提交片段后动态给出的
  • Theresource id that is missing is the id of created fragment - CardBackFragment.
  • The resource id is given dynamically after you replace and commit the fragment

为了证明我刚才所说的,这是我调试您的应用程序时的屏幕截图,请注意显示的 id : 这是调试器告诉它丢失的丢失的ID:

For prof of what I have just said, here is a screenshot when I was debugging your app notice the id that is shown: And here is the missing id that the debugger told it was missing:

要清楚一点,newContainerId tis被翻译成十六进制ID ,在这里(对不起我的英语不好)

And to be clear, the newContainerId tis translated into hex id that is here (sorry for my bad english)

那这里发生了什么?

答案在于代码执行该行的方式: myHolderflipcard.cardView.setVisibility(View.GONE); 提交要显示的片段后便触发了该事件.

The answer lies in the way the code is execute the line: myHolderflipcard.cardView.setVisibility(View.GONE); That was trigger after you commit the fragment to be shown.

这是发生了什么: 当您告诉卡片视图消失时,最后一项从ui中删除->因为它已从ui中删除,并且是回收者视图中的最后一项->缩短recycler view的高度以最小化view.该错误发生在最后一个项目上,因为recycler view知道容纳该问题的row layout为空,并且它是最后一个项目->最后一个项目被转移到上面的问题行.同时,没有将fragment插入到framelayout中的线程.因此,完成并尝试找到containerid时,它将找不到它.因此,崩溃.

Here is what happen: When you told the card view to be gone, the last item is removed from ui -> Because it is removed from ui and it is the last item on the recycler view -> the height of the recycler view is shorten to minimize the view. The bug happen for the last item because the recycler view understand that the row layout that hold the question is empty and it is the last item -> the last item is instead transfer to the question row above. Meanwhile, the thread that insert the fragment into your framelayout is not done. So when it's done and it try to find the containerid, it cannot find it. Hence, the crash.

因此解决此问题的方法是等待框架完全添加然后,然后删除问题

So the way to fix it is to wait for the frame to be added completely then you remove the question

这里是解决方法:

  • flipcard方法中删除myHolderflipcard.cardView.setVisibility(View.GONE);

在外部创建一个:private MyHolder curHolder;

创建一个可运行的对象以隐藏CardView:

Create a runnable to hide the 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);

//handler.postDelayed(this,500); } };

// handler.postDelayed(this, 500); } };

在提交完成后将其发布:

post it after the commit is done:

        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);代替

Although it happens really fast. You can use handler.postDelayed(runnable, 100); instead if you want to ensure that the fragment is successfully replaced under any circumstances

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

And here is the full code (since I'm really bad at english, so I post it just in case)

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

这篇关于android.content.res.Resources $ NotFoundException:无法找到资源ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆