首页 > 解决方案 > android 应用程序中回收站视图节点的总数不断增加

问题描述

我的原始问题 我正在使用 firebase 实时数据库制作一个 android 应用程序。我在侧面回收器视图中获得了 firebase 节点的总和。我在回收站视图之外有一个文本视图,我在其中获取了回收站视图值的小计。我的问题是我无法得到实际的总和,而且当我上下滚动时总和不断增加。这是我的主要活动 JAVA 代码:

public class MainActivity extends AppCompatActivity {
    FirebaseDatabase myfire;
    DatabaseReference myRef;
    private FirebaseRecyclerOptions<entry> options;
    int totalEarned = 0;
    int totalSpent = 0;
    int totalSaved=0;
    @Override
    public void onBackPressed() {
        final AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
        dialog.setTitle("Are you sure to exit?");
        dialog.setPositiveButton("Play", (dialog1, which) -> {

        });

        dialog.setNegativeButton("Exit", (dialog12, which) -> {
            FirebaseAuth.getInstance().signOut();
            MainActivity.this.finish();

        });
        dialog.show();
    }

    private String getUID() {
        FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
        if (mUser != null) {
            String strUID = mUser.getUid();
            if (!TextUtils.isEmpty(strUID)) {
                return strUID;
            }
        }

        return "";

    }
    @SuppressLint("SetTextI18n")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //==============
        final RecyclerView userlist = (RecyclerView) findViewById(R.id.idRecycleView);
        myfire = FirebaseDatabase.getInstance();
        userlist.setLayoutManager(new LinearLayoutManager(this));

        //==================
        final TextView tvTotalIncome = findViewById(R.id.idTotalIncome);
        final TextView tvTotalExpanse = findViewById(R.id.idTotalExpanse);
        final TextView tvTotalSaved = findViewById(R.id.idTotalSaved);
        //==================

        final FloatingActionButton btnBudget = findViewById(R.id.idCreateBudget);
        myfire = FirebaseDatabase.getInstance();
        final String strUID = getUID();
        if (TextUtils.isEmpty(strUID)) {
            //handle case of null UID
        }

        final Intent i = getIntent();
        final String month = Objects.requireNonNull(i.getExtras()).getString("Month");
        //-------------------------------
        btnBudget.setOnClickListener(v -> {
            Intent o;
            o = new Intent(MainActivity.this, AddBudgetActivity.class);
            o.putExtra("Month",month);
            startActivity(o);
            finish();

        });

        if (type.equals("Income")) {
            try {
                totalEarned = (totalEarned+sum);
            } catch (NumberFormatException ex) {
            }

            tvTotalIncome.setText("-)"+String.valueOf( totalEarned));
            holder.btnIcon.setBackgroundResource(R.drawable.circlegreen);
            holder.tvEntry.setText("(+)"+String.valueOf(sum)  );

            try {
                totalSaved = (totalEarned-totalSpent);
            } catch (NumberFormatException ex) {
            }
            tvTotalSaved.setText("(=)"+String.valueOf( totalSaved));
        }else if (type.equals("Expanse")) {

            try {
                totalSpent = (totalSpent+sum);
            } catch (NumberFormatException ex) {
            }
            tvTotalExpanse.setText("-)"+String.valueOf( totalSpent));
            holder.btnIcon.setBackgroundResource(R.drawable.circlered);
            holder.tvEntry.setText("(-)"+String.valueOf(sum)  );
            try {
                totalSaved = (totalEarned-totalSpent);
            } catch (NumberFormatException ex) {
            }
            tvTotalSaved.setText("(=)"+String.valueOf( totalSaved));
        }else {
            Toast.makeText(MainActivity.this, " Something Went Wrong !", Toast.LENGTH_SHORT).show();
        }

        //======================


