2017-08-23 13 views
1

ユーザーが受け取ったフレンドリクエストを表示するためのカスタムListViewアダプタがあります。各行には、「受諾」ボタンがあります。ユーザーがそのボタンをクリックすると、データベースを更新しながらボタンをプログレスバーに置き換えます。このプロセスが完了したら、その行を削除します。ListViewカスタムアダプタ - 最後の行が欲しいものの代わりに削除される

まあ、これはほとんど起こります。

プログレスバーを表示するには、ボタンの表示を非表示に変更し、プログレスバーの表示を見えるように変更します。

行が正しく削除され、データベースがそれに応じて更新されます。問題は、notifyDataSetChangedメソッドを呼び出すと、削除された行だけが最後の行になります。ここで

私のコードスニペットの更新バージョン:https://www.youtube.com/watch?v=9JoJ3RuRwsY


EDIT:問題を示し

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

私はアクションで、この活動の動画を添付しています、最新の作業コード:

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

答えて

2

は、ここで私thinkは、アダプタが初期化されると同様にgetCountは2を返し、

するのは、次の2人のユーザーUSER1で始めましょうuser2の

を(アンドロイドスタジオ気圧にアクセスすることはできません)何が起こるかです。

getViewメソッドは、位置0のために1回、2回実行され、一度1

のためにこれは、あなたが受け入れる押すと

を 内USER1があり、view2-> vh2-> user2がviewholderのVH1を持つ二つのビューのVIEW1を作成しますあなたのコードと設定VIEW1の可視性

を実行しますGETCOUNT方法は、1

を返します

全体のアダプターを無効にしているnotifydatasetchanged呼び出します

GetViewメソッドは、位置0のために初期化されますが、初期化ビュー引数(VIEW1)で開始します引数はそのビューの可視性は何が起こるか

をuser1にプログレスバーを表示すると参照して設定した

:GETCOUNTこれは私 thinkが働くべきである1

を返されたので、それが不要になったため、USER1がデータベースから削除されませんが、それはまだVIEW1のviewholder内に存在する、とVIEW2が配置されていることです0

最初のあなたはインスタンス変数を宣言します。その後、

User _working_user = null; 

@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.acceptBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       acceptRequest(view); 
      } 
     }); 

     view.setTag(holder); 
    } else 
     holder = (ViewHolder) view.getTag(); 

    holder.user = (User) getItem(position); 
    holder.userEmail_TextView.setText(holder.user.getEmail()); 
    holder.name_TextView.setText(holder.user.getName()); 
    holder.acceptBtn.setTag(holder); //not a big fan of this btw, seems to be a cyclic reference 

    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 vh = (ViewHolder) acceptButtonView.getTag(); 

     _working_user = vh.user; 

     vh.acceptProgressBar.setVisibility(View.VISIBLE); 
     vh.acceptBtn.setVisibility(View.INVISIBLE); 
     //thew above two lines could be replaced with a notifyDataSetChanged 


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

今以上のいくつかの注意事項に

を動作しますが、ここにあるはずです何か他のものが呼び出す可能性がありますので、私たちは_working_userを使用しますNotifyDataSetChanged()はデータベースの実行中に何も実行されませんが、理論上は必要ありません。

私は本当にありませんonclickハンドラがビューを渡すように、個人的な好みを呼び出すことができます。if(view == null)ブロック内でクリックハンドラを宣言し、ビューの所有者のユーザオブジェクトで引数を受け入れるようにします。

+0

詳細な回答をいただきありがとうございます。問題を修正しました! –

関連する問題