Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
217 views
in Technique[技术] by (71.8m points)

android - Update ListView in Master/Detail after a form is saved

I have implemented a master detail as follow:

enter image description here

In the left I have a FragmentList and in the right I have a form related to the items of the list. When I press the save button, I need to update the list (in this case if the name is updated, the list has to be updated as well).

When the app is in landscape I show the master/detail, if not I show only the list and when a name is pressed, I create a new activity.

My problem here is that I couldn't update the list when the save button is pressed. The notifyDataSetChanged is not working.

By the other hand, I'm using tabs so I have a main Activity that contains the listFragment and inside the ListFragment I have a fragment.

listFragment:

public class ListWordFragment extends SherlockListFragment {

private ListWordAdapter adapter;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_list_words, null);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    setHasOptionsMenu(true);

    ListView list = getListView();

    pullToRefreshAttacher = ((MainActivity) getActivity()).getAttacher();
    pullToRefreshAttacher.addRefreshableView(list, this);

    // Cargamos la lista de palabras
    WordDAO wordsDao = new WordSqliteDAO();
    Cursor mCursorWords = wordsDao.list(getSherlockActivity());

    if (mCursorWords.getCount() > 0) {
        String[] from = new String[] { Word.NAME, Word.TYPE, Word.TRANSLATE };
        int[] to = new int[] { R.id.textView_word, R.id.textView_type,
                R.id.textView_translate };

        adapter = new ListWordAdapter(
                getSherlockActivity(), R.layout.row_list_words,
                mCursorWords, from, to, 0);
        setListAdapter(adapter);
        list.setItemChecked(0, true);
        fillRow(list,0);
    }
}


@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    fillRow(l, position);

}

private void fillRow(ListView l, int position) {
    Cursor cursor = (Cursor) l.getItemAtPosition(position);
    String id = cursor.getString(cursor.getColumnIndex(Word.ID));
    String name = cursor.getString(cursor.getColumnIndex(Word.NAME));
    String type = cursor.getString(cursor.getColumnIndex(Word.TYPE));
    String translate = cursor.getString(cursor.getColumnIndex(Word.TRANSLATE));
    String example = cursor.getString(cursor.getColumnIndex(Word.EXAMPLE));
    String note = cursor.getString(cursor.getColumnIndex(Word.NOTE));

    if ((getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) 
            && (getResources().getString(R.string.selected_configuration).equals(Constants.CONFIGURATION_LARGE))) {

        WordDetailFragment frag = (WordDetailFragment) getFragmentManager()
                .findFragmentById(R.id.word_detail_fragment);

        if(frag!=null){
            frag.setId(id);
            frag.setName(name);
            frag.setType(type);
            frag.setTranslate(translate);
            frag.setExample(example);
            frag.setNote(note);
        }

    } else {

        Intent i = new Intent(getActivity().getApplicationContext(),
                WordDetailActivity.class);

        i.putExtra(Word.ID, id);
        i.putExtra(Word.NAME, name);
        i.putExtra(Word.TYPE, type);
        i.putExtra(Word.TRANSLATE, translate);
        i.putExtra(Word.EXAMPLE, example);
        i.putExtra(Word.NOTE, note);

        startActivity(i);
    }
}


   //THIS METHOD IS CALLED FROM THE MAIN ACTIVITY
public void onWordSaved() {
    WordDAO wordsDao = new WordSqliteDAO();
    Cursor mCursorWords = wordsDao.list(getSherlockActivity());
    adapter.swapCursor(mCursorWords);
    adapter.notifyDataSetChanged();
}

}

WordDetailFragment:

public class WordDetailFragment extends Fragment {

    //THIS IS FOR THE COMUNNICATION WITH THE MAIN ACTIVITY
OnWordSavedListener mCallback;

    // Container Activity must implement this interface
    public interface OnWordSavedListener {
        public void onWordSaved();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnWordSavedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnWordSavedListener");
        }
    }

private EditText editTxt_id;
private EditText editTxt_name;
private EditText editTxt_type;
private EditText editTxt_translate;
private EditText editTxt_example;
private EditText editTxt_note;
private Button bttn_save;

public void setId(String id) {
    if(id!=null){
        editTxt_id.setText(id);
    }
}

public void setName(String name) {
    if(name!=null){
        editTxt_name.setText(name);
    }
}

public void setType(String type) {
    if(type!=null){
        editTxt_type.setText(type);
    }
}

public void setExample(String example) {
    if(example!=null){
        editTxt_example.setText(example);
    }
}


public void setTranslate(String translate) {
    if(translate!=null){
        editTxt_translate.setText(translate);
    }
}

public void setNote(String note) {
    if(note!=null){
        editTxt_note.setText(note);
    }
}