        myRef = myfire.getReference().child("Data").child(strUID).child(month);
//-------------------------
        options = new FirebaseRecyclerOptions.Builder<entry>()
                .setQuery(myRef, entry.class)
                .build();
        final FirebaseRecyclerAdapter<entry, holder_menu> adapter = new FirebaseRecyclerAdapter<entry, holder_menu>(options) {


            @Override
            protected void onBindViewHolder(@NonNull @NotNull holder_menu holder, final int i, @NonNull @NotNull entry model) {
                final String title = getRef(i).getKey();
                assert title != null;


                myRef = myfire.getReference().child("Data").child(strUID).child(month).child(title).child("Budget");
                myRef.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        int budget = 0;

                        if (dataSnapshot.getValue() == null) {
                            Toast.makeText(getApplicationContext(), "Data Not Available", Toast.LENGTH_LONG).show();
                        } else {

                            final String stData1 = (Objects.requireNonNull(dataSnapshot.child("stData1").getValue())).toString();
                            final String stData2 = (Objects.requireNonNull(dataSnapshot.child("stData2").getValue())).toString();
                            final String stData3 = (Objects.requireNonNull(dataSnapshot.child("stData3").getValue())).toString();
                            final String stData4 = (Objects.requireNonNull(dataSnapshot.child("stData4").getValue())).toString();

                            entry basic = new entry(stData1, stData2, stData3, stData4);

                            String first = stData2.substring(0, 1);
                            holder.btnIcon.setText(first);
                            holder.tvHead.setText(stData2);
                            String type;
                            type=(stData3);
                            holder.tvBudget.setText("@" + stData4);
                            int amount = 0;

                            //important line
                            try {
                                amount = (Integer.parseInt(stData4));
                            } catch (NumberFormatException ex) {
                            }
                            //======================
                            budget = amount;

                            myRef = myfire.getReference().child("Data").child(strUID).child(month).child(title).child("Entry");
                            final int finalBudget = budget;
                            myRef.addValueEventListener(new ValueEventListener() {
                                int sum = 0;
                                @Override
                                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {


                                    for (DataSnapshot data : dataSnapshot.getChildren()) {
                                        String section = data.child("stData2").getValue(String.class);
                                        String value = data.child("stData4").getValue(String.class);
                                        assert value != null;
                                        int total = 0;

                                        //important line
                                        try {
                                            total = (Integer.parseInt(value));
                                        } catch (NumberFormatException ex) {
                                        }
                                        //======================
                                        sum = sum + total;
                                        //==============
                                        //======================
                                        if (section.equals("Saving")) {
                                            holder.tvHead.setBackgroundColor(getResources().getColor(R.color.saving));

                                        }else if (section.equals("Paying")) {

                                            holder.tvHead.setBackgroundColor(getResources().getColor(R.color.paying));
                                        }else if (section.equals("Using")) {

                                            holder.tvHead.setBackgroundColor(getResources().getColor(R.color.using));
                                        }else if (section.equals("Earning")) {
                                            holder.tvHead.setBackgroundColor(getResources().getColor(R.color.earning));

                                        }else if (section.equals("Taking")) {

                                            holder.tvHead.setBackgroundColor(getResources().getColor(R.color.taking));
                                        }else if (section.equals("Drawing")) {

                                            holder.tvHead.setBackgroundColor(getResources().getColor(R.color.drawing));

                                        }else {
                                            Toast.makeText(MainActivity.this, " Something Went Wrong !", Toast.LENGTH_SHORT).show();
                                        }
                                    }

                                    holder.tvEntry.setText("(+)" + String.valueOf(sum)  );
                                    holder.tvBalance.setText("(=)" + String.valueOf(finalBudget - sum) );

                                    //important line
                                    holder.btnView.setOnClickListener(new View.OnClickListener() {
                                        @Override
                                        public void onClick(View v) {
                                            Intent o;
                                            o = new Intent(MainActivity.this, ViewHistoryActivity.class);
                                            o.putExtra("Title", title);
                                            o.putExtra("Month", month);
                                            o.putExtra("Type", type);
                                            startActivity(o);
                                            finish();
                                        }
                                    });
                                    holder.btnAdd.setOnClickListener(new View.OnClickListener() {
                                        @Override
                                        public void onClick(View v) {

                                            if (type.equals("Income")) {
                                                Intent o;
                                                o = new Intent(MainActivity.this, EntryIncomeActivity.class);
                                                o.putExtra("Title", title);
                                                o.putExtra("Month", month);
                                                o.putExtra("Type", type);
                                                startActivity(o);
                                                finish();

                                            }else if (type.equals("Expanse")) {
                                                Intent o;
                                                o = new Intent(MainActivity.this, EntryExpanseActivity.class);
                                                o.putExtra("Title", title);
                                                o.putExtra("Month", month);
                                                o.putExtra("Type", type);
                                                startActivity(o);
                                                finish();

                                            }else {
                                                Toast.makeText(MainActivity.this, " Something Went Wrong !", Toast.LENGTH_SHORT).show();
                                            }



                                        }
                                    });
                                    if (type.equals("Income")) {
                                        try {
                                            totalEarned = (totalEarned+sum);
                                        } catch (NumberFormatException ex) {
                                        }

                                        tvTotalIncome.setText("-)"+String.valueOf( totalEarned));
                                        holder.btnIcon.setBackgroundResource(R.drawable.circlegreen);
                                        holder.tvEntry.setText("(+)"+String.valueOf(sum)  );

                                        try {
                                            totalSaved = (totalEarned-totalSpent);
                                        } catch (NumberFormatException ex) {
                                        }
                                        tvTotalSaved.setText("(=)"+String.valueOf( totalSaved));
                                    }else if (type.equals("Expanse")) {

                                        try {
                                            totalSpent = (totalSpent+sum);
                                        } catch (NumberFormatException ex) {
                                        }
                                        tvTotalExpanse.setText("-)"+String.valueOf( totalSpent));
                                        holder.btnIcon.setBackgroundResource(R.drawable.circlered);
                                        holder.tvEntry.setText("(-)"+String.valueOf(sum)  );
                                        try {
                                            totalSaved = (totalEarned-totalSpent);
                                        } catch (NumberFormatException ex) {
                                        }
                                        tvTotalSaved.setText("(=)"+String.valueOf( totalSaved));
                                    }else {
                                        Toast.makeText(MainActivity.this, " Something Went Wrong !", Toast.LENGTH_SHORT).show();
                                    }

                                    //======================



                                }

                                @Override
                                public void onCancelled(@NonNull DatabaseError databaseError) {
                                    throw databaseError.toException(); // never ignore errors
                                }
                            });

                        }

                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {
                        throw error.toException(); // never ignore errors
                    }

                });
            }

            @NonNull
            @Override
            public holder_menu onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item1, parent, false);
                return new holder_menu(v);
            }
        };

        adapter.startListening();
        userlist.setAdapter(adapter);


    }



}

