android因使用自定义基本适配器过滤而更新Listview

时间:2014-10-14 09:19:06

标签: android android-listview baseadapter notifydatasetchanged android-searchmanager

我在Android中的ListView上实施搜索机制时遇到了问题。

  • 我目前在ListView
  • 中显示公司列表
  • ListView链接到引用数据模型的自定义BaseAdapter
  • 数据模型通过HTTP requests处理数据收集。

我成功部分过滤:已识别的公司在listview中被识别,但其他公司(与搜索约束不匹配的公司仍在那里),即使我删除了它们

以下是代码:

package org.x.activites;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.x.R;
import org.x.activites.utils.Analytics;
import org.x.adapters.listview.AbstractDynamicModel;
import org.x.adapters.listview.AbstractExtendedDynamicViewAdapter;
import org.x.adapters.listview.ViewHolder;
import org.x.application.Application;
import org.x.http.HTTPRequest;
import org.x.list.adapters.PartnerViewHolder;
import org.x.model.Partner;

import android.app.AlertDialog;
import android.app.SearchManager;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ListView;

import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.widget.SearchView;

public class GeoPartnerActivity extends SherlockActivity {
    private ListView listView;
    PartnersModel partnersModel;
    PartnerListAdapter partnerAdpt;
    private SearchManager searchManager;
    private SearchView searchView;

    public GeoPartnerActivity() {
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_partner);
        listView = (ListView) findViewById(R.id.partnerList);
        partnersModel = new PartnersModel();
        partnerAdpt = new PartnerListAdapter(partnersModel);
        listView.setAdapter(partnerAdpt);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getSupportMenuInflater().inflate(R.menu.activity_partners, menu);
        searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
        if (null != searchView) {
            searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
            searchView.setIconifiedByDefault(false);
        }

        SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() {
            public boolean onQueryTextChange(String newText) {
                return false;
            }

            public boolean onQueryTextSubmit(String query) {
                if (TextUtils.isEmpty(query)) {
                    listView.clearTextFilter();
                }
                else {
                    listView.setFilterText(query);
                }
                partnerAdpt.getFilter().filter(query);
                return true;
            }
        };

        searchView.setOnQueryTextListener(queryTextListener);
        searchView.setQueryHint("Salut StackExchange");
        return super.onCreateOptionsMenu(menu);
    }

    public class PartnersModel extends AbstractDynamicModel<Partner> {

        public PartnersModel() {
        }

        private HTTPRequest createRequest() {
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("currentIndex", getElements().size() + ""));
            nameValuePairs.add(new BasicNameValuePair("partnersNumber", "5"));

            return new HTTPRequest("http://xxxxxxxxxxxxxxxx/partners", nameValuePairs);
        }

        @Override
        protected BackgroundTask createBackgroundTask() {
            BackgroundTask backgroundTask = new BackgroundTask(GeoPartnerActivity.this, createRequest()) {
                List<Partner> lastLoaded = new ArrayList<Partner>();

                @Override
                protected List<Partner> getLoadedElements() {
                    return lastLoaded;
                }

                @Override
                protected void handleSuccess(Object object) {
                    lastLoaded.clear();
                    try {
                        JSONArray array = (JSONArray) object;
                        for (int i = 0; i < array.length(); i++) {
                            JSONObject jsonObject = (JSONObject) array.get(i);

                            Partner partner = new Partner(jsonObject);

                            lastLoaded.add(partner);
                        }

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

                }
            };
            return backgroundTask;
        }

        @Override
        public List<Partner> getElements() {
            return super.getElements();
        }

        @Override
        protected Context getContext() {
            return GeoPartnerActivity.this;
        }

    }

    private class PartnerListAdapter extends AbstractExtendedDynamicViewAdapter<Partner> implements Filterable {

        private PartnersModel partnerList, partnerFullList;
        private PartnerFilter partnerFilter;

        public PartnerListAdapter(PartnersModel model) {
            super(GeoPartnerActivity.this, model);
            partnerList = model;
            partnerFullList = new PartnersModel();
        }

        @Override
        public Filter getFilter() {
            if (partnerFilter == null) {
                partnerFilter = new PartnerFilter();
            }
            return partnerFilter;
        }

        public void notifyDataSetChanged() {
            super.notifyDataSetChanged();
        }

        @Override
        protected int getResourceID() {
            return PartnerViewHolder.ResourceId;
        }

        @Override
        protected ViewHolder createViewHolder(View convertView) {
            return new PartnerViewHolder(convertView);
        }

        public class PartnerFilter extends Filter {

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();

                List<Partner> partnerFilteredList = new ArrayList<Partner>();
                for (Iterator<Partner> iterator = partnerList.iterator(); iterator.hasNext();) {

                    Partner partner = iterator.next();
                    partnerFullList.getElements().add(partner);

                    if (false == partner.getName().toUpperCase().contains(constraint.toString().toUpperCase())) {
                        partnerFilteredList.add(partner);
                    }
                }
                results.values = partnerFilteredList;
                results.count = partnerFilteredList.size();

                return results;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                if (results.count == 0)
                    partnerAdpt.notifyDataSetInvalidated();
                else {
                    for (Iterator<Partner> iterator = ((List<Partner>) results.values).iterator(); iterator.hasNext();) {
                        Partner p = (Partner) iterator.next();
                        if (partnerAdpt.partnerList.getElements().remove(p));
                            p.setName("del-> " + p.getName());  
                    }

                    //listView.setAdapter(null);
                    //listView.setAdapter(new PartnerListAdapter(partnerList));
                    ((PartnerListAdapter) listView.getAdapter()).notifyDataSetChanged();
                    listView.refreshDrawableState();
                    listView.invalidateViews();
                }
            }
        }
    }
}

