过滤自定义baseadapter中的应用程序列表

我正在尝试使用我的baseadapter类为我的已安装应用程序的列表视图实现searchview。

目前它看起来像这样:

在此处输入图像描述

问题是,当我遇到崩溃时

09-02 19:56:47.925 1628-1628/com.spicycurryman.getdisciplined10.app.dev E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.spicycurryman.getdisciplined10.app.dev, PID: 1628 java.lang.NullPointerException at com.spicycurryman.getdisciplined10.app.BlockActivity$2.onQueryTextSubmit(BlockActivity.java:126) 

因为我不确定如何设置我的listview和适配器

目前这是我的片段类:

 package com.spicycurryman.getdisciplined10.app; import android.annotation.TargetApi; import android.app.ActionBar; import android.app.FragmentTransaction; import android.app.SearchManager; import android.content.Context; import android.content.pm.ActivityInfo; import android.os.Build; import android.os.Bundle; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.text.Spannable; import android.text.SpannableString; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.widget.ArrayAdapter; import android.widget.ListView; import com.ibc.android.demo.appslist.app.ApkAdapter; import info.androidhive.tabsswipe.adapter.TabsPagerAdapter; /** * Created by Spicycurryman on 6/17/14. */ public class BlockActivity extends ActionBarActivity implements ActionBar.TabListener, SearchView.OnQueryTextListener { private ViewPager viewPager; private TabsPagerAdapter mAdapter; private ActionBar actionBar; ApkAdapter mAppAdapter; private ListView mListView; private ArrayAdapter hanadapter; SearchManager searchManager; SearchView searchView; // Tab titles private String[] tabs = {"Installed Apps"}; @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) @Override protected void onCreate(Bundle savedInstanceState) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); super.onCreate(savedInstanceState); setTheme(R.style.Theme_Light_appalled); SpannableString s = new SpannableString("GetDisciplined"); s.setSpan(new TypefaceSpan(this, "roboto-lightitalic.ttf.ttf"), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // Update the action bar title with the TypefaceSpan instance ActionBar actionBar = getActionBar(); actionBar.setTitle(s); setContentView(R.layout.block_apps); // Initilization viewPager = (ViewPager) findViewById(R.id.pager); actionBar = getActionBar(); mAdapter = new TabsPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(mAdapter); actionBar.setHomeButtonEnabled(false); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // Adding Tabs for (String tab_name : tabs) { actionBar.addTab(actionBar.newTab().setText(tab_name) .setTabListener(this)); } /** * on swiping the viewpager make respective tab selected * */ final ActionBar finalActionBar = actionBar; viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int position) { // on changing the page // make respected tab selected finalActionBar.setSelectedNavigationItem(position); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.block, menu); searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); searchView = (SearchView) menu.findItem(R.id.action_search).getActionView(); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { if (!isLoading()) { mAppAdapter.getFilter().filter(query); } return true; } private boolean isLoading() { return false; } @Override public boolean onQueryTextChange(String newText) { if (!isLoading()) { if (newText.contains(newText)) { mAppAdapter.getFilter().filter(newText); } } return true; } }); return false; } @Override public boolean onPrepareOptionsMenu(Menu menu) { return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: onBackPressed(); break; default: return super.onOptionsItemSelected(item); } return true; } @Override public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { viewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { } @Override public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { } @Override public boolean onQueryTextSubmit(String s) { return false; } @Override public boolean onQueryTextChange(String s) { return false; } } 

这是我的BaseAdapter类注意底部:

 package com.ibc.android.demo.appslist.app; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.Filterable; import android.widget.TextView; import android.widget.Toast; import android.widget.Filter; import com.spicycurryman.getdisciplined10.app.R; import java.util.ArrayList; import java.util.HashSet; import java.util.List; // public class ApkAdapter extends BaseAdapter implements Filterable { //Pastebin link: http://pastebin.com/LGRicg4U , http://pastebin.com/c4WfmhMK , http://pastebin.com/gFuuM4dY, http://pastebin.com/4Q7EP9G4 // http://pastebin.com/Te2g072w, http://pastebin.com/NLT5iUiA , SharedPreferences sharedPrefs; SharedPreferences sharedPrefsapp; List packageList; TextView appnamestyle; Activity context; PackageManager packageManager; boolean[] itemChecked; HashSet checked; Filter mFilter; String PACKAGE_NAME; TextView appname; public ApkAdapter(Activity context, List packageList, PackageManager packageManager) { super(); this.context = context; this.packageList = packageList; this.packageManager = packageManager; itemChecked = new boolean[packageList.size()]; } private class ViewHolder { TextView apkName; CheckBox ck1; TextView packageName; } public int getCount() { return packageList.size(); } public Object getItem(int position) { return packageList.get(position); } public long getItemId(int position) { return 0; } @Override public View getView(final int position, View convertView, ViewGroup parent) { final ViewHolder holder; LayoutInflater inflater = context.getLayoutInflater(); if (convertView == null) { convertView = inflater.inflate(R.layout.installed_apps, null); holder = new ViewHolder(); holder.apkName = (TextView) convertView .findViewById(R.id.appname); holder.apkName.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/raleway-medium.otf")); holder.ck1= (CheckBox)convertView .findViewById(R.id.checkBox1); holder.packageName = (TextView) convertView.findViewById(R.id.app_package); convertView.setTag(holder); //holder.ck1.setTag(packageList.get(position)); } else { holder = (ViewHolder) convertView.getTag(); } // ViewHolder holder = (ViewHolder) convertView.getTag(); final PackageInfo packageInfo = (PackageInfo) getItem(position); Drawable appIcon = packageManager .getApplicationIcon(packageInfo.applicationInfo); // Make sure to define it again! PACKAGE_NAME = packageInfo.packageName; final String appName = packageManager.getApplicationLabel( packageInfo.applicationInfo).toString(); appIcon.setBounds(0, 0, 80, 80); holder.apkName.setCompoundDrawables(appIcon, null, null, null); holder.apkName.setCompoundDrawablePadding(15); holder.apkName.setText(appName); //holder.packageName.setText(PACKAGE_NAME); holder.ck1.setChecked(false); if (itemChecked[position]) holder.ck1.setChecked(true); else holder.ck1.setChecked(false); // CHANGE UP EVERYTHING! MAKE THIS SHIT WORK, TIGGA! checked = new HashSet(); PACKAGE_NAME = packageInfo.packageName; //Log.d("just here: ", PACKAGE_NAME); sharedPrefs = context.getSharedPreferences(context.getApplicationContext().getPackageName(), Context.MODE_PRIVATE); sharedPrefsapp = context.getSharedPreferences("appdb", Context.MODE_PRIVATE); holder.ck1.setChecked(sharedPrefs.getBoolean(PACKAGE_NAME,false)); holder.ck1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { SharedPreferences.Editor editor = context.getSharedPreferences(context.getApplicationContext().getPackageName(), Context.MODE_PRIVATE).edit(); SharedPreferences.Editor editorapp = context.getSharedPreferences("appdb", Context.MODE_PRIVATE).edit(); if (holder.ck1.isChecked()) { itemChecked[position] = true; holder.ck1.setChecked(true); editor.putBoolean(packageInfo.packageName, true); editorapp.putString(packageInfo.packageName, packageInfo.packageName); editor.apply(); editorapp.apply(); // sharedPrefs = context.getSharedPreferences(context.getApplicationContext().getPackageName(), Context.MODE_PRIVATE); } else { itemChecked[position] = false; holder.ck1.setChecked(false); editor.putBoolean(packageInfo.packageName, false); editorapp.remove(packageInfo.packageName); editor.apply(); editorapp.apply(); //sharedPrefs = context.getSharedPreferences(context.getApplicationContext().getPackageName(), Context.MODE_PRIVATE); } } }); return convertView; } @Override public Filter getFilter() { if (mFilter == null) { mFilter = new ItemsFilter(); } return mFilter; } private class ItemsFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence prefix) { // TODO Auto-generated method stub List packageList_2 = packageList; String prefixString = prefix.toString().toLowerCase(); FilterResults results = new FilterResults(); ArrayList FilteredList = new ArrayList(); if (prefix == null || prefix.length() == 0) { results.values = packageList_2; results.count = packageList_2.size(); return results; } for (int i = 0; i < packageList_2.size(); i++) { String filterText = prefix.toString().toLowerCase(); try { PackageInfo data = packageList_2.get(i); if (data.applicationInfo .loadLabel(context.getApplicationContext().getPackageManager()) .toString().toLowerCase().contains(filterText)) { FilteredList.add(data); } else if (data.packageName.contains(filterText)) { FilteredList.add(data); } } catch (Exception e) { Toast.makeText(context.getApplicationContext(), "exception e" + e.toString(), Toast.LENGTH_SHORT).show(); } } results.values = FilteredList; results.count = FilteredList.size(); return results; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { Toast.makeText(context.getApplicationContext(),"result-0 "+results.count, Toast.LENGTH_SHORT).show(); packageList = (List) results.values; notifyDataSetChanged(); } } } 

我如何设置mAppAdapter以使其过滤结果? 已经做了很多研究,但无法为我的案例提供解决方案。

编辑:

得到此错误:

 Process: com.spicycurryman.getdisciplined10.app.dev, PID: 1317 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.spicycurryman.getdisciplined10.app.dev/com.spicycurryman.getdisciplined10.app.InstalledAppActivity}: java.lang.NullPointerException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) at android.app.ActivityThread.access$800(ActivityThread.java:135) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) at dalvik.system.NativeStart.main(Native Method) 