已编辑问题根据@androidLearner 的建议

主要活动

public class MainActivity extends AppCompatActivity {
    FirebaseDatabase myfire;
    DatabaseReference myRef;
    int totalEarned = 0;
    int totalSpent = 0;
    int totalSaved=0;
    madapter adapter;


    String iconsData;
    String headsData;
    int budgetsData=0;
    int enteriesData=0;
    int balancesData=0;
    @Override
    public void onBackPressed() {
        final AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
        dialog.setTitle("Are you sure to exit?");
        dialog.setPositiveButton("Play", (dialog1, which) -> {

        });

        dialog.setNegativeButton("Exit", (dialog12, which) -> {
            FirebaseAuth.getInstance().signOut();
            MainActivity.this.finish();

        });
        dialog.show();
    }

    private String getUID() {
        FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
        if (mUser != null) {
            String strUID = mUser.getUid();
            if (!TextUtils.isEmpty(strUID)) {
                return strUID;
            }
        }

        return "";

    }
    @RequiresApi(api = Build.VERSION_CODES.N)
    @SuppressLint("SetTextI18n")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //==============
        final RecyclerView userlist = (RecyclerView) findViewById(R.id.idRecycleView);
        myfire = FirebaseDatabase.getInstance();
        userlist.setLayoutManager(new LinearLayoutManager(this));

