Android 使用searchview发布结果时未更新ListView

Android 使用searchview发布结果时未更新ListView,android,android-listview,searchview,Android,Android Listview,Searchview,我一直在编写一个android应用程序,它使用SearchView在我的数据库中搜索,我能够搜索注释,当我在结果数组列表上执行Log.e()时,我会看到正确的结果,但是应该更改以显示搜索结果的listview不会受到影响。我正在使用自定义适配器。我只是不知道publishResults方法中的结果如何实时修改我的listview MainActivity.java public class MainActivity extends RoboActionBarActivity { pri

我一直在编写一个android应用程序,它使用SearchView在我的数据库中搜索,我能够搜索注释,当我在结果数组列表上执行Log.e()时,我会看到正确的结果,但是应该更改以显示搜索结果的listview不会受到影响。我正在使用自定义适配器。我只是不知道
publishResults
方法中的结果如何实时修改我的
listview

MainActivity.java

public class MainActivity extends RoboActionBarActivity {

    private static final int NEW_NOTE_RESULT_CODE = 4;
    private static final int EDIT_NOTE_RESULT_CODE = 5;

    @InjectView(android.R.id.empty)   private TextView emptyListTextView;
    @InjectView(android.R.id.list)    private ListView listView;
    @InjectView(R.id.add_note_button) private FloatingActionButton addNoteButton;

    @Inject private NoteDAO noteDAO;

    private ArrayList<Integer> selectedPositions;
    private ArrayList<NotesAdapter.NoteViewWrapper> notesData;
    private NotesAdapter listAdapter;
    private ActionMode.Callback actionModeCallback;
    private ActionMode actionMode;

    /** {@inheritDoc} */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Inicializa los componentes //////////////////////////////////////////////////////////////
        listView.setOnTouchListener(new ShowHideOnScroll(addNoteButton, getSupportActionBar())); // Esconde o muesta el FAB y la Action Bar
        addNoteButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                // Crear una nota nueva
                startActivityForResult(EditNoteActivity.buildIntent(MainActivity.this), NEW_NOTE_RESULT_CODE);
            }
        });
        selectedPositions = new ArrayList<>();
        listView.setTextFilterEnabled(true);
        setupNotesAdapter();
        setupActionModeCallback();
        setListOnItemClickListenersWhenNoActionMode();
        updateView();
    }

    /** {@inheritDoc} */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);

    // Get the SearchView and set the searchable configuration
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
    // Assumes current activity is the searchable activity
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(true); // Do not iconify the widget; expand it by default

    SearchView.OnQueryTextListener textChangeListener = new SearchView.OnQueryTextListener()
    {
        @Override
        public boolean onQueryTextChange(String query)
        {

            listAdapter.getFilter().filter(query);
            return true;
        }
        @Override
        public boolean onQueryTextSubmit(String query)
        {
            // this is your adapter that will be filtered

            return false;
        }
    };
    searchView.setOnQueryTextListener(textChangeListener);
    return true;
}



    /** {@inheritDoc} */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_about_info:
                new AboutNoticeDialog()
                        .show(getSupportFragmentManager(), "dialog_about_notice");
                return true;
            case R.id.action_import:
                importNotes();
                return true;

            case R.id.action_export:
                exportNotes();
                return true;
            default: return super.onOptionsItemSelected(item);
        }
    }

    private void exportNotes() {
        for (Note note : noteDAO.fetchAll()) {
            StringBuilder exportNotes = new StringBuilder();

        }
        }

    private void importNotes() {

    }

    /** {@inheritDoc} */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == NEW_NOTE_RESULT_CODE) {
            if (resultCode == RESULT_OK) addNote(data);
        }
        if (requestCode == EDIT_NOTE_RESULT_CODE) {
            if (resultCode == RESULT_OK) updateNote(data);
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    /** Crea la llamada al modo contextual. */
    private void setupActionModeCallback() {
        actionModeCallback = new ActionMode.Callback() {

            /** {@inheritDoc} */
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                setListOnItemClickListenersWhenActionMode();
                // inflar menu contextual
                mode.getMenuInflater().inflate(R.menu.context_note, menu);
                return true;
            }

            /** {@inheritDoc} */
            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                // Nada
                return false;
            }

            /** {@inheritDoc} */
            @Override
            public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {
                switch (item.getItemId()) {
                    // borrar notas solo si hay notas a borrar; sino se acaba el modo contextual.
                    case R.id.action_delete:
                        if (!selectedPositions.isEmpty()) {
                            new AlertDialog.Builder(MainActivity.this)
                                    .setMessage(getString(R.string.delete_notes_alert, selectedPositions.size()))
                                    .setNegativeButton(android.R.string.no, null)
                                    .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {

                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            deleteNotes(selectedPositions);
                                            mode.finish();
                                        }
                                    })
                                    .show();
                        } else mode.finish();
                        return true;
                    case R.id.action_share:
                        if (!selectedPositions.isEmpty()){
                            shareNotes(selectedPositions);
                        }
                        return true;
                    case R.id.action_select_all:
                        selectAll();
                    default:
                        return false;
                }
            }

            /** {@inheritDoc} */
            @Override
            public void onDestroyActionMode(ActionMode mode) {
                // Regresar al modo normal
                setListOnItemClickListenersWhenNoActionMode();
                resetSelectedListItems();
            }
        };
    }

    private void selectAll() {
        for ( int i=0; i < listAdapter.getCount(); i++) {
            selectedPositions.add(i);
            notesData.get(i).setSelected(true);
            listAdapter.notifyDataSetChanged();
        }
    }

    /** Inicializa el adaptador de notas. */
    private void setupNotesAdapter() {
        notesData = new ArrayList<>();
        for (Note note : noteDAO.fetchAll()) { // Convertir a wrapper
            NotesAdapter.NoteViewWrapper noteViewWrapper = new NotesAdapter.NoteViewWrapper(note);
            notesData.add(noteViewWrapper);
        }
        listAdapter = new NotesAdapter(notesData);
        listView.setAdapter(listAdapter);
    }

    /** Actualiza la vista de esta actividad cuando hay notas o no hay notas. */
    private void updateView() {
        if (notesData.isEmpty()) { // Mostrar mensaje
            listView.setVisibility(View.GONE);
            emptyListTextView.setVisibility(View.VISIBLE);
        } else { // Mostrar lista
            listView.setVisibility(View.VISIBLE);
            emptyListTextView.setVisibility(View.GONE);
        }
    }

    /**
     * Agrega una nota a lista y la fuente de datos.
     *
     * @param data los datos de la actividad de edición de notas.
     */
    private void addNote(Intent data) {
        Note note = EditNoteActivity.getExtraNote(data);
        noteDAO.insert(note);
        NotesAdapter.NoteViewWrapper noteViewWrapper = new NotesAdapter.NoteViewWrapper(note);
        notesData.add(0,noteViewWrapper);
        updateView();
        listAdapter.notifyDataSetChanged();
    }
/*
this method is called when the contextual action button of share is pressed
 */
    private void shareNotes(ArrayList<Integer> selectedPositions) {
        StringBuilder shareBody = new StringBuilder();
        // Primero borra de la base de datos
        for (int position : selectedPositions) {
            NotesAdapter.NoteViewWrapper noteViewWrapper = notesData.get(position);
            shareBody.append(noteViewWrapper.getNote().getContent());
        }

        Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
        sharingIntent.setType("text/plain");
        sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody.toString());
        startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.share_using)));
    }

    /**
     * Borra notas de la lista y de la fuente de datos.
     *
     * @param selectedPositions las posiciones de las notas en la lista.
     */

    private void deleteNotes(ArrayList<Integer> selectedPositions) {
        ArrayList<NotesAdapter.NoteViewWrapper> toRemoveList = new ArrayList<>(selectedPositions.size());
        // Primero borra de la base de datos
        for (int position : selectedPositions) {
            NotesAdapter.NoteViewWrapper noteViewWrapper = notesData.get(position);
            toRemoveList.add(noteViewWrapper);
            noteDAO.delete(noteViewWrapper.getNote());
        }
        // Y luego de la vista (no al mismo tiempo porque pierdo las posiciones que hay que borrar)
        for (NotesAdapter.NoteViewWrapper noteToRemove : toRemoveList) notesData.remove(noteToRemove);
        updateView();
        listAdapter.notifyDataSetChanged();
    }

    /**
     * Actualiza una nota en la lista y la fuente de datos.
     *
     * @param data los datos de la actividad de edición de notas.
     */
    private void updateNote(Intent data) {
        Note updatedNote = EditNoteActivity.getExtraUpdatedNote(data);
        noteDAO.update(updatedNote);
        for (NotesAdapter.NoteViewWrapper noteViewWrapper : notesData) {
            // Buscar la nota vieja para actulizarla en la vista
            if (noteViewWrapper.getNote().getId().equals(updatedNote.getId())) {
                noteViewWrapper.getNote().setContent(updatedNote.getContent());
                noteViewWrapper.getNote().setUpdatedAt(updatedNote.getUpdatedAt());
            }
        }
        listAdapter.notifyDataSetChanged();
    }

    /** Reinicia las notas seleccionadas a no seleccionadas y limpia la lista de seleccionados. */
    private void resetSelectedListItems() {
        for (NotesAdapter.NoteViewWrapper noteViewWrapper : notesData) noteViewWrapper.setSelected(false);
        selectedPositions.clear();
        listAdapter.notifyDataSetChanged();
    }

    /**
     * Inicializa las acciones de la lista al hacer click en sus items cuando NO esta activo el
     * modo contextual.
     */
    private void setListOnItemClickListenersWhenNoActionMode() {
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // Ver la nota al hacer click
                startActivityForResult(ViewNoteActivity.buildIntent(MainActivity.this, notesData.get(position).getNote()), EDIT_NOTE_RESULT_CODE);

            }
        });
        listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                // Iniciar modo contextual para selección de items
                notesData.get(position).setSelected(true);
                listAdapter.notifyDataSetChanged();
                selectedPositions.add(position);
                actionMode = startSupportActionMode(actionModeCallback);
                return true;
            }
        });
    }

    /**
     * Inicializa las acciones de la lista al hacer click en sus items cuando esta activo el menu
     * contextual.
     */
    private void setListOnItemClickListenersWhenActionMode() {
        listView.setOnItemLongClickListener(null);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // Agregar items a la lista de seleccionados y cambiarles el fondo.
                // Si se deseleccionan todos los items, se acaba el modo contextual
                if (selectedPositions.contains(position)) {
                    selectedPositions.remove((Object)position); // no quiero el índice sino el objeto
                    if (selectedPositions.isEmpty()) actionMode.finish();
                    else {
                        notesData.get(position).setSelected(false);
                        listAdapter.notifyDataSetChanged();
                    }
                } else {
                    notesData.get(position).setSelected(true);
                    listAdapter.notifyDataSetChanged();
                    selectedPositions.add(position);
                }
            }
        });
    }
}
公共类MainActivity扩展了RoboActionBarActivity{
私有静态最终整数新注释结果代码=4;
私有静态最终整数编辑\注释\结果\代码=5;
@InjectView(android.R.id.empty)私有文本视图emptyListTextView;
@InjectView(android.R.id.list)私有ListView ListView;
@InjectView(R.id.add_note_按钮)私有浮动操作按钮addnote按钮;
@注入私有notedaonotedao;
private ArrayList Selected Positions;
私人ArrayList notesData;
私有NotesAdapter列表适配器;
私有ActionMode.Callback actionModeCallback;
私人行动模式;
/**{@inheritardoc}*/
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//组成部分//////////////////////////////////////////////////////////////
setOnTouchListener(新的ShowHideOnScroll(addNoteButton,getSupportActionBar());//Esconde o muesta el FAB y la操作栏
addNoteButton.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
//我不知道该怎么做
startActivityForResult(EditNoteActivity.buildIntent(MainActivity.this),新的\u注释\u结果\u代码);
}
});
selectedPositions=new ArrayList();
setTextFilterEnabled(true);
setupnotesdapter();
setupActionModeCallback();
setListOnItemClickListenersWhenNoActionMode();
updateView();
}
/**{@inheritardoc}*/
@TargetApi(构建版本代码蜂窝)
@凌驾
公共布尔onCreateOptions菜单(菜单){
getMenuInflater().充气(R.menu.main,menu);
//获取SearchView并设置可搜索配置
SearchManager SearchManager=(SearchManager)getSystemService(Context.SEARCH\u服务);
SearchView SearchView=(SearchView)菜单.findItem(R.id.action_search).getActionView();
//假设当前活动是可搜索的活动
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName());
searchView.setIconifiedByDefault(true);//不要将小部件图标化;默认情况下展开它
SearchView.OnQueryTextListener textChangeListener=新建SearchView.OnQueryTextListener()
{
@凌驾
公共布尔onQueryTextChange(字符串查询)
{
listAdapter.getFilter().filter(查询);
返回true;
}
@凌驾
公共布尔值onQueryTextSubmit(字符串查询)
{
//这是将被筛选的适配器
返回false;
}
};
setOnQueryTextListener(textChangeListener);
返回true;
}
/**{@inheritardoc}*/
@凌驾
公共布尔值onOptionsItemSelected(菜单项项){
开关(item.getItemId()){
案例R.id.action\u关于信息:
关于noticedialog()的新信息
.show(getSupportFragmentManager(),“关于通知的对话框”);
返回true;
案例R.id.action\u导入:
importNotes();
返回true;
案例R.id.行动\出口:
exportNotes();
返回true;
默认:返回super.onOptionsItemSelected(项目);
}
}
私人票据(){
for(注意:noteDAO.fetchAll()){
StringBuilder exportNotes=新建StringBuilder();
}
}
私有无效导入注释(){
}
/**{@inheritardoc}*/
@凌驾
受保护的void onActivityResult(int请求代码、int结果代码、意图数据){
if(requestCode==新注释\结果\代码){
如果(resultCode==RESULT_OK)添加注释(数据);
}
if(requestCode==编辑注释结果代码){
if(resultCode==RESULT_OK)updateNote(数据);
}
super.onActivityResult(请求代码、结果代码、数据);
}
/**克里亚·拉马达·莫多*/
私有void setupActionModeCallback(){
actionModeCallback=新建ActionMode.Callback(){
/**{@inheritardoc}*/
@凌驾
公共布尔onCreateActionMode(ActionMode模式,菜单){
setListOnItemClickListenersWhenActionMode();
//充气菜单上下文
mode.getMenuInflater().充气(R.menu.context\u注意,菜单);
返回true;
}
/**{@inheritardoc}*/
@凌驾
公共布尔onPrepareActionMode(操作模式,菜单){
//娜达
返回false;
}
/**{@inheritardoc}*/
@凌驾
公共布尔值onActionItemClicked(最终ActionMode模式,菜单项){
开关(item.getItemId()){
//borrar不是一个borrar,而是一个borrar;这是一个中国-东盟国家。
案例R.id.行动\删除:
如果(!selectedPositions.isEmpty()){
新建AlertDialog.Builder(MainActivity.this)
.setMessage(getString(R.string.delete_notes_alert,selectedPositions.size()))
.setNegativeButton(android.R.string.no,null)
.setPositiveButton(android.R.string.yes,新的DialogInterface.O
public class NotesAdapter extends BaseAdapter implements Filterable{

    private static final DateFormat DATETIME_FORMAT = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);

    private final List<NoteViewWrapper> data;
    private List<NoteViewWrapper> filtered_data;


     /** Wrapper para notas. Util para cambiar el fondo de los item seleccionados. */
    public static class NoteViewWrapper {

        private final Note note;
        private boolean isSelected;

        /**
         * Contruye un nuevo NoteWrapper con la nota dada.
         *
         * @param note una nota.
         */
        public NoteViewWrapper(Note note) {
            this.note = note;
        }

        public Note getNote() {
            return note;
        }

        public void setSelected(boolean isSelected) {
            this.isSelected = isSelected;
        }
    }



    /**
     * Constructor.
     *
     * @param data la lista de notas a usar como fuente de datos para este adaptador.
     */
    public NotesAdapter(List<NoteViewWrapper> data) {
        this.data = data;
        this.filtered_data = data;
    }

    /** @return cuantos datos hay en la lista de notas. */
    @Override
    public int getCount() {
        return data.size();
    }

    /**
     * @param position la posición de la nota que se quiere
     * @return la nota en la posición dada.
     */
    @Override
    public NoteViewWrapper getItem(int position) {
        return data.get(position);
    }

    /**
     * @param position una posición
     * @return la misma posición dada
     */
    @Override
    public long getItemId(int position) {
        return position;
    }

    /**
     * Muestra los datos de la nota en la posición dada en una instancia del componente visual
     * {@link com.rants.R.layout#notes_row}.
     *
     * @see <a href="http://bit.ly/MJqzXb">Hold View Objects in a View Holder</a>
     * @param position la posición de la nota en curso.
     * @param convertView el componente visual a usar.
     * @param parent el componente visual padre del componente visual a usar.
     * @return la vista con los datos.
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) { // inflar componente visual
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.notes_row, parent, false);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else holder = (ViewHolder) convertView.getTag(); // ya existe, solo es reciclarlo
        // Inicializa la vista con los datos de la nota
        NoteViewWrapper noteViewWrapper = data.get(position);
        holder.noteIdText.setText(String.valueOf(noteViewWrapper.note.getId()));
        // Corta la cadena a 80 caracteres y le agrega "..."

        SpannableString hashText = new SpannableString(noteViewWrapper.note.getContent());
        Matcher matcher = Pattern.compile("#([A-Za-z0-9_-]+)").matcher(hashText);
        while (matcher.find())
        {
            hashText.setSpan(new ForegroundColorSpan(Color.BLUE), matcher.start(), matcher.end(), 0);
        }


        holder.noteContentText.setText(hashText);

        holder.noteDateText.setText(DATETIME_FORMAT.format(noteViewWrapper.note.getUpdatedAt()));
        // Cambia el color del fondo si es seleccionado
        if (noteViewWrapper.isSelected) holder.parent.setBackgroundColor(parent.getContext().getResources().getColor(R.color.selected_note));
        // Sino lo regresa a transparente
        else holder.parent.setBackgroundColor(parent.getContext().getResources().getColor(android.R.color.transparent));
        return convertView;
    }

    /** Almacena componentes visuales para acceso rápido sin necesidad de buscarlos muy seguido.*/
    private static class ViewHolder {

        private TextView noteIdText;
        private TextView noteContentText;
        private TextView noteDateText;

        private View parent;

        /**
         * Constructor. Encuentra todas los componentes visuales en el componente padre dado.
         *
         * @param parent un componente visual.
         */
        private ViewHolder(View parent) {
            this.parent = parent;
            noteIdText = (TextView) parent.findViewById(R.id.note_id);
            noteContentText = (TextView) parent.findViewById(R.id.note_content);
            noteDateText = (TextView) parent.findViewById(R.id.note_date);
        }
    }

@Override
public Filter getFilter() {
Filter filter = new Filter(){

    @Override
    protected FilterResults performFiltering(CharSequence query) {
        FilterResults results = new FilterResults();
        ArrayList<NoteViewWrapper> filtered = new ArrayList<NoteViewWrapper>();
        query = query.toString().toLowerCase();

        for(int i=0;i<data.size();i++){
            String dataName = data.get(i).getNote().getContent().toLowerCase();
            if (dataName.contains(query)){
                filtered.add(data.get(i));
            }

        }
        results.count = filtered.size();
        results.values = filtered;
        Log.e("values", results.values.toString());
        return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        if (results.count == 0){
            notifyDataSetInvalidated();
        } else {
            filtered_data = (ArrayList<NoteViewWrapper>) results.values;
            NotesAdapter.this.notifyDataSetChanged();
            Log.e("we are in publish results",filtered_data.toString());
        }
    }
};

return filter;
}
}
 filtered_data = (ArrayList<NoteViewWrapper>) results.values;
            NotesAdapter.this.notifyDataSetChanged();
            Log.e("we are in publish results",filtered_data.toString());
NoteViewWrapper noteViewWrapper = data.get(position);
NoteViewWrapper noteViewWrapper = filtered_data.get(position);
@Override
    public View getView(int position, View convertView, ViewGroup parent) {}
notifyDataSetChanged();