这是我的新代码:

http://pastebin.com/sGd15Uve

这是我的edittext,它表示它为null:

   

不清楚为什么当它明显存在时会产生这个错误。

编辑:我开发了一个组件,它允许您过滤自定义ListViews并动态更改filter等。我认为它有一个简单的实现和你。 试试看!

我希望这对你们所有人来说都更好。

https://github.com/matessoftwaresolutions/AndroidFilterableList

对我来说最简单的方法:

  1. 定义自定义通用filter
  2. 定义使其成为通用所需的侦听器
  3. 将所有项目链接到视图

例:

  1. 我的扩展baseAdapter实现了两个接口(IFilteredItem和IFilteredListListener。

其内容是:

 public class MenuListAdapter extends BaseAdapter implements IFilteredListListener, IFilterableItem { public MenuListAdapter(Context context,List points) { this.context = context; //Elements for the list this.points = points; } .... 

BaseAdapter方法和其他实现:

 @Override public int getCount() { return points.size(); } @Override public Object getItem(int position) { return points.get(position); } @Override public long getItemId(int position) { return position; } @Override public Filter getFilter() { if (filter == null) { filter = new ListFilter(points, this, this,this); } return filter; } @Override public void onSearchResult(List objects) { if (objects.size() == 0) { points = objects; objects.add(mockedPointForEmptyList); } else { points = objects; } } @Override public String getStringForFilter(PointOfInterest item) { return item.getTitle(); } .... 

在我的活动中,我有一个列表视图。 我设置了自定义适配器,它会根据兴趣点的标题比较filter:

在您的活动中,获取将用于过滤列表的编辑文本,并添加观察者:

 filterText = (EditText) customActionBar.findViewById(R.id.searchText); filterText.addTextChangedListener(filterTextWatcher); 

在您的活动(属性区域)中,定义您的观察者:

 private TextWatcher filterTextWatcher = new TextWatcher() { public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { yourMenuAdapter.getFilter().filter(s); } }; 

我建议你使用我自己的filter实现(复制和粘贴,如果你发现任何错误请告诉我!):

 public class ListFilter extends Filter { private List adapterFilterElements; private List originalFilterElements; private final Object mLock = new Object(); private List originalFilterValues; private IFilteredListListener listener; private BaseAdapter baseAdapter; private IFilterableItem filterableItem; public ListFilter(List originalElements, BaseAdapter baseAdapter, IFilteredListListener listener, IFilterableItem filterableItem) { this.adapterFilterElements = originalElements; this.originalFilterElements = originalElements; this.baseAdapter = baseAdapter; this.listener = listener; this.filterableItem = filterableItem; } @Override protected FilterResults performFiltering(CharSequence prefix) { FilterResults results = new FilterResults(); if (originalFilterValues == null) { synchronized (mLock) { originalFilterValues = fillListNamesFromItems(adapterFilterElements); } } if (prefix == null || prefix.length() == 0) { ArrayList list; synchronized (mLock) { list = new ArrayList(originalFilterValues); } results.values = list; results.count = list.size(); } else { String prefixString = prefix.toString().toLowerCase(Locale.UK); ArrayList values; synchronized (mLock) { values = new ArrayList(originalFilterValues); } final int count = values.size(); final ArrayList newValues = new ArrayList(); for (int i = 0; i < count; i++) { final String value = values.get(i); final String valueText = value.toString().toLowerCase(Locale.UK); // First match against the whole, non-splitted value if (valueText.startsWith(prefixString)) { newValues.add(value); } else { final String[] words = valueText.split(" "); final int wordCount = words.length; // Start at index 0, in case valueText starts with // space(s) for (int k = 0; k < wordCount; k++) { if (words[k].startsWith(prefixString)) { newValues.add(value); break; } } } } results.values = newValues; results.count = newValues.size(); } return results; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { results.values = fillItemListFromNames((List) results.values); listener.onSearchResult((List) results.values); adapterFilterElements = (List) results.values; if (results.count > 0) { baseAdapter.notifyDataSetChanged(); } else { baseAdapter.notifyDataSetInvalidated(); } } private List fillItemListFromNames(List names) { List ret = new ArrayList(); if (names != null) { for (String s : names) { for (T p : originalFilterElements) { if (filterableItem.getStringForFilter(p).equals(s)) { ret.add(p); break; } } } } return ret; } private List fillListNamesFromItems(List items) { List ret = new ArrayList(); if (items != null) { for (T item : items) { ret.add(filterableItem.getStringForFilter(item)); } } return ret; } 

}

构造函数接收基本适配器和这些自定义接口的两个实现:

 public interface IFilteredListListener extends Filterable { public void onSearchResult(List objects); 

}

 public interface IFilterableItem { public String getStringForFilter(T item); 

}

希望这个具体的例子有所帮