在搜索查看SherlockListFragment [英] SearchView in SherlockListFragment

查看:454
本文介绍了在搜索查看SherlockListFragment的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的SherlockListFragment.There使用搜索查看是一个自定义ArrayAdapter并包含一个图像和两个TextViews每个项目一个ListView一些麻烦。一切正常,直到我申请搜索查看我的ListFragment。搜索图标可扩展,我也能够进入的话在搜索栏中。

I have some troubles using SearchView in my SherlockListFragment.There is a custom ArrayAdapter and a listview which contains one image and two TextViews for each item. Everything works well until I applied SearchView for my ListFragment. The search icon is expandable and I'm also able to enter words into the search bar.

问题

自定义适配器现在能够过滤列表视图,但是当我从扩展搜索查看删除最后一个字母,或关闭搜索查看,应用程序崩溃。

The custom adapter is able to filter the listview now, but when I delete the last letter from the expandable searchview, or close the searchview, the app crashed.

我重视我的ArrayAdapter类,还有,我下面的SherlockListFragment。

I have attached my ArrayAdapter class, as well as, my SherlockListFragment below.

自定义ArrayAdapter与过滤等级

 public static class ShopListAdapter extends ArrayAdapter<ShopEntry>
 {
    private final LayoutInflater mInflater;

    private List<ShopEntry> filteredData;
    private List<ShopEntry> originalData;

    public ShopListAdapter(Context context, List<ShopEntry> filteredData)
    {
        super(context, android.R.layout.simple_list_item_2, filteredData);
        mInflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.filteredData = filteredData;

    }

    public void setData(List<ShopEntry> data)
    {
        clear();
        if(data != null)
        {
            for(ShopEntry ShopEntry : data)
            {
                add(ShopEntry);

            }
        }
        filteredData = data;
        originalData = data;

    }

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

    @Override
    public ShopEntry getItem(int pos)
    {
        return filteredData.get(pos);
    }

    /**
     * Populate new items in the list.
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View view;

        if(convertView == null)
        {
            view = mInflater.inflate(R.layout.specific_shop_list_item,
                    parent, false);
        }
        else
        {
            view = convertView;
        }

        ShopEntry item = filteredData.get(position);
        String url = item.getImg();
        ((SmartImageView) view.findViewById(R.id.shopImg)).setImageUrl(url);
        ((TextView) view.findViewById(R.id.shopType)).setText(item
                .getShopName());
        view.setBackgroundColor(0xff1e8e8);

        return view;
    }

    private class MyFilter extends Filter
    {

        @SuppressWarnings("unchecked" )
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results)
        {
            if(results != null && results.count > 0)
            {
                filteredData = (ArrayList<ShopEntry>) results.values;
                notifyDataSetChanged();

            }
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint)
        {
            constraint = constraint.toString();
            filteredData = originalData;
            if(constraint.length() == 0 || constraint.equals(""))
            {
                FilterResults original = new FilterResults();
                original.count = filteredData.size();
                original.values = filteredData;
                return original;
            }
            else
            {
                List<ShopEntry> filtered = new ArrayList<ShopEntry>();
                for(ShopEntry l : filteredData)
                {
                    if(l.getShopName().contains(constraint))
                    { // YOU NEED TO CHANGE THIS
                        filtered.add(l);
                        Log.d("filter", "filter " + constraint + " "
                                + l.getShopName().toString());
                    }
                }
                FilterResults newFilterResults = new FilterResults();
                newFilterResults.count = filtered.size();
                newFilterResults.values = filtered;
                return newFilterResults;
            }
        }
    }

    MyFilter mFilter;

    @Override
    public Filter getFilter()
    {
        if(mFilter == null)
        {
            mFilter = new MyFilter();
        }
        return mFilter;
    }

}

我的ListFragment类

public class ShopListFragment extends SherlockListFragment implements
    LoaderManager.LoaderCallbacks<List<ShopEntry>>, OnQueryTextListener
 {

List<ShopEntry> shopEntry = new ArrayList<ShopEntry>();

// This is the Adapter being used to display the list's data.
ShopListAdapter mAdapter;
SearchView searchView;
// If non-null, this is the current filter the user has provided.
String mCurFilter = "";

OnQueryTextListenerCompat mOnQueryTextListenerCompat;

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

    // Give some text to display if there is no data. In a real
    // application this would come from a resource.
    setEmptyText("No Such Shop");

    // We have a menu item to show in action bar.
    setHasOptionsMenu(true);

    // Create an empty adapter we will use to display the loaded data.
    mAdapter = new ShopListAdapter(getActivity(), shopEntry);
    setListAdapter(mAdapter);

    // Start out with a progress indicator.
    setListShown(false);

    // Prepare the loader. Either re-connect with an existing one,
    // or start a new one.

    getLoaderManager().initLoader(0, null, this);

}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
    // Place an action bar item for searching.
    // super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.menu_with_search, menu);

    MenuItem item = menu.findItem(R.id.action_search);

    searchView = new SearchView(getSherlockActivity().getSupportActionBar()
            .getThemedContext());
    searchView.setQueryHint(getString(R.string.search_hint));

    searchView.setOnQueryTextListener(this);

    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    if(currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    {
        item.setOnActionExpandListener(new OnActionExpandListener()
        {

            @Override
            public boolean onMenuItemActionCollapse(MenuItem item)
            {
                searchView.onActionViewCollapsed();
                searchView.setQuery(null, true);
                searchView.clearFocus();
                return true; // Return true to collapse action view
            }

            @Override
            public boolean onMenuItemActionExpand(MenuItem item)
            {
                // TODO Auto-generated method stub

                return true;
            }
        });
    }
    else
    {
        // do something for phones running an SDK before froyo
        searchView.setOnCloseListener(new OnCloseListener()
        {

            @Override
            public boolean onClose()
            {
                searchView.onActionViewCollapsed();
                searchView.setQuery(null, true);
                searchView.clearFocus();
                return false;
            }
        });
    }

    item.setActionView(searchView);
    super.onCreateOptionsMenu(menu, inflater);

}

@Override
public boolean onQueryTextChange(String newText)
{ // called when the action bar search text has changed. Update
    // the search filter, and restart the loader to do a new query
    // with this filter.
    String newFilter = !TextUtils.isEmpty(newText) ? newText : null;
    // Don't do anything if the filter hasn't actually changed.
    // Prevents restarting the loader when restoring state.
    if(mCurFilter == null && newFilter == null)
    {
        return true;
    }
    if(mCurFilter != null && mCurFilter.equals(newFilter))
    {
        return true;
    }
    mCurFilter = newFilter;
    mAdapter.getFilter().filter(mCurFilter.toString());

    getLoaderManager().restartLoader(0, null, this);

    return true;
}

@Override
public boolean onQueryTextSubmit(String query)
{
    // TODO Auto-generated method stub
    return true;
}

@Override
public Loader<List<ShopEntry>> onCreateLoader(int id, Bundle args)
{
    // This is called when a new Loader needs to be created. This
    // sample only has one Loader with no arguments, so it is simple.

    return new ShopListLoader(getActivity());
}

@Override
public void onLoadFinished(Loader<List<ShopEntry>> loader,
        List<ShopEntry> data)
{
    // Set the new data in the adapter.
    mAdapter.setData(data);

    // The list should now be shown.
    if(isResumed())
    {
        setListShown(true);
    }
    else
    {
        setListShownNoAnimation(true);
    }
}

@Override
public void onLoaderReset(Loader<List<ShopEntry>> loader)
{
    // Clear the data in the adapter.
    mAdapter.setData(null);
}
 }

日志文件

08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:962)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:496)
    08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:212)
    08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:30)
    08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.text.method.BaseKeyListener.backspaceOrForwardDelete(BaseKeyListener.java:94)
    08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.text.method.BaseKeyListener.backspace(BaseKeyListener.java:49)
    08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.text.method.BaseKeyListener.onKeyDown(BaseKeyListener.java:155)
    08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.text.method.QwertyKeyListener.onKeyDown(QwertyKeyListener.java:356)
    08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.text.method.TextKeyListener.onKeyDown(TextKeyListener.java:136)
    08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.widget.TextView.doKeyDown(TextView.java:5385)
    08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.widget.TextView.onKeyDown(TextView.java:5204)
    08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.widget.AutoCompleteTextView.onKeyDown(AutoCompleteTextView.java:716)
    08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.KeyEvent.dispatch(KeyEvent.java:2609)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.View.dispatchKeyEvent(View.java:7205)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1920)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1395)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.app.Activity.dispatchKeyEvent(Activity.java:2370)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at com.actionbarsherlock.app.SherlockFragmentActivity.dispatchKeyEvent(SherlockFragmentActivity.java:121)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1847)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3701)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewRootImpl.handleImeFinishedEvent(ViewRootImpl.java:3651)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:2818)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.os.Looper.loop(Looper.java:137)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at android.app.ActivityThread.main(ActivityThread.java:5041)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at java.lang.reflect.Method.invokeNative(Native Method)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at java.lang.reflect.Method.invoke(Method.java:511)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
08-20 01:44:44.549: E/AndroidRuntime(4246):     at dalvik.system.NativeStart.main(Native Method)

谁能帮我? THX

Can anyone help me ? thx

推荐答案

搜索查看夏洛克扩大它集的TextView 组件,可以从源头上看到:

When the SearchView in Sherlock is expanded it sets the TextView component to "", you can see it from the source:

 @Override
public void onActionViewExpanded() {
    if (mExpandedInActionView) return;

    mExpandedInActionView = true;
    mCollapsedImeOptions = mQueryTextView.getImeOptions();
    mQueryTextView.setImeOptions(mCollapsedImeOptions | EditorInfo.IME_FLAG_NO_FULLSCREEN);
    mQueryTextView.setText("");
    setIconified(false);
}

这就是为什么你的过滤器返回原始数据。相反,相比于 android.widget.SearchView 它不设置查询时动作视图也崩溃了。你需要省略为(除非需要)过滤,并检查如果你是无效的的ListView长话短说进行过滤的时候,因为你还没有张贴的过滤实现。

That's why your filter returns the original data. Contrary, comparing to the android.widget.SearchView it does not set the query to "" when the action view is also collapsed. Long story short you need to omit filtering with "" (unless needed), and also check if you are invalidating the ListView when the filtering is performed, since you havent posted the filtering implementation.

编辑:过滤列表视图的示例

Example of filtering listview

私有类MyFilter扩展过滤器{

private class MyFilter extends Filter {

@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
    if (results!=null && results.count > 0) {
        items = (ArrayList<Data>) results.values;
        notifyDataSetChanged();

    }
}

@Override
protected FilterResults performFiltering(CharSequence constraint) {
    constraint = constraint.toString().toLowerCase();
    items = mOriginalData;
    if (constraint.length() == 0 || constraint.equals("")) {
        FilterResults original = new FilterResults();
        original.count = items.size();
        original.values = items;
        return original;
    } else {
        List<Data> filtered = new ArrayList<Data>();
        for (Data l : items) {
            if ( SOME CONDITION TO FILTER ){ // YOU NEED TO CHANGE THIS
             filtered.add(l);
            }
        }
        FilterResults newFilterResults = new FilterResults();
        newFilterResults.count = filtered.size();
        newFilterResults.values = filtered;
        return newFilterResults;
    }
}

};

在您的适配器:

@Override
public Filter getFilter() {
    if (mFilter == null) {
        mFilter = new MyFilter();
    }
    return mFilter;
}

这篇关于在搜索查看SherlockListFragment的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