在android中使用edittext对ListView进行排序

Posted

技术标签:

【中文标题】在android中使用edittext对ListView进行排序【英文标题】:Sort ListView using edittext in android 【发布时间】:2015-01-30 20:09:48 【问题描述】:

我想做什么::

我正在尝试使用编辑文本搜索列表视图

发生了什么:

数据已正确填充到列表视图,但在 edittext 中输入文本时出现错误


FrgVendorsSearch.java

public class FrgVendorsSearch extends Fragment implements OnClickListener


    private String errMsg="",txtMsg="";
    private static boolean isErr=false;
    ListView lst;
    ArrayList<HashMap<String, String>> lstData;
    SearchModel searchModel;
    HashMap<String, String> mapData;
    ImageButton btnFilterId;
    EditText edtSearchId;
    String url;

    String name;
    String city;
    AdptVendorSearch adapter;
    String serverStatus,serverMessage;
    String categories;
    private ArrayList<SearchModel> _searchModel = new ArrayList<SearchModel>();

    public FrgVendorsSearch()

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

    

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) 

        View rootView = inflater.inflate(R.layout.frg_vendors_search, container, false);
        initInstances(rootView);
        return rootView;
    


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

    

    @Override
    public void onStart() 
        super.onStart();
        url=getResources().getString(R.string.vendorList_api)+"?status=1".trim();
        setOnClickListeners();


        if(CommonFunctions.isOnline(getActivity()))
            //Internet connectivity is available
            new LongOperation().execute("");
        else
            //Show the Message
            getFragmentManager().popBackStack(FrgAddNewJobs.class.getSimpleName(), getFragmentManager().POP_BACK_STACK_INCLUSIVE);
            DlgUniversalError.showQuitAlert(getActivity(), getResources().getString(R.string.connToInternetTryAgain));  
        


        edtSearchId.addTextChangedListener(new TextWatcher() 

                @Override
                public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) 
                    adapter.getFilter().filter(arg0);
                

                @Override
                public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                        int arg3) 
                

                @Override
                public void afterTextChanged(Editable arg0) 

                
            );
    


    @Override
    public void onClick(View v) 
        switch (v.getId()) 
        case R.id.btnFilterId:

            break;

        case R.id.edtSearchId:

            break;
        

    

    private class LongOperation extends AsyncTask<String, Integer, String> 


        @Override
        protected void onPreExecute() 



        


        @Override
        protected String doInBackground(String... params) 


            try 

                httpServerRequest(url);

             catch (ConnectTimeoutException e) 
                if(isErr==false)
                    errMsg=e.getLocalizedMessage();
                    isErr=true;
                
                publishProgress(1);
            catch (SocketException e) 
                if(isErr==false)
                    errMsg=e.getLocalizedMessage();
                    isErr=true;
                
                publishProgress(2);
            catch (IOException e) 
                if(isErr==false)
                    errMsg=e.getLocalizedMessage();
                    isErr=true;
                
                publishProgress(3);
             catch (JSONException e) 
                if(isErr==false)
                    errMsg=e.getLocalizedMessage();
                    isErr=true;
                
                publishProgress(4);
             catch (Exception e) 
                if(isErr==false)
                    errMsg=e.getLocalizedMessage();
                    isErr=true;
                
                publishProgress(0);
             

            return "Executed";
        

        @Override
        protected void onProgressUpdate(Integer... arrMsg) 
            if(arrMsg[0]==0)
                if(isErr==true)
                    DlgUniversalError.showQuitAlert(getActivity(),errMsg);//Pop the dialog  
                
            
            else if(arrMsg[0]==1)
                DlgUniversalError.showQuitAlert(getActivity(),getActivity().getResources().getString(R.string.connDelayTryAgainLater));//Pop the dialog 
            
            else if(arrMsg[0]==2)
                DlgUniversalError.showQuitAlert(getActivity(),getActivity().getResources().getString(R.string.connDelayTryAgainLater));//Pop the dialog 

            
            else if(arrMsg[0]==3)
                DlgUniversalError.showQuitAlert(getActivity(),getActivity().getResources().getString(R.string.connDelayTryAgainLater));//Pop the dialog 

            
            else if(arrMsg[0]==4)
                DlgUniversalError.showQuitAlert(getActivity(),errMsg);//Pop the dialog  

            

        

        @Override
        protected void onPostExecute(String result) 
            adapter=new AdptVendorSearch(getActivity(),_searchModel);
            lst.setAdapter(adapter);
        

    



    private void httpServerRequest(String _url) throws Exception 

        InputStream inputStream = null;
        InputStream response = null;
        String result = "";
        JSONObject jsonObj;
        DateFormat sdf;
        DateFormat df;
        Date startDate;
        try 
            //lstData.clear();
            HttpClient httpclient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(_url);
            //SET THE HTTP HEADERS
            httpGet.setHeader("phonenumber",AppController.getPhoneNumber());
            httpGet.setHeader("authtoken",AppController.getAuthCode());
            //SET THE HTTP PARAMS
            HttpParams httpParameters = httpGet.getParams();
            HttpConnectionParams.setConnectionTimeout(httpParameters, 10*1000);
            HttpConnectionParams.setSoTimeout(httpParameters, 10*1000);
            // 8. Execute POST request to the given URL
            HttpResponse httpResponse = httpclient.execute(httpGet);
            // 9. receive response as inputStream
            inputStream = httpResponse.getEntity().getContent();
            // 10. convert inputstream to string
            if(inputStream != null)
                result = convertInputStreamToString(inputStream);
            else
                result = "Did not work!";

            jsonObj = new JSONObject(result);

            serverStatus=jsonObj.getString("status");
            serverMessage=jsonObj.getString("message");

            if(serverMessage.equalsIgnoreCase("Done"))
                //Valid Response

                JSONArray data=jsonObj.getJSONArray("data");
                for(int i=0; i<data.length();i++)
                    mapData=new HashMap<String, String>();
                    JSONObject temp_obj = data.getJSONObject(i);

                    JSONObject userIdObj=new JSONObject(temp_obj.getString("userId"));
                    name=userIdObj.getString("name");
                    JSONObject addressIdObj=new JSONObject(temp_obj.getString("addressId"));
                    city=addressIdObj.getString("city");

                    JSONArray categoryArrObj=temp_obj.getJSONArray("sp_category");
                    StringBuilder categoryBuilder = new StringBuilder();
                    for(int j=0; j<categoryArrObj.length();j++)
                        JSONObject temp_obj_category = categoryArrObj.getJSONObject(j);
                        JSONObject jobCategoryObj=new JSONObject(temp_obj_category.getString("jobCategoryId"));
                        categoryBuilder.append(jobCategoryObj.getString("name"));
                        categoryBuilder.append(", ");
                    
                    categories=categoryBuilder.toString();

                    // Prepare the List object
                    mapData.put("name",name);
                    mapData.put("city",city);
                    mapData.put("categories",categories);

                    lstData.add(mapData);

                    SearchModel searchModel=new SearchModel();

                    searchModel.setName(name);
                    searchModel.setLocation(city);
                    searchModel.setCategory(categories);
                    _searchModel.add(searchModel);
                               


                Log.d("", "");

            else if(serverMessage.equalsIgnoreCase("Invalid Tolken"))
                //Tolken Expired
                Intent i = new Intent(getActivity(), ActMain.class);
                SharedPreferences pref = getActivity().getApplicationContext().getSharedPreferences("MyPref", 0);
                Editor editor = pref.edit();
                editor.clear();
                editor.commit();
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                startActivity(i);
            



         catch (MalformedURLException e) 
            if(isErr==false)
                errMsg=e.getLocalizedMessage();
                isErr=true;
            
            throw e;
        catch (ConnectTimeoutException e) 
            if(isErr==false)
                errMsg=e.getLocalizedMessage();
                isErr=true;
            
            throw e;
        catch (SocketException e) 
            if(isErr==false)
                errMsg=e.getLocalizedMessage();
                isErr=true;
            
            throw e;
        catch (IOException e) 
            if(isErr==false)
                errMsg=e.getLocalizedMessage();
                isErr=true;
            
            throw e;
         catch (JSONException e) 
            if(isErr==false)
                errMsg=e.getLocalizedMessage();
                isErr=true;
            
            throw e;
         catch (Exception e) 
            if(isErr==false)
                errMsg=e.getLocalizedMessage();
                isErr=true;
            
            throw e;
         
    


    private void initInstances(View rootView) 

        lstData=new ArrayList<HashMap<String,String>>();
        searchModel=new SearchModel();
        lst=(ListView) rootView.findViewById(R.id.lst);
        btnFilterId=(ImageButton) rootView.findViewById(R.id.btnFilterId);
        edtSearchId=(EditText) rootView.findViewById(R.id.edtSearchId);
    

    private void setOnClickListeners() 
        edtSearchId.setOnClickListener(this);
        btnFilterId.setOnClickListener(this);
    


    private static String convertInputStreamToString(InputStream inputStream) throws Exception
        String result = "";
        try 
            BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
            String line = "";
            result = "";
            while((line = bufferedReader.readLine()) != null)
                result += line;
            inputStream.close();
         catch (Exception e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        return result;
     


AdptVendorSearch.java

public class AdptVendorSearch extends BaseAdapter implements Filterable

    Context context;
    private ValueFilter valueFilter;
    ArrayList<SearchModel> searchModel;
    private ArrayList<SearchModel> _searchModel;
    private ArrayList<SearchModel> mStringFilterList;


    public AdptVendorSearch(Context _context, ArrayList<SearchModel> _searchModel) 
        this.context = _context;
        this._searchModel=_searchModel;
        mStringFilterList=_searchModel;
        getFilter();
    

    @Override
    public int getCount() 
        // TODO Auto-generated method stub
        return mStringFilterList.size();
    

    @Override
    public Object getItem(int position) 
        // TODO Auto-generated method stub
        return null;
    

    @Override
    public long getItemId(int position) 
        // TODO Auto-generated method stub
        return position;
    

    // our ViewHolder.
    // caches our TextView
    static class ViewHolderItem 
        TextView txtMsgNameId,txtLocationId,txtCategoryId,txtAvailId;
        RatingBar rtngId;

    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        // TODO Auto-generated method stub

        ViewHolderItem viewHolder;


        if(convertView==null)

            // inflate the layout
            LayoutInflater inflater = (LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

            convertView = inflater.inflate(R.layout.adpt_vendor_search, parent, false);
            //convertView.setMinimumHeight(30); //set minimum height of view here

            // well set up the ViewHolder
            viewHolder = new ViewHolderItem();
            viewHolder.txtMsgNameId = (TextView) convertView.findViewById(R.id.txtMsgNameId);
            viewHolder.txtLocationId = (TextView) convertView.findViewById(R.id.txtLocationId);
            viewHolder.txtCategoryId = (TextView) convertView.findViewById(R.id.txtCategoryId);
            viewHolder.txtAvailId = (TextView) convertView.findViewById(R.id.txtAvailId);
            viewHolder.rtngId = (RatingBar) convertView.findViewById(R.id.rtngId);

            // store the holder with the view.
            convertView.setTag(viewHolder);

        else
            // we've just avoided calling findViewById() on resource every time
            // just use the viewHolder
            viewHolder = (ViewHolderItem) convertView.getTag();
        


        viewHolder.txtMsgNameId.setText(_searchModel.get(position).getName());
        viewHolder.txtLocationId.setText("Location: "+_searchModel.get(position).getlocation());
        viewHolder.txtCategoryId.setText("Category: "+_searchModel.get(position).getCategory());
        //viewHolder.txtAvailId.setText("Availability: "+mapData.get("availability"));
        //viewHolder.rtngId.setRating((Float.valueOf(mapData.get("ratings"))));

        return convertView;
    

    @Override
    public Filter getFilter() 
        if(valueFilter==null) 
            valueFilter=new ValueFilter();
        
        return valueFilter;
    



    private class ValueFilter extends Filter 

        //Invoked in a worker thread to filter the data according to the constraint.
        @Override
        protected FilterResults performFiltering(CharSequence constraint) 
            FilterResults results=new FilterResults();
            if(constraint!=null && constraint.length()>0)
                ArrayList<SearchModel> filterList=new ArrayList<SearchModel>();
                //ArrayList<HashMap<String, String>> filterlstData=new ArrayList<HashMap<String, String>>();

                for(int i=0;i<mStringFilterList.size();i++)
                    if((mStringFilterList.get(i).getName().toUpperCase())
                            .contains(constraint.toString().toUpperCase())) 
                        SearchModel SearchModel = new SearchModel();
                        SearchModel.setName(mStringFilterList.get(i).getName());
                        SearchModel.setCategory(mStringFilterList.get(i).getCategory());
                        SearchModel.setLocation(mStringFilterList.get(i).getlocation());
                        filterList.add(SearchModel);
                    
                
                results.count=filterList.size();
                results.values=filterList;
            else
                results.count=mStringFilterList.size();
                results.values=mStringFilterList;
            
            return results;
        


        //Invoked in the UI thread to publish the filtering results in the user interface.
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) 
            _searchModel=(ArrayList<SearchModel>) results.values;
            notifyDataSetChanged();
        
    

日志::

12-02 19:57:07.985: E/androidRuntime(625): FATAL EXCEPTION: main
12-02 19:57:07.985: E/AndroidRuntime(625): java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
12-02 19:57:07.985: E/AndroidRuntime(625):  at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
12-02 19:57:07.985: E/AndroidRuntime(625):  at java.util.ArrayList.get(ArrayList.java:304)
12-02 19:57:07.985: E/AndroidRuntime(625):  at com.windhyaworks.adapters.AdptVendorSearch.getView(AdptVendorSearch.java:96)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.AbsListView.obtainView(AbsListView.java:2012)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.ListView.makeAndAddView(ListView.java:1772)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.ListView.fillSpecific(ListView.java:1318)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.ListView.layoutChildren(ListView.java:1603)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.AbsListView.onLayout(AbsListView.java:1863)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.View.layout(View.java:11180)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.ViewGroup.layout(ViewGroup.java:4203)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.View.layout(View.java:11180)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.ViewGroup.layout(ViewGroup.java:4203)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.View.layout(View.java:11180)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.ViewGroup.layout(ViewGroup.java:4203)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:887)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.View.layout(View.java:11180)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.ViewGroup.layout(ViewGroup.java:4203)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.View.layout(View.java:11180)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.ViewGroup.layout(ViewGroup.java:4203)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.View.layout(View.java:11180)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.ViewGroup.layout(ViewGroup.java:4203)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.View.layout(View.java:11180)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.ViewGroup.layout(ViewGroup.java:4203)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1468)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2418)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.os.Handler.dispatchMessage(Handler.java:99)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.os.Looper.loop(Looper.java:137)
12-02 19:57:07.985: E/AndroidRuntime(625):  at android.app.ActivityThread.main(ActivityThread.java:4340)
12-02 19:57:07.985: E/AndroidRuntime(625):  at java.lang.reflect.Method.invokeNative(Native Method)
12-02 19:57:07.985: E/AndroidRuntime(625):  at java.lang.reflect.Method.invoke(Method.java:511)
12-02 19:57:07.985: E/AndroidRuntime(625):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
12-02 19:57:07.985: E/AndroidRuntime(625):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
12-02 19:57:07.985: E/AndroidRuntime(625):  at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

【参考方案1】:

这个:

@Override
public int getCount() 
    // TODO Auto-generated method stub
    return mStringFilterList.size();

到:

@Override
public int getCount() 
    // TODO Auto-generated method stub
    return _searchModel.size();

因为你有:

    protected void publishResults(CharSequence constraint,
            FilterResults results) 
        _searchModel=(ArrayList<SearchModel>) results.values; // <<--- here
        notifyDataSetChanged();
    

【讨论】:

检查他的构造函数。 mStringFilterList=_searchModel;那么有什么区别呢? _searchModel=(ArrayList) results.values;此行将引用指向在 ArrayList filterList=new ArrayList(); 创建的另一个列表 mStringFilterList 仍保留原始列表。 你有没有尝试我的建议。

以上是关于在android中使用edittext对ListView进行排序的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android Studio中对包含数值的EditText字段执行基本计算

50个Android开发技巧(09 避免用EditText对日期进行验证)

Android之UI--重绘EditText以及实现Button的渐变色

Android EditText 下划线样式未显示在模拟器中

Android EditText 中背景的默认颜色渐变是啥?

Android限制EditText只能输入中文或者指定内容的实现