Anis Kaloun
Anis Kaloun

Reputation: 190

android-display data from database to listview and refresh it everytime

I am using a ListView inside my Fragment. I also have an EditText and a Button. So every time I click on my Button I take the content of my EditText how can I refresh my ListView every time I add a friend in my database without having to go into another Fragment and comeback.

Here is my fragment.

public class ContactFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_contact, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ListView list = getView().findViewById(R.id.contactframe);
        auth = FirebaseAuth.getInstance();
        final User user = new User();
        bouton = getView().findViewById(R.id.search_btn);
        email = getView().findViewById(R.id.search_field);
        bouton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!email.getText().toString().trim().equals(auth.getCurrentUser().getEmail().toString().trim())) {
                    user.addFriend(auth.getCurrentUser().getUid(), email.getText().toString().trim());
                    email.setText("");
                } else {
                    Toast.makeText(getActivity(), "Action refusé", Toast.LENGTH_LONG).show();
                }
            }
        });

        contactList = new ArrayList<User>();
        mDatabase = FirebaseDatabase.getInstance().getReference("User").child(auth.getCurrentUser().getUid().toString())
                .child("contact");
        mDatabase.addListenerForSingleValueEvent(valueEventListener);

        adaptor = new ContactAdaptor(getActivity(), contactList);
        list.setAdapter(adaptor);
    }

    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            contactList.clear();
            if (dataSnapshot.exists()) {
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    User ami = snapshot.getValue(User.class);
                    contactList.add(ami);
                }

                adaptor.notifyDataSetChanged();
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    };
}

And my Adapter

public class ContactAdaptor extends ArrayAdapter<User> {
    private LayoutInflater mInflater;
    ArrayList<User> myList;

    public ContactAdaptor(FragmentActivity activity, List<User> myList) {
        super(activity, 0, myList);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        User item = (User) getItem(position);
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_contact, parent, false);
        }

        TextView username = (TextView) convertView.findViewById(R.id.text_view_contact_username);
        TextView email = (TextView) convertView.findViewById(R.id.contact_email);
        username.setText(item.username);
        email.setText(item.email);

        return convertView;
    }
}

The layout file is

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- Editext for Search -->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/search_field"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="true"
            android:layout_marginStart="15dp"
            android:layout_marginTop="33dp"
            android:background="@drawable/search_layout"
            android:ems="10"
            android:hint="Chercher içi"
            android:inputType="textPersonName"
            android:paddingBottom="10dp"
            android:paddingLeft="20dp"
            android:paddingRight="20dp"
            android:paddingTop="10dp"
            android:textColor="#999999"
            android:textSize="16sp" />

        <Button
            android:id="@+id/search_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignTop="@+id/search_field"
            android:layout_marginEnd="60dp"
            android:text="Ajouter" />
    </RelativeLayout>

    <ListView
        android:id="@+id/contactframe"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="20dp"
        android:layout_marginRight="16dp"
        android:scrollbarSize="4dp"
        android:scrollbarThumbVertical="@drawable/scrollbar"
        android:scrollbars="vertical"
        tools:context="com.android.pfe.fragment.ContactFragment"></ListView>
</LinearLayout>

Upvotes: 1

Views: 49

Answers (1)

Reaz Murshed
Reaz Murshed

Reputation: 24211

You have used addListenerForSingleValueEvent which fetches the data for a single time and do not keep the underlying connection open to listen to any data change in firebase side.

You just have to use the addValueEventListener instead of addListenerForSingleValueEvent like the following.

mDatabase = FirebaseDatabase.getInstance().getReference("User").child(auth.getCurrentUser().getUid().toString())
            .child("contact");

// This is where you should use the addValueEventListener instead of addListenerForSingleValueEvent
mDatabase.addValueEventListener(valueEventListener);

I am copying the portion which is helpful here from the firebase documentation.

In some cases you may want a callback to be called once and then immediately removed, such as when initializing a UI element that you don't expect to change. You can use the addListenerForSingleValueEvent() method to simplify this scenario: it triggers once and then does not trigger again.

Hope that will fix your problem.

Upvotes: 1

Related Questions