        //==================
        final TextView tvTotalIncome = findViewById(R.id.idTotalIncome);
        final TextView tvTotalExpanse = findViewById(R.id.idTotalExpanse);
        final TextView tvTotalSaved = findViewById(R.id.idTotalSaved);
        //==================

        final FloatingActionButton btnBudget = findViewById(R.id.idCreateBudget);
        myfire = FirebaseDatabase.getInstance();
        final String strUID = getUID();
        if (TextUtils.isEmpty(strUID)) {
            //handle case of null UID
        }

        final Intent i = getIntent();
        final String month = Objects.requireNonNull(i.getExtras()).getString("Month");

        //-------------------------------
        btnBudget.setOnClickListener(v -> {
            Intent o;
            o = new Intent(MainActivity.this, AddBudgetActivity.class);
            o.putExtra("Month",month);
            startActivity(o);
            finish();

        });


//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&---new method

        myRef = myfire.getReference().child("Data").child(strUID).child(month);
        myRef.addValueEventListener(new ValueEventListener() {

            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {


                for (DataSnapshot data : dataSnapshot.getChildren()) {
                    String title = dataSnapshot.getKey();
                    assert title != null;
                    myRef = myfire.getReference().child("Data").child(strUID).child(month).child(title).child("Budget");
        myRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                if (dataSnapshot.getValue() == null) {
                    Toast.makeText(getApplicationContext(), "Data Not Available", Toast.LENGTH_LONG).show();
                } else {

                    final String stData1 = (Objects.requireNonNull(dataSnapshot.child("stData1").getValue())).toString();
                    final String stData2 = (Objects.requireNonNull(dataSnapshot.child("stData2").getValue())).toString();
                    final String stData3 = (Objects.requireNonNull(dataSnapshot.child("stData3").getValue())).toString();
                    final String stData4 = (Objects.requireNonNull(dataSnapshot.child("stData4").getValue())).toString();

                    entry basic = new entry(stData1, stData2, stData3, stData4);

                    iconsData = stData2.substring(0, 1);
                    headsData=stData2;
                    //---------------------------------------------------------------------------entry
                    myRef = myfire.getReference().child("Data").child(strUID).child(month).child(title).child("Entry");
                    myRef.addValueEventListener(new ValueEventListener() {
                        int sum = 0;
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {


                            for (DataSnapshot data : dataSnapshot.getChildren()) {
                                String section = data.child("stData2").getValue(String.class);
                                String value = data.child("stData4").getValue(String.class);
                                assert value != null;
                                int total = 0;
 try {
                                                            total=(Integer.parseInt(value));
                                                        } catch (NumberFormatException ex) {
                                                        }
                                //==============
                                  sum=sum+total;
                            }
                                 enteriesData=sum;
                        }

                        @Override
                        public void onCancelled(@NonNull DatabaseError databaseError) {
                            throw databaseError.toException(); // never ignore errors
                        }
                    });

                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                throw error.toException(); // never ignore errors
            }

        });
                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                throw databaseError.toException(); // never ignore errors
            }
        });
          //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&------NewMethod
        balancesData=budgetsData-enteriesData;
        ArrayList<String> iconList = new ArrayList<>();
        iconList.add(iconsData);
        ArrayList<String> headList= new ArrayList<>();
        headList.add(headsData);
        ArrayList<Integer> budgetList = new ArrayList<>();
        budgetList.add(budgetsData);
        ArrayList<Integer> entryList = new ArrayList<>();
        entryList.add(enteriesData);
        ArrayList<Integer> balanceList = new ArrayList<>();
        balanceList.add(balancesData);

        adapter = new madapter ( this, iconList,headList,budgetList,entryList,balanceList);
        userlist.setAdapter(adapter);
    }



}

RECYCLER VIEW 适配器

