0

I'm developing a feed app, where people can make posts and these posts will populate a RecyclerView.

I have a FAB button that leads to a post activity, but when I post and then comeback to the MainActivity the list is not updated. But when I use the logout button and log back in, the list gets updated, or when I launch the activity it works.

I think this happens because my Async function gets called to work on onCreate, but I can't work like these, I need the AsyncTask to automatically fetch, otherwise people won't get the list updated in real time.

Could you please show me a light in the dark? Here are the codes for MainActivity, PostActivity and logout function from another class.


Main Activity:

public class MainActivity extends AppCompatActivity {

private AppCompatActivity activity = MainActivity.this;
private RecyclerView recyclerViewNews;
private List<Noticia> listNoticias;
private NewsRecyclerAdapter newsRecyclerAdapter;
private DBNoticias databaseHelper;
private Button btnLogout;
private LinearLayoutManager mLayoutManager;
UserSession userSession;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    userSession = new UserSession(getApplicationContext());

    recyclerViewNews = findViewById(R.id.recyclerViewNews);
    btnLogout = findViewById(R.id.btlogout);

    TextView usuario = findViewById(R.id.textView5);


    /**
     * Olá mundo by Alciomar
     */
    SharedPreferences sharedPreferences = getSharedPreferences("Reg", Context.MODE_PRIVATE);
    String  uName = sharedPreferences.getString("Name", "");
    usuario.setText(uName.toUpperCase());


    try {
        btnLogout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                userSession.logoutUser();
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }

    initStuff();
    getDataFromPostgres();

    FloatingActionButton fab = findViewById(R.id.fabNews);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(MainActivity.this, PostNews.class);
            startActivity(intent);
        }
    });

}


/**
 * This method is to initialize objects to be used
 */