@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    final Bundle arguments = getArguments();

    if(arguments != null){

        final String id = arguments.getString(Word.ID);
        setId(id);

        final String name = arguments.getString(Word.NAME);
        setName(name);

        final String type = arguments.getString(Word.TYPE);
        setType(type);

        final String translate = arguments.getString(Word.TRANSLATE);
        setTranslate(translate);

        final String example = arguments.getString(Word.EXAMPLE);
        setExample(example);

        final String note = arguments.getString(Word.NOTE);
        setNote(note);

    }

    bttn_save.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            boolean error = false;
            Toast toast;

            String id = editTxt_id.getText().toString();
            String name = editTxt_name.getText().toString();
            String type = editTxt_type.getText().toString();
            String translate = editTxt_translate.getText().toString();
            String example = editTxt_example.getText().toString();
            String note = editTxt_note.getText().toString();

            // Verificacion de errores
            if(name.equals("") || name==null){
                editTxt_name.setError(getResources().getString(R.string.error_blank_field));
                error = true;
            }

            if(type.equals("") || type==null){
                editTxt_type.setError(getResources().getString(R.string.error_blank_field));
                error = true;
            }

            if(translate.equals("") || translate==null){
                editTxt_translate.setError(getResources().getString(R.string.error_blank_field));
                error = true;
            }

            // FIN  Verificacion de errores 

            if(!error){

                WordDAO wordDao = new WordSqliteDAO();


                if(id!=null && !id.equals("")){

                    Date updated_at = new Date();
                    Word word = new Word(id, name, type, translate, example, note, updated_at);

                    Boolean modificado = wordDao.update(getActivity(), word);

                    if(modificado){
                        toast = Toast.makeText(getActivity(), getResources().getString(R.string.ok_word_updated), Toast.LENGTH_SHORT);
                        toast.show();
                        mCallback.onWordSaved();

                    }else{
                        toast = Toast.makeText(getActivity(), getResources().getString(R.string.error_word_updated), Toast.LENGTH_SHORT);
                        toast.show();
                    }

                }else{

                    Word word = new Word(name, type, translate, example, note);
                    String idRowInserted = wordDao.insert(getActivity(), word);

                    if(idRowInserted.equals("-1")==false){
                        toast = Toast.makeText(getActivity(), getResources().getString(R.string.ok_word_inserted), Toast.LENGTH_SHORT);
                        toast.show();
                        mCallback.onWordSaved();

                    }else{
                        toast = Toast.makeText(getActivity(), getResources().getString(R.string.error_word_inserted), Toast.LENGTH_SHORT);
                        toast.show();
                    }

                    id = idRowInserted;
                }


            }else{
                toast = Toast.makeText(getActivity(), getResources().getString(R.string.error_form), Toast.LENGTH_SHORT);
                toast.show();
            }
        }
    });
}

}

MAIN ACTIVITY:

public class MainActivity extends SherlockFragmentActivity implements
        ViewPager.OnPageChangeListener, TabListener, OnWordSavedListener {


    private ActionBar action_bar;
    private ViewPager view_pager;
    private CustomPagerAdapter adapter;
    private PullToRefreshAttacher pullToRefreshAttacher;

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



        adapter = new CustomPagerAdapter(getSupportFragmentManager());
        view_pager = (ViewPager) findViewById(R.id.pager);
        view_pager.setAdapter(adapter);
        view_pager.setOnPageChangeListener(this);

        action_bar = getSupportActionBar();
        action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        action_bar.removeAllTabs();
        action_bar.addTab(action_bar.newTab().setText(R.string.list_words)
                .setTabListener(this));
        action_bar.addTab(action_bar.newTab().setText(R.string.list_idioms)
                .setTabListener(this));

    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        view_pager.setCurrentItem(tab.getPosition());

    }


    @Override
    public void onPageSelected(int position) {
        action_bar.setSelectedNavigationItem(position);

    }

    public PullToRefreshAttacher getAttacher() {
        return pullToRefreshAttacher;
    }

    //HERE WHE NOTIFY THE LISTFRAGMENT THAT THE SAVE BUTTON WAS PUSHED
    @Override
    public void onWordSaved() {
        int index = view_pager.getCurrentItem();

        Fragment currentFragment = adapter.getItem(index);

        if (currentFragment instanceof ListWordFragment) {
            ListWordFragment frag = (ListWordFragment) currentFragment;
            frag.onWordSaved();

        }

    }

}

EDIT:

If I change my custom cursor adapter to SimpleCursorAdapter, it works fine. WHY?!?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It looks like you are updating the content that is backing the cursor, but registering a DataSetObserver which is for when the cursors themselves have been directly updated (like if you had added a row to an ArrayAdapter directly.

Since you are update the DAO with inserts, it seems like you should be registering a DataContentObserver so the cursor will be updated from it's data source.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...