public class madapter extends RecyclerView.Adapter<madapter.ViewHolder> {

    private List<String> stricon;
    private List<String> strhead;
    private List<Integer> intbudget;
    private List<Integer> intentry;
    private List<Integer> intbalance;

    //---
    private LayoutInflater mInflater;
    private ItemClickListener mClickListener;

    // data is passed into the constructor

    public madapter(MainActivity mainActivity, ArrayList<String> iconList, ArrayList<String> headList, ArrayList<Integer> budgetList, ArrayList<Integer> entryList, ArrayList<Integer> balanceList) {
        this.mInflater = LayoutInflater.from(mainActivity);
        this.stricon = iconList;
        this.strhead = headList;
        this.intbudget = budgetList;
        this.intentry = entryList;
        this.intbalance= balanceList;
    }


    // inflates the row layout from xml when needed
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.item1, parent, false);
        return new ViewHolder(view);
    }

    // binds the data to the TextView in each row
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        String icons = stricon.get(position);
        String heads = strhead.get(position);
        int budgets = intbudget.get(position);
        int entries = intentry.get(position);
        int balances = intbalance.get(position);
        holder.btnIcon.setText(icons);
        holder.tvHead.setText(heads);
        holder.tvBudget.setText(String.valueOf(budgets));
        holder.tvEntry.setText(String.valueOf(entries));
        holder.tvBalance.setText(String.valueOf(balances));

    }

    // total number of rows
    @Override
    public int getItemCount() {
        return stricon.size();

    }


    // stores and recycles views as they are scrolled off screen
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public Button btnIcon;
        public TextView tvHead;
        public TextView tvBudget;
        public TextView tvEntry;
        public TextView tvBalance;
        public Button btnView;
        public Button btnAdd;
        ViewHolder(View itemView) {
            super(itemView);
            btnIcon= (Button) itemView.findViewById(R.id.idIcon);
            tvHead = (TextView) itemView.findViewById(R.id.idHead);
            tvBudget = (TextView) itemView.findViewById(R.id.idBudget);
            tvEntry = (TextView) itemView.findViewById(R.id.idEntry);
            tvBalance = (TextView) itemView.findViewById(R.id.idBalance);
            btnView= (Button) itemView.findViewById(R.id.idView);
            btnAdd = (Button) itemView.findViewById(R.id.idAdd);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
        }
    }

    // convenience method for getting data at click position
    String getItem(int id) {
        return stricon.get(id);


    }



    // parent activity will implement this method to respond to click events
    public interface ItemClickListener {
        void onItemClick(View view, int position);
    }
}

编辑后的新问题

我无法通过方法 datasnapshot 从 firebase 获取任何数据到我的数组列表。但是是的,如果我手动将核心文本或数字添加到我的列表中,我的回收站视图会显示数据。

这是崩溃报告

2021-05-24 00:07:12.368 19933-19933/com.myappname E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.myappname, PID: 19933
    java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at java.util.ArrayList.get(ArrayList.java:437)
        at com.myappname.model.rvAdapter.onBindViewHolder(mAdapter.java:54)
        at com.myappname.model.rvAdapter.onBindViewHolder(mAdapter.java:16)2021-05-24 .......................................

标签: javaandroidandroid-recyclerview

解决方案


从 firebase 获取数据后设置适配器

         myRef.addValueEventListener(new ValueEventListener() {
                            int sum = 0;
                            @Override
                            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
    
    
                                for (DataSnapshot data : dataSnapshot.getChildren()) {
                                    String section = data.child("stData2").getValue(String.class);
                                    String value = data.child("stData4").getValue(String.class);
                                    assert value != null;
                                    int total = 0;
    
                                    //==============
                                      sum=sum+total;
                                }
                                     enteriesData=sum;
//Send your data to adapter as per your need from here
          adapter = new madapter ( this, iconList,headList,budgetList,entryList,balanceList);
            userlist.setAdapter(adapter);
                            }

推荐阅读