I will suggest a solution to the problem of Fragment
but I have another suggestion to improve the way you update your list on ActivityList
.
From what I understand, you update the list whenever your Activity
That includes the call to onResume
resulting from the finalisation of ActivityNewItem
, but there is a negative effect in this form due to the life cycle of the Activity
. When your app goes into the background and comes back, you’ll go to BD
needlessly.
In the case of Fragment
there is no interference in the life cycle of the Activity
then the onResume
is not called. Nor is it good to call the notifyDataSetChanged
because at that moment the Fragment
will be displayed, and the user has not yet deleted the item, given the asynchronicity.
1. Updating the list after iteration with Quickviewfragment
In the method onListItemClick
, i would make a small change. Pass a Listener
for the Fragment (or leave the onAttach
set it), so that at the end of the interaction (update, delete, any other), it calls the method to update the list.
The ActionListener
in the code, is the form of communication (avoiding coupling) between the Fragment
and the Activity
. With the interface methods the Fragment
may notify the Activity
of the interactions made that require updating in the Activity
.
It would look something like:
Class ActivityList
:
public class ActivityList extends ListActivity implements QuickViewFragment.ActionListener {
// ... Codigo e mais codigo
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
ListItem item = (ListItem) l.getItemAtPosition(position);
FragmentManager fm = getFragmentManager();
QuickViewFragment quickView = QuickViewFragment.newInstance(item);
quickView.setActionListener(this);
// Sendo generico, pois nao sei que acoes poderiam ocorrer no fragment
quickView.show(fm, "tag_quick_view");
// Nao precisa do adapter.notifyDataSetChanged();
}
@Override
public void onDelete(Item item) {
atualizaLista(item);
// O metodo atualiza pode ser de duas formas:
// Ou ele remove o item da lista, sem ir no banco.
// Ou ele atualiza toda a lista, select no banco.
}
// Demais metodos da interface
}
Class QuickViewFragment
:
public class QuickViewFragment extends DialogFragment {
private ActionListener mAl;
@Override
public View onCreateView(...) {
// ...
}
public interface ActionListener {
public void onDelete(...);
public void onUpdate(...);
// ... O que mais quiser
}
private void ActionListener al; // Getter/Setter suprimidos
@Override
public void onAttach(Activity a) {
super.onAttach(a);
if(a instanceof ActionListener) {
mAl = (ActionListener) a;
}
// Apenas uma sugestão de uso, nao precisa ser assim...
}
@Override
public void onDismiss(DialogInterface dialog) {
if(al != null) {
//Chamar alguma acao do Listener
}
super.onDismiss(dialog);
}
@Override
public void onDestroyView(...) {
al = null; // Evitar MemoryLeak
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// ... Código
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// ... Mais Código
// Na configuracao do botao negativo (utilizar o ClickListener para chamar a Callback.
builder.setNegativeButton(R.string.quickview_delete,
new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Codigo de deleção no BD...
if(mAl != null) {
mAl.onDelete(...);
}
}
}
);
}
In the interface methods you would update your list.
The method onAttach
belongs to the life cycle of Fragment
, He is called when the Fragment
is "attached" to Activity
, before being added. I recommend reading the documentation on the life cycle of Fragment
.
Already the method onDismiss
is called when the Dialog
of DialogFragment
is being closed. Take a look at the documentation of the method DialogFragment.onDismiss(DialogInterface dialog)
.
2. Updating the list after return from Activitynewitem
When you call an Activity using Intent
, there is an alternative way that indicates that you are expecting a result of the return of ActivityNewItem
. The startActivityForResult (Intent intent, int requestCode)
, and to get the return you need to write the method onActivityResult (int requestCode, int resultCode, Intent data)
of his ListActivity
to know whether or not to update the list.
In the method onOptionsItemSelected
of ListActivity
I would make a small change:
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.menu_list_add) {
// activity responsável por adicionar novos itens
// ao banco de dados
Intent addItem = new Intent(this, ActivityNewItem.class);
startActivityForResult(addItem, 999, null); // Guarde o numero 999 pra depois
return true;
}
return super.onOptionsItemSelected(item);
}
And add this class method ListActivity
:
protected void onActivityResult(int requestCode /* 999 */, int resultCode, Intent data) {
if(requestCode == 999 && resultCode == RESULT_OK) {
// Atualiza lista, pois o retorno foi positivo...
}
super.onActivityResult(...);
}
In the ActivityNewItem
put something like:
@Override
public void finish() {
if(houveAlteracao) { // Se houve alguma atualizacao nessa `Activity`
setResult(RESULT_OK, dado);
// Diz para a Activity que me chamou
// Que houve uma alteracao de dados aqui...
}
super.finish();
}
I believe with this working, you don’t need to use the method onResume
to update the list, unless some external app modifies your BD
.
The answer was long, but I hope it helps...
This insertion of new items in another Activity, by chance could not be done adding new items in
Dialog Fragment
?– Lucas Santos
It is indifferent in the case. It is an application for personal use and does not need to be very complex. I created a new Activity for convenience, but it could perfectly be something similar to the way I’m using to view/delete items. But why the question?
– Renan Lazarotto
The why of the question is that if it is a simple item, for example a name, you could do so: a list Fragment that uses loaders. In this list you have a menu to add. If you click add opens a Fragment dialog asking for the name, you enter and the list is automatically updated due to you being using loaders. If you press an item, it displays a dialog giving you the option to edit and delete. It is also updated automatically due to the use of loaders. I find it so much simpler when the list is simple.
– Lucas Santos
The item in the case is a form, with 5 different fields. But how do loaders work? Have any reference link?
– Renan Lazarotto
I do, but it’s in English, it’ll do?
– Lucas Santos
Could be, no problem at all.
– Renan Lazarotto
[Official Documentation on Loaders][1] [Translated Website Documentation][2] [I learned from this website about loaders][3] [1]: http://developer.android.com/guide/components/loaders.html [2]: http://celeiroandroid.blogspot.com.br/2011/04/loaders.html [3]: http://www.androiddesignpatterns.com/2012/07/loaders-and-loadermanager-background.html
– Lucas Santos
One more thing, have preferences for Fragments, after that use and accustom you will not want anything else. I saw that you are using Listactivity.
– Lucas Santos
I thought it would be simpler to use a Listactivity instead of a Listfragment for reasons of the application being for personal use. In other projects, I use Listfragment more for the simplicity that Fragments brought.
– Renan Lazarotto