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

时间:2014-09-02 19:58:37

标签: java android android-listview baseadapter searchview

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

目前它看起来像这样:

enter image description here

问题在于,当我用

命中它时崩溃了
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<String> 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<PackageInfo> packageList;
    TextView appnamestyle;

    Activity context;
    PackageManager packageManager;
    boolean[] itemChecked;
    HashSet checked;
    Filter mFilter;

    String PACKAGE_NAME;

    TextView appname;

    public ApkAdapter(Activity context, List<PackageInfo> 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<PackageInfo> packageList_2 = packageList;
            String prefixString = prefix.toString().toLowerCase();
            FilterResults results = new FilterResults();
            ArrayList<PackageInfo> FilteredList = new ArrayList<PackageInfo>();

            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<PackageInfo>) 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:

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layoutsearch"

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:cursorVisible="true"
    android:hint="@string/hint"
    android:imeOptions="actionDone"
    android:inputType="text"
    android:textColor="@android:color/white"
    android:textCursorDrawable="@android:color/white" />

当它明显存在时,不确定为什么会产生此错误。

1 个答案:

答案 0 :(得分:2)

-

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

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

https://github.com/matessoftwaresolutions/AndroidFilterableList

-

对我来说最简单的方法:

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

    1. 我的扩展baseAdapter实现了两个接口 (IFilteredItem和IFilteredListListener。
    2. 其内容是:

      public class MenuListAdapter extends BaseAdapter implements IFilteredListListener<PointOfInterest>, IFilterableItem<PointOfInterest> {    
      public MenuListAdapter(Context context,List<PointsOfInterest> 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<PointOfInterest>(points, this, this,this);
          }
          return filter;
      }
      
      @Override
      public void onSearchResult(List<PointOfInterest> objects) {
          if (objects.size() == 0) {
              points = objects;
              objects.add(mockedPointForEmptyList);
          } else {
              points = objects;
          }
      }
      
      @Override
      public String getStringForFilter(PointOfInterest item) {
          return item.getTitle();
      }
      ....
      

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

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

      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);
          }
      
      };
      

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

      public class ListFilter<T> extends Filter {
      
      private List<T> adapterFilterElements;
      private List<T> originalFilterElements;
      private final Object mLock = new Object();
      
      private List<String> originalFilterValues;
      private IFilteredListListener<T> listener;
      private BaseAdapter baseAdapter;
      private IFilterableItem<T> filterableItem;
      
      public ListFilter(List<T> originalElements, BaseAdapter baseAdapter, IFilteredListListener<T> listener, IFilterableItem<T> 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<String> list;
              synchronized (mLock) {
                  list = new ArrayList<String>(originalFilterValues);
              }
              results.values = list;
              results.count = list.size();
          } else {
              String prefixString = prefix.toString().toLowerCase(Locale.UK);
              ArrayList<String> values;
              synchronized (mLock) {
                  values = new ArrayList<String>(originalFilterValues);
              }
              final int count = values.size();
              final ArrayList<String> newValues = new ArrayList<String>();
              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<String>) results.values);
          listener.onSearchResult((List<T>) results.values);
          adapterFilterElements = (List<T>) results.values;
          if (results.count > 0) {
              baseAdapter.notifyDataSetChanged();
          } else {
              baseAdapter.notifyDataSetInvalidated();
          }
      }
      
      private List<T> fillItemListFromNames(List<String> names) {
          List<T> ret = new ArrayList<T>();
          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<String> fillListNamesFromItems(List<T> items) {
          List<String> ret = new ArrayList<String>();
          if (items != null) {
              for (T item : items) {
                  ret.add(filterableItem.getStringForFilter(item));
              }
          }
          return ret;
      }
      

      }

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

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

      }

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

      }

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