ListView自定义适配器 - 最后一行被删除而不是被通缉的

时间:2017-08-23 19:59:57

标签: android listview firebase listview-adapter

我有一个自定义ListView适配器,用于显示用户收到的好友请求。对于每一行,都有一个“接受”按钮。当用户点击该按钮时,我在更新数据库时用进度条替换该按钮。完成此过程后,我想删除该行。

嗯,这几乎就是这样。

为了显示进度条,我将按钮的可见性更改为不可见,并且可以看到进度条的可见性。

正确删除行,数据库会相应更新。问题是,在我调用notifyDataSetChanged方法后,唯一删除的行是最后一行。

这是我的代码段的更新版本:

    public class FriendRequestsReceived_UserListAdapter extends GeneralListAdapter {

        private List<User> friendRequestsReceived_UserList;

        public FriendRequestsReceived_UserListAdapter(Context context, int resource, List<User> items) {
            super(context, resource, items);
            this.friendRequestsReceived_UserList=items;
        }

        private class ViewHolder {
            TextView userEmail_TextView;
            TextView name_TextView;
            Button acceptBtn;
            ProgressBar acceptProgressBar;
            User user;
        }

        @Override
        public View getView(int position, View view, ViewGroup parent) {
            ViewHolder holder;
            LayoutInflater inflater = LayoutInflater.from(getContext());

            if (view == null) {
                view = inflater.inflate(R.layout.friend_requests_received_listview_row, parent, false);

                holder = new ViewHolder();
                holder.userEmail_TextView = (TextView) view.findViewById(R.id.user_email);
                holder.name_TextView = (TextView) view.findViewById(R.id.user_name);
                holder.acceptBtn = (Button) view.findViewById(R.id.acceptRequestBtn);
                holder.acceptProgressBar = (ProgressBar) view.findViewById(R.id.acceptProgressBar);
                holder.user = (User) getItem(position);
                view.setTag(holder);
            } else
                holder = (ViewHolder) view.getTag();


            if (holder.user!=null) {
                holder.userEmail_TextView.setText(holder.user.getEmail());
                holder.name_TextView.setText(holder.user.getName());
                holder.acceptBtn.setTag(holder);
                holder.acceptBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        acceptRequest(view);
                    }
                });
            }
            return view;
        }

        private void acceptRequest(View acceptButtonView){
            final ViewHolder vh = (ViewHolder) acceptButtonView.getTag();

            vh.acceptProgressBar.setVisibility(View.VISIBLE);
            vh.acceptBtn.setVisibility(View.INVISIBLE);

//Some code for updating database's related variables...

            mDatabase.updateChildren(dataForDatabase, new DatabaseReference.CompletionListener() {
                @Override
                public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                    if (databaseError != null) showConnectionErrorToast();
                    else {
                        Toast.makeText(getContext(), "Success", Toast.LENGTH_SHORT).show();
                        friendRequestsReceived_UserList.remove(vh.user);
                        notifyDataSetChanged();
                    }
                }
            });
        }
    }

我正在附加此活动的视频,以显示问题:https://www.youtube.com/watch?v=9JoJ3RuRwsY

编辑:最新且有效的代码:

public class FriendRequestsReceived_UserListAdapter extends GeneralListAdapter {

    private String loggedUser;
    private ConnectivityManager cm;
    private List<User> friendRequestsReceived_UserList;

    User working_user = null;

    public FriendRequestsReceived_UserListAdapter(Context context, int resource, List<User> items) {
        super(context, resource, items);
        this.friendRequestsReceived_UserList=items;
    }

    private class ViewHolder {
        Button acceptBtn;
        ProgressBar acceptProgressBar;
        User user;
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        LayoutInflater vi = LayoutInflater.from(getContext());

        view = vi.inflate(R.layout.friend_requests_received_listview_row, null);
        final ViewHolder holder = new ViewHolder();
        TextView userEmail_TextView = (TextView) view.findViewById(R.id.user_email);
        TextView name_TextView = (TextView) view.findViewById(R.id.user_name);
        Button acceptBtn = (Button) view.findViewById(R.id.acceptRequestBtn);
        ProgressBar acceptProgressBar = (ProgressBar) view.findViewById(R.id.acceptProgressBar);
        User myUser = (User) getItem(position);

        holder.acceptBtn=acceptBtn;
        holder.acceptProgressBar=acceptProgressBar;
        holder.user=myUser;

        acceptBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                acceptRequest(view, holder);
            }
        });


        userEmail_TextView.setText(myUser.getEmail());
        name_TextView.setText(myUser.getName());


        if (holder.user == working_user) {
            holder.acceptProgressBar.setVisibility(View.VISIBLE);
            holder.acceptBtn.setVisibility(View.INVISIBLE);
        }
        else {
            holder.acceptProgressBar.setVisibility(View.INVISIBLE);
            holder.acceptBtn.setVisibility(View.VISIBLE);
        }
        return view;
    }

    private void acceptRequest(View acceptButtonView, final ViewHolder holder){
        Context context=getContext();
        working_user = holder.user;

        holder.acceptProgressBar.setVisibility(View.VISIBLE);
        holder.acceptBtn.setVisibility(View.INVISIBLE);

        loggedUser=SaveSharedPreference.getLoggedEmail(context);
        final DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();

        final String senderEmail=holder.user.getEmail();

        cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        if (cm.getActiveNetworkInfo()!=null) {
            mDatabase.child("Users").child(loggedUser).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    if (dataSnapshot.exists()){
                        mDatabase.child("Users").child(senderEmail).addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                                if (dataSnapshot.exists()){

                                    Map data = new HashMap();
                                    data.put("Users/"+loggedUser+"/friend_requests_received/"+senderEmail, null);
                                    data.put("Users/"+loggedUser+"/friends_list/"+senderEmail,true);

                                    mDatabase.updateChildren(data, new DatabaseReference.CompletionListener() {
                                        @Override
                                        public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                                            if (databaseError!=null)
                                                showConnectionErrorToast();

                                            else {//Success
                                                Context context=getContext();
                                                Toast.makeText(context,
                                                        "Success", Toast.LENGTH_SHORT).show();
                                                friendRequestsReceived_UserList.remove(holder.user);
                                                notifyDataSetChanged();

                                            }
                                        }
                                    });

                                }
                                else {
                                    showConnectionErrorToast();
                                }
                            }

                            @Override
                            public void onCancelled(DatabaseError databaseError) {
                                showConnectionErrorToast();
                            }
                        });
                    }
                    else {
                        showConnectionErrorToast();
                    }
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    showConnectionErrorToast();
                }
            });
        }
        else {
            showConnectionErrorToast();
        }
    }

1 个答案:

答案 0 :(得分:2)

这是我 p1 <- df[[1]] %>% group_by(type) %>% plot_ly(x=~factor(Index), y = ~value, color = ~type, colors = c("#132B43", "#56B1F7"), type = 'scatter', mode = 'lines') p2 <- df[[2]] %>% group_by(type) %>% plot_ly(x=~factor(Index), y = ~value, color = ~type, colors = c("#132B43", "#56B1F7"), type = 'scatter', mode = 'lines', showlegend = F) p3 <- df[[3]] %>% group_by(type) %>% plot_ly(x=~factor(Index), y = ~value, color = ~type, colors = c("#132B43", "#56B1F7"), type = 'scatter', mode = 'lines', showlegend = F) subplot(p1,p2,p3,nrows=1,titleY = TRUE, shareX = TRUE, margin = c(0.085,0.01,0.1,0.1)) 发生的事情(无法访问android studio atm)

假设您从两个用户user1,user2

开始

当适配器初始化时,getCount返回2;

GetView运行两次,一次用于位置0,一次用于一次

这会创建两个视图view1,其中包含view1 vh1,其中包含user1 和view2-&gt; vh2-&gt; user2

当您按下接受时,您运行代码并设置view1的可见性

然后你调用notifydatasetchanged使整个适配器无效

getcount方法将返回1

getview方法将初始化为位置0,但将以View参数初始化(view1)开始

该参数的视图可见性设置为显示进度条并引用user1

会发生什么情况是user1从数据库中删除但它仍然存在于view1的viewholder中,并且因为getcount返回1而不再需要view2而放置了view2

这是我think应该工作的地方:

首先声明一个实例变量:

think

然后

User _working_user = null;

现在上面应该可以了,但是这里有一些注意事项

我们使用_working_user,因为当数据库内容执行时,有其他东西会调用NotifyDataSetChanged(),如果没有,理论上它不应该被需要

我真的不喜欢onclick处理程序传递视图的事实,你可以调用它的个人偏好,我要做的是在if(view == null)块中声明click处理程序,然后调用accept视图持有者的用户对象

的参数