这是菜单布局

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/menu_search"
        android:actionViewClass="com.actionbarsherlock.widget.SearchView"
        android:icon="@drawable/toolbar_find"
        android:showAsAction="always"
        android:title="Search">
    </item>
</menu>

以下是过滤前的截图:

enter image description here

之后:

enter image description here

我已使用“del-&gt;”标记了项目的名称,因此所有这些项目都已标识,但未从列表中删除!!!

编辑:

这是顶级适配器AbstractDynamicViewAdapter:

public abstract class AbstractDynamicViewAdapter extends BaseAdapter {
    protected final Context _context;

    protected final ArrayList<AdapterItem> _list;

    private final LayoutInflater _inflater;

    private final int _progressResourceId;
    private final int _unavailableResourceId;
    private final int _emptyResourceId;

    protected boolean _isInitialization = false;
    protected boolean _isRequestSubmited = false;

    public AbstractDynamicViewAdapter(Context context, int progressResourceId, int unavailableResourceId,
            int emptyResourceId) {
        _context = context;
        _inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        _list = new ArrayList<AdapterItem>();

        _progressResourceId = progressResourceId;
        _unavailableResourceId = unavailableResourceId;
        _emptyResourceId = emptyResourceId;
    }

    protected abstract View onDataView(int position, AdapterItem item, View convertView, ViewGroup parent);

    protected abstract void onDataLoad();

    protected abstract boolean isMoreToLoad();

    protected abstract void onSubmitDataRequest();

    @Override
    public int getCount() {
        return _list.size();
    }

    @Override
    public Object getItem(int position) {
        Object result = null;

        if (position < _list.size()) {
            result = _list.get(position);
        }

        return result;
    }

@Override
/* Override this method when implementing stable id */
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (_list.size() > position) {
        AdapterItem item = _list.get(position);

        if (item.viewType == ViewType.Data) {
            convertView = onDataView(position, item, convertView, parent);
        }
        else {
            int resourceid = getResourceByViewType(item.viewType);
            convertView = tryInflateView(convertView, resourceid, parent);
            tryCreateViewHolder(convertView, item, resourceid);

            if (!_isRequestSubmited && item.viewType == ViewType.Progress) {
                submitDataRequest();
            }
        }
    }

    return convertView;
}
protected int getResourceByViewType(ViewType expectedType) {
    int result = 0;

    switch (expectedType) {
        case Progress:
            result = _progressResourceId;
            break;
        case Unavailable:
            result = _unavailableResourceId;
            break;
        case Empty:
            result = _emptyResourceId;
            break;
        default:
            break;
    }

    return result;
}

protected void tryCreateViewHolder(View viewSource, AdapterItem item, int resourceId) {
    ViewHolder viewItem = (ViewHolder) viewSource.getTag();
    if (viewItem == null) {
        viewItem = new ViewHolder(viewSource, resourceId);
    }
}