private void initStuff() {

    try {
        listNoticias = new ArrayList<>();
        newsRecyclerAdapter = new NewsRecyclerAdapter(listNoticias);

        mLayoutManager = new LinearLayoutManager(getApplicationContext());
        mLayoutManager.setReverseLayout(true);
        mLayoutManager.setStackFromEnd(true);
        recyclerViewNews.setLayoutManager(mLayoutManager);
        recyclerViewNews.setItemAnimator(new DefaultItemAnimator());
        recyclerViewNews.setHasFixedSize(true);
        recyclerViewNews.setAdapter(newsRecyclerAdapter);
        databaseHelper = new DBNoticias(activity);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

/**
 * This method is to fetch all user records from SQLite
 */
private void getDataFromPostgres() {
    // AsyncTask is used that SQLite operation not blocks the UI Thread.
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            listNoticias.clear();
            for (DBNoticias dbNoticias : databaseHelper.getNewsList()) {
                Noticia noticia = new Noticia();
                noticia.setUser_id(dbNoticias.getId());
                noticia.setNewsTitle(dbNoticias.getNewsTitle());
                noticia.setNewsMessage(dbNoticias.getNewsPost());

                listNoticias.add(noticia);
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            newsRecyclerAdapter.notifyDataSetChanged();
        }
    }.execute();
}

Post News Activity:

public class PostNews extends AppCompatActivity {

private DBNoticias dbNoticias;
private Button btnpostar;
private EditText editTextCDNewsTitle;
private EditText editTextCDNewsPost;
private Noticia noticia;
private SharedPreferences sharedPreferences;

public void alert(String titulo, String txt){
    AlertDialog alertDialog = new AlertDialog.Builder(PostNews.this).create();
    alertDialog.setTitle(titulo);
    alertDialog.setMessage(txt);
    alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
    alertDialog.show();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_post_news);

    btnpostar = findViewById(R.id.btn_postar);
    dbNoticias = new DBNoticias();

    editTextCDNewsTitle = findViewById(R.id.EditTextNewsTitle);
    editTextCDNewsPost = findViewById(R.id.EditTextNewsPost);

}

public void salvarNoticia(View view) {
    try {
        {
            String newsTitle = editTextCDNewsTitle.getText().toString();
            String newsPost = editTextCDNewsPost.getText().toString();

            if (!(editTextCDNewsTitle.getText().toString().equals("") || editTextCDNewsTitle.getText() == null ||
                    editTextCDNewsPost.getText().toString().equals("") || editTextCDNewsPost.getText() == null

            )) {

                sharedPreferences = getSharedPreferences("Reg", Context.MODE_PRIVATE);
               String  uName = sharedPreferences.getString("Name", "");
               String uEmail = sharedPreferences.getString("Email", "");
               int  uIdUser = sharedPreferences.getInt("IdUser", 0);

                dbNoticias.setNewsTitle(newsTitle);
                dbNoticias.setNewsPost(newsPost);
                dbNoticias.setIdUser(uIdUser);


                dbNoticias.salvar();

                noticia = new Noticia();


                Toast.makeText(getApplicationContext(), "Notícia postada com sucesso",
                        Toast.LENGTH_LONG).show();

                editTextCDNewsTitle.setText("");
                editTextCDNewsPost.setText("");
            }

        }
    }
    catch (Exception e){
        alert("Erro", e.getMessage());
    }
}

Thank you in advance if you read and try to help!

Sheharyar
  • 73,588
  • 21
  • 168
  • 215
MvD
  • 37
  • 11
  • You can call the AsyncTask in your `onResume()` method instead of `onCreate()`. – SripadRaj Mar 08 '18 at 12:08
  • use startActivityForResult() for your feeds activity and in onActivityResult() call the asynctask – Akshay Mar 08 '18 at 12:13
  • Your code looks ok but since you are calling `getDataFromPostgres()` from `onCreate()` the method will only get called when the activity is recreated or re-launched. I will suggest you to read this https://developer.android.com/guide/components/activities/activity-lifecycle.html. – Sunil Sunny Mar 08 '18 at 12:16
  • Thank you all for the help. I got the list to work, just need to fix the scroll to top on item added. – MvD Mar 08 '18 at 12:59

2 Answers2

0

Please use this, it's working for me

 newsRecyclerAdapter.notifyItemInserted(position);
 newsRecyclerAdapter.notifyDataSetChanged();
Akshay
  • 318
  • 1
  • 15
0

There are multiple ways to do this:


Method 1 – Use onResume()

If you call your getDataFromPostgres() method in onResume instead of onCreate, it'll fetch data and refresh list every time the activity wakes from a pause (for example coming back from another activity)

// existing code

@Override
public void onResume(){
    super.onResume();
    getDataFromPostgres()
}

(This would be the simplest solution)


Method 2 – Poll the DB continuously

If there are other services that might be updating the database and you need to always show the latest state in the activity, another way (although really inefficient) would be to keep refreshing the list after a defined time period (let's say 10 seconds as an example).

How to run an async task for every x mins in android?


Method 3 – Use onActivityResult

If you want to update the list only when a new entry has been created in the second activity, you can use onActivityResult to notify the first activity on action and then refresh your list there.

How to manage `startActivityForResult` on Android?

Sheharyar
  • 73,588
  • 21
  • 168
  • 215
  • The onResume works, but it won't show the recent item on top of the list, I have to scroll the ReciclerView up to see the most recently entry. I think this can be solved used the onActivityResult. Do you agree? – MvD Mar 08 '18 at 12:42
  • Scrolling is a separate issue from this, and it'll be the same case for `onActivityResult` too. You'll need to check if new items were added to the list and manually scroll to the top (if the list scroll state was already at 0). – Sheharyar Mar 08 '18 at 12:44
  • Should I do this on Async onPostExecute? – MvD Mar 08 '18 at 12:47
  • Yes. Also see this: https://stackoverflow.com/questions/41655486/android-recyclerview-scroll-to-top – Sheharyar Mar 08 '18 at 12:49
  • Thank you so much for the help, I'll go on my own from here – MvD Mar 08 '18 at 12:54