草庐IT

android - FirebaseRecyclerAdapter 无法将第一个布局识别为位置

coder 2023-12-22 原文

我的标题有点难以理解,但基本上当我将项目添加到我的数据库时,它应该显示在 RecyclerView 中。现在在我的 RecyclerView 中我有两个布局,但问题是我的数据库的第一项在我的其他布局中落后于我的第一项。因此,如果我的数据库中有 3 个项目,它只显示数据库中的 2 个项目,第一个项目隐藏在 RecyclerView 中我的第一个项目后面,这是一个完全不使用数据库的不同布局。

这是我的代码:

 FirebaseRecyclerOptions<Event> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<Event>()
            .setQuery(query1, Event.class).build();
    AccAdapter = new FirebaseRecyclerAdapter<Event, RecyclerView.ViewHolder>(firebaseRecyclerOptions){

        final static int TYPE_HEADER = 0;
        final static int TYPE_ITEM = 1;


        @Override
        public int getItemViewType(int position) {
            if (position == 0) return TYPE_HEADER;
            return TYPE_ITEM;
        }

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

            if (viewType == TYPE_HEADER){
                View view = LayoutInflater.from(getActivity()).inflate(R.layout.recycler_view_row_add_items,
                        parent, false);
                return new ProdudctHolder3(view);
            } else {
                View view = LayoutInflater.from(getActivity()).inflate(R.layout.recycler_view_row_acc,
                        parent, false);
                return new ProductHolder2(view);
            }
        }

        @Override
        protected void onBindViewHolder(final RecyclerView.ViewHolder holder, int position, final Event model) {
            if (holder instanceof ProdudctHolder3){
                ((ProdudctHolder3) holder).addBackground.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        startActivity(new Intent(getActivity(), AccAddItems.class ));
                    }
                });
            } else{

                final ProductHolder2 productHolder2 = (ProductHolder2) holder;


                productHolder2.mName.setText(model.getName());
                productHolder2.view.setBackgroundResource(getBackgroundDrawable(Integer.valueOf(model.getProductAmount())));
                productHolder2.mbackground.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                        dialog = new Dialog(getActivity());
                        dialog.setContentView(R.layout.popup_edit_product);

                        SeekBar amountSeekBar = dialog.findViewById(R.id.amountSeekBar);
                        amountSeekBar.setMax(100);
                        amountSeekBar.setProgress(Integer.valueOf(model.getProductAmount()));
                        amountSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                            @Override
                            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                                progress = i;
                            }

                            @Override
                            public void onStartTrackingTouch(SeekBar seekBar) {

                            }

                            @Override
                            public void onStopTrackingTouch(SeekBar seekBar) {
                                getRef(holder.getAdapterPosition()).child("productAmount").setValue(String.valueOf(progress));
                                dialog.dismiss();

                            }
                        });

                        dialog.show();

                    }
                });

                productHolder2.mbackground.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View view) {
                        final PopupMenu popupMenu = new PopupMenu(getActivity(), productHolder2.mbackground);

                        popupMenu.inflate(R.menu.menu_acc);
                        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                            @Override
                            public boolean onMenuItemClick(MenuItem menuItem) {
                                switch (menuItem.getItemId()){
                                    case R.id.deleteProduct:
                                        getRef(productHolder2.getAdapterPosition()).removeValue();
                                        popupMenu.dismiss();
                                        return true;

                                    default:
                                        return false;
                                }
                            }
                        });

                        popupMenu.show();

                        return true;
                    }
                });

            }
        }

    };

    mAccRecyclerViewRef.setAdapter(AccAdapter);

我的两个产品持有人

私有(private)类 ProdudctHolder3 扩展了 RecyclerView.ViewHolder{

    private RelativeLayout addBackground;

    public ProdudctHolder3(View itemView) {
        super(itemView);
        addBackground = itemView.findViewById(R.id.mBackground2);
    }
}

private class ProductHolder2 extends RecyclerView.ViewHolder{

    private TextView mName;
    private RelativeLayout mbackground;
    private View view;

    public ProductHolder2(View itemView) {
        super(itemView);

        mName = itemView.findViewById(R.id.ItemName);
        mbackground = itemView.findViewById(R.id.mBackground1);
        view = itemView.findViewById(R.id.amountIndicator);

    }
}

最佳答案

理想的解决方案是在单个 RecyclerView 上设置两个适配器,但不幸的是,这是不可能的。 但是,您可以制作一个处理两种类型项目的自定义适配器。我将通过举个例子来解释这一点。

假设您需要显示两种类型的对象,人类外星人。您的对象需要完全不同的布局和完全不同的 ViewHolders。请查看下面的 ViewHolders 代码:

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static class HumanViewHolder extends RecyclerView.ViewHolder {
        public HumanViewHolder(View itemView) {
            super(itemView);

            //Prepare your ViewHolder
        }

        public void bind(Human human) {

            //Display your human object
        }
    }

    private static class AlienViewHolder extends RecyclerView.ViewHolder {
        public AlienViewHolder(View itemView) {
            super(itemView);

            //Prepare your ViewHolder
        }

        public void bind(Alien alien) {

            //Display your alien object
        }
    }
}

首先,您需要向适配器添加两个不同的常量来表示两种类型的 View :

private static final int ITEM_TYPE_HUMAN;
private static final int ITEM_TYPE_ALIEN;

为简单起见,我们还假设您将对象存储在列表中:

private List<Object> items = new ArrayList<>();

public MyAdapter(List<Object> items) {
    this.items.addAll(items);

    //Other stuff if needed
}

现在,您需要做的第一件事就是实现 getItemViewType() 方法:

@Override
public int getItemViewType(int position) {
    if (items.get(position) instanceof Human) {
        return ITEM_TYPE_HUMAN;
    } else {
        return ITEM_TYPE_ALIEN;
    }
} 

其次,您需要像这样在 onCreateViewHolder() 方法中使用项目类型:

@Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)  {
    LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());

    if (viewType == ITEM_TYPE_HUMAN) {
        View view = layoutInflater.inflate(R.layout.item_human, parent, false);

        return new HumanViewHolder(view);
    } else {      
        View view = layoutInflater.inflate(R.layout.item_alien, parent, false);

        return new AlienViewHolder(view);
    } 
} 

最后,您只需要像这样绑定(bind)适当的 View 持有者:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
    Object item = items.get(position);

    if (viewHolder instanceof HumanViewHolder) {
        ((HumanViewHolder) viewHolder).bind((Human) item);
    } else {
        ((AlienViewHolder) viewHolder).bind((Alien) item);
    } 
} 

关于android - FirebaseRecyclerAdapter 无法将第一个布局识别为位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50777733/

有关android - FirebaseRecyclerAdapter 无法将第一个布局识别为位置的更多相关文章

  1. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  3. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  4. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  5. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  6. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  7. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

    我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

  8. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  9. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  10. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

随机推荐