protected View tryInflateView(View viewSource, int resourceId, ViewGroup parent) {
    View result = null;

    if (viewSource != null && viewSource.getTag() != null) {
        ViewHolder viewItem = (ViewHolder) viewSource.getTag();
        // try to re-use view if it has the same type
        if (viewItem != null && viewItem.resourceId == resourceId) {
            result = viewSource;
        }
    }

    if (result == null) {
        // create new view
        result = _inflater.inflate(resourceId, parent, false);
    }

    return result;
}

    protected void addItem(Object value, Object tag) {
        AdapterItem item = new AdapterItem(value, tag);
        _list.add(item);
    }

    protected void removeItem(Object item) {
        _list.remove(item);
    }

    protected void addUnavailableItem() {
        AdapterItem item = new AdapterItem(ViewType.Unavailable);
        _list.add(item);
    }

    protected void submitDataRequest() {
        showProgress();
        onSubmitDataRequest();
        _isRequestSubmited = true;
    }

    protected void setDataCompleted() {
        _list.clear();
        onDataLoad();
        if (isMoreToLoad()) {
            showProgress();
        }
        notifyDataSetChanged();

        _isRequestSubmited = false;
    }

    private void removeAnyBut(ViewType type) {
        if (type != ViewType.Progress) {
            tryEndProgress();
        }

        if (type != ViewType.Empty) {
            tryEndEmpty();
        }

        if (type != ViewType.Unavailable) {
            tryEndUnavailable();
        }
    }

    private void tryShowItem(ViewType type) {
        removeAnyBut(type);

        if (_list.size() == 0 || _list.get(_list.size() - 1).viewType != type) {
            _list.add(new AdapterItem(type));
        }

        notifyDataSetChanged();
    }

    protected void showUnavailable() {
        tryShowItem(ViewType.Unavailable);
    }

    protected void showProgress() {
        tryShowItem(ViewType.Progress);
    }

    protected void showEmpty() {
        tryShowItem(ViewType.Empty);
    }

    private void tryRemoveItem(ViewType type) {
        if (_list.size() > 0 && _list.get(_list.size() - 1).viewType == type) {
            _list.remove(_list.size() - 1);
        }
    }

    protected void tryEndProgress() {
        tryRemoveItem(ViewType.Progress);
    }

    protected void tryEndUnavailable() {
        tryRemoveItem(ViewType.Unavailable);
    }

    protected void tryEndEmpty() {
        tryRemoveItem(ViewType.Empty);
    }

}

中间适配器AbstractExtendedDynamicViewAdapter:

public abstract class AbstractExtendedDynamicViewAdapter<T> extends AbstractDynamicViewAdapter {
    private final AbstractDynamicModel<T> _model;

    private boolean offlineModedataLoaded = false;

    private Handler handler = new Handler() {
        @Override
        public void dispatchMessage(Message msg) {
            setDataCompleted();
        }
    };

    public AbstractExtendedDynamicViewAdapter(Context context, AbstractDynamicModel<T> model) {
        super(context, R.layout.progress_item, R.layout.unavailable_item, R.layout.empty_item);

        _model = model;
        _model.setLoadCompleted(handler);
        submitDataRequest();
    }

    @Override
    public View onDataView(int position, AdapterItem item, View convertView, ViewGroup parent) {
        convertView = tryInflateView(convertView, getResourceID(), parent);
        ViewHolder viewHolder = (ViewHolder) convertView.getTag();
        if (viewHolder == null) {
            viewHolder = createViewHolder(convertView);
        }
        viewHolder.render(item);
        return convertView;
    }
    public boolean removeElement(Object obj) {
        //return _list.remove(obj);
        return _model.getElements().remove(obj);
    }

    protected abstract int getResourceID();

    protected abstract ViewHolder createViewHolder(View convertView);

    @Override
    protected boolean isMoreToLoad() {
        if (Utils.isConnected(_context)) {
            offlineModedataLoaded = true;
            return true;
        }
        else
            if (false == offlineModedataLoaded) {
                offlineModedataLoaded = true;
                return true;
            }
        return false;
    }

    @Override
    protected void onDataLoad() {
        if (_model.getElements().isEmpty()) {
            addUnavailableItem();
            showUnavailable();
        }
        else {
            for (int i = 0; i < _model.getElements().size(); i++) {

                addItem(_model.getElements().get(i), null);
            }
        }
    }

    @Override
    protected void onSubmitDataRequest() {
        _model.loadMore();
    }

}

1 个答案:

答案 0 :(得分:0)

if (partnerAdpt.partnerList.getElements().remove(p));
                            p.setName("del-> " + p.getName());  

使用此代码,您只能更新过滤结果。您应该使用以下代码从放入适配器的列表中删除此值:

super(GeoPartnerActivity.this, model);

尝试获得&#34;模型&#34;来自适配器的数据(不是来自摘要)并删除&#34; p&#34;。