What is the best way to refresh a list using Firebase

Jurdun :

How I'm currently updating my lists in my project clearly isn't the standard for apps. How do would I refresh the list without clearing it?

This code writes just fine, without any interruptions; however, once the user has finished editing, the list is cleared and refreshed, returning the user to the top of the list. What is best practice when it comes to refreshing data, especially if the data is being edited by another user without interrupting the current user.

Writing:

protected void addStep() {
String stepID = Database.push().getKey();
step newStep = new step(recipeID, stepID, "stepImage", "","");
Database.child(stepID).setValue(newStep);
getData();

}

Adapter:

package asdasd.asd;

import android.app.Activity;
import android.support.annotation.NonNull;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * This class is the class responsible for handling the lists of steps that the user will see during the creator phase.
 * It works by setting an array adapter which uses the fragment_steps layout displaying it on a list within the StepActivity
 * On text listeners are on each of the fields, when the user edits one of the fields, the program waits 600ms, and then uploads the
 * data to the database;
 * this refreshes the list TODO change the way the list refreshes in the instance of the creator; perhaps add a delay of 1 minuite before refresh, and or if a new step has been added
 * A timer is responsible for this delay. The setting of data is to a specific path; being the recipe -> step -> long/shortText field.
 */

public class stepList extends ArrayAdapter<step>{
    private Activity context;
    private List<step> steps;
    private DatabaseReference database;
    private Timer timer1,timer2;

    public stepList(Activity context, List<step> steps) {
        super(context, R.layout.fragment_step, steps);
        this.context = context;
        this.steps = steps;
    }

    @NonNull
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        //get database
        database = FirebaseDatabase.getInstance().getReference("steps");

        //init Layout inflater
        LayoutInflater inflater = context.getLayoutInflater();

        //step
        View listViewItem = inflater.inflate(R.layout.fragment_step,null,true);

        //step objects
        final TextView descriptionText = (TextView) listViewItem.findViewById(R.id.stepRecipeShortText);
        final TextView longDescriptionText = (TextView) listViewItem.findViewById(R.id.stepRecipeLongText);
        ImageView stepImage = listViewItem.findViewById(R.id.stepImage);
        //init step
        final step step = steps.get(position);

        //get stepID
        final String stepID = step.getStepID();

        //Set Data
        descriptionText.setText(step.getStepDescription());
        longDescriptionText.setText(step.getStepLongDescription());

        //TODO If user has uploaded an image, then use that, else then use default

        //Add listener to descriptionText so that when a user edits the fields, it is uploaded to the same step in the database
        descriptionText.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // user is typing: reset already started timer (if existing)
                if (timer1 != null) {
                    timer1.cancel();
                }
            }
            @Override
            public void afterTextChanged(Editable s) {
                timer1 = new Timer();
                timer1.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        String newDescriptionText = descriptionText.getText().toString();
                        addToDatabase(stepID,"stepDescription", newDescriptionText);
                    }
                }, 600);
            }
        });
        //Add listener to LongDescriptionText so that when a user edits the fields, it is uploaded to the same step in the database
        longDescriptionText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // user is typing: reset already started timer (if existing)
                if (timer2 != null) {
                    timer2.cancel();
                }
            }
            @Override
            public void afterTextChanged(Editable s) {
                timer2 = new Timer();
                timer2.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        String newLongDescriptionText = longDescriptionText.getText().toString();
                        addToDatabase(stepID, "stepLongDescription", newLongDescriptionText);
                    }
                }, 600);
            }
        });
        return listViewItem;
    }
    //Add the data the user is entering to the database; there is a 600ms delay on the period between the user stopping typing and the data being updated.
    private void addToDatabase(String id, String location, String text) {
        database.child(id).child(location).setValue(text);
    }
}

Getting:

public void getData() {
        //receives all the recipes and adds them to the list
        Database.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                //Clear the list
                listStepsList.clear();
                //Iterate through the nodes
                for(DataSnapshot stepSnapshot : dataSnapshot.getChildren()){
                    //get recipe
                    step step = stepSnapshot.getValue(step.class);
                    //add step to list, if it is apart of the same recipe.
                    if(step.getRecipeID().equals(recipeID)) {
                        listStepsList.add(step);
                    }
                }
                //create Adapter
                stepList stepAdapter = new stepList(StepActivity.this, listStepsList);
                //Attatch adapter to listview
                viewStepsList.setAdapter(stepAdapter);
                stepAdapter.notifyDataSetChanged();
            }
            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }
Frank van Puffelen :

I assume you're seeing a "big bang"/flash whenever there's a change in the database. If so, that is because you're updating the entire list, even if only a single item in the data was changed.

To improve this, you'll want to more granularly update the adapter for changes. To do so, you can attach a ChildEventListener, which fires events at one level lower in your data structure. So say a new node is added to your list, instead of rebuilding the entire list to add the one node, you'd get a single onChildAdded call with just the one new node. You'd then update listStepsList instead of rebuilding it, and tell the adapter about the changes.

For an example of this, I recommend checking out FirebaseUI, as the adapters in there all use this pattern. They build from a common FirebaseArray class that observes the database, and then have adapter classes to glue to array to the UI. For example, here's how FirebaseRecyclerAdapter connects the changes in the database to minimal updates to the view.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

What is the best way to refresh a page?

What is the best way to add data to a list in Firebase Realtime Database

What’s the best way to reload / refresh an iframe?

Best way to refresh a list with events in WebView

What is the best way of using Arrays.asList() to initialize a List

What is the best way to get the list of column names using CsvHelper?

What's the best way to organize a display list using AS3?

What is the best way to parameterize a pytest function using a fixture that returns a list?

What is the best way to print position of items in the list of strings using python

What is the best way to center list items using bootstrap?

What is the best way to set the followers list using parse.com

What is the best way to categorize/group and sort a list of elements using javascript?

What is the best way to trim a list?

What is the best way to copy a list?

What's the best way to prime/refresh a url in varnish 4 using a single http request?

What's the best way of structuring data on firebase?

Best way to add data to a list in firebase database

What's the Best Way to Get a "Pull to Refresh" from a UITableView?

What is the best way to use PeriodicTimer for refresh component in blazor server

what is the best way to iterate a list and exit in java

What is the best way to check if a variable is a list?

What is the best way to remove objects from a List

What is the best way to iterate over list

What is the best way to compare images in a bitmap list

What's the best way to list size of / in Terminal?

What is the best way of object list casting

What is the best way to pass a list of functions as argument?

What is the best way of modifying and replacing list elements?

What is the best way to store a list of dates