【问题标题】:Null Model Object When Reading Data List From Firebase Database从 Firebase 数据库读取数据列表时为空模型对象
【发布时间】:2017-04-10 11:43:22
【问题描述】:

我正在使用 Firebase 实时数据库来填充回收站视图,使用材料设计卡片视图来显示不同类别的业务。

在我的导航抽屉中,我有一个类别列表,我将在这些类别中显示我所在地区的不同类型的企业。到目前为止,我只有一个片段可以放大视图,以确保在我到达其他片段之前一切正常nav categories,这是 Firebase 数据库的屏幕截图database

当我点击“会计/财务”片段时,我从 Android Studios 中得到一个显示 java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference

这会将我带到我的 Recyclerview 适配器类中的 getItemCount()。它返回 null 因为 Model 类为 null。如果我硬编码一个像 10 这样的数字以在getItemCount() 中返回,那么它将在onBindViewHolder() 中出错,我从企业列表中获取位置。这是我认为与该问题有关的代码。部分代码将被删除以使其尽可能简洁。

这是我从 Firebase 数据库获取数据并尝试将数据分配给 Businesses.java 模型类以从 recyclerview 读取的主要活动。

public class HomeScreenActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener
{
    private List<Businesses> mBusinesses = new ArrayList<>();
    private RecyclerViewAdapter mRecyclerViewAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home_screen);

        DatabaseReference database = FirebaseDatabase.getInstance().getReference().child("accounting");
        database.addChildEventListener(new ChildEventListener()
        {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s)
            {
                Businesses model = dataSnapshot.getValue(Businesses.class);
                mBusinesses.add(model);
            }
        });
    }


    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item)
    {
        int id = item.getItemId();
        displaySelectedScreen(id);
        item.setCheckable(true);
        setTitle(item.getTitle());

        return true;
    }

    private void displaySelectedScreen(int itemId)
    {
        Fragment fragment = null;

        switch (itemId)
        {
            case R.id.nav_accounting_finance:
                fragment = new AccountingFinanceFrag();
                break;
        }

        if (fragment != null)
        {
            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.replace(R.id.fragment_container, fragment);
            ft.commit();
        }
    }

}

这是我的模型类,当从“会计/财务”片段调用 recyclerview 时返回 null

@IgnoreExtraProperties
public class Businesses
{
    public String Name;
    public String About;
    public String Picture;
    public long Phone;

    public Businesses()
    {

    }

    public Businesses(String name, String about, String picture)
    {
        Name = name;
        About = about;
        Picture = picture;
    }
}

这是我的 Recyclerview 适配器类,我在其中获取了应该包含 Firebase 数据库数据的空模型对象。

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecViewHolder>
{
    private Context mContext;
    private List<Businesses> mBusinesses;

    public RecyclerViewAdapter(Context context, List<Businesses> businesses)
    {
        mContext = context;
        mBusinesses = businesses;
    }

    @Override
    public RecViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View view = inflater.inflate(R.layout.card, parent, false);
        return new RecViewHolder(view);
    }

    @Override
    public void onBindViewHolder(RecViewHolder holder, int position)
    {
        Businesses businesses = mBusinesses.get(position);
        holder.mName.setText(businesses.Name);
        holder.mAbout.setText(businesses.About);
        holder.bindGalleryItem(businesses);
    }

    @Override
    public int getItemCount()
    {
        return mBusinesses.size();
    }

    public class RecViewHolder extends RecyclerView.ViewHolder
    {
        private CardView mCardView;
        private Businesses mBusinesses;
        private ImageView mImageView;
        private TextView mName, mAbout;

        RecViewHolder(View itemView)
        {
            super(itemView);
            mCardView = (CardView) itemView.findViewById(R.id.card_view);
            mImageView = (ImageView) itemView.findViewById(R.id.buisness_image);
            mName = (TextView) itemView.findViewById(R.id.business_name);
            mAbout = (TextView) itemView.findViewById(R.id.buisness_about);
        }

        public void bindGalleryItem(Businesses businesses)
        {
            mBusinesses = businesses;
            Glide.with(mContext)
                    .load(businesses.Picture)
                    .placeholder(R.mipmap.ic_launcher)
                    .diskCacheStrategy(DiskCacheStrategy.RESULT)
                    .override(200, 200)
                    .into(mImageView);
        }
    }
}

这是 recyclerview 被夸大的片段。

public class AccountingFinanceFrag extends Fragment
{
    private List<Businesses> mBusinesses;
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private TextView mNameText, mAboutText;
    private ImageView mImageView;

        @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View v = inflater.inflate(R.layout.fragment_category, container, false);

        mNameText = (TextView) v.findViewById(R.id.business_name);
        mAboutText = (TextView) v.findViewById(R.id.buisness_about);
        mImageView = (ImageView) v.findViewById(R.id.buisness_image);

        mRecyclerView = (RecyclerView) v.findViewById(R.id.fragment_recyclerview);
        mAdapter = new RecyclerViewAdapter(getContext(), mBusinesses );
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

        return v;
    }
}

数据库的 JSON 文件

 {
  "accounting" : {
    "buisness_0" : {
      "About" : "dummy text",
      "Address" : "123 test ave test, test 00000",
      "Email" : "test@example.com",
      "Name" : "Test test",
      "Owner" : "Test owner",
      "Phone" : 4120000000,
      "Picture" : "add link"
    },
    "business_1" : {
      "About" : "dummy text",
      "Address" : "123 test ave test, test 00000",
      "Email" : "test@example.com",
      "Name" : "Test test",
      "Owner" : "Test owner",
      "Phone" : 4120000000,
      "Picture" : "add link"
    }
  }
}

【问题讨论】:

  • 请为您的 Firebase 数据库截图
  • @Elsunhoty 我正在从数据库中获取数据。当我调试并在Businesses model = dataSnapshot.getValue(Businesses.class) 行上放置断点时,我能够看到它。但是我用截图更新了代码
  • 您在问题中包含了 JSON 树的图片。请将其替换为实际的 JSON 作为文本,您可以通过单击 your Firebase Database console 中的导出 JSON 链接轻松获得。将 JSON 作为文本使其可搜索,使我们可以轻松地使用它来测试您的实际数据并在我们的答案中使用它,通常只是一件好事。 (@Elsunhoty:请询问 JSON 文本,而不是截图)
  • @FrankvanPuffelen 我更新了代码,但我确信数据库没有问题,因为我在 onChildAdded() 中获得了数据。

标签: android firebase firebase-realtime-database


【解决方案1】:

您的活动中的mBusinesses 和您的片段中的mBusinesses 是不同的东西,这就是发生混淆的地方。

在您的活动中,您初始化并向mBusinesses 添加条目,但是在创建 RecyclerView 时,您将片段的mBusinesses 对象传递给它,该对象尚未初始化或添加任何数据,因此NullPointerException

为此,Fragment 需要将数据提供给 RecyclerView,可能是通过在 Fragment 中加载数据,或者 Activity 将数据传递给 Fragment 或其他方式。

【讨论】:

    猜你喜欢
    • 2020-01-21
    • 2020-10-10
    • 1970-01-01
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    • 2018-02-17
    相关资源
    最近更新 更多