2014-01-06 59 views
1

我遇到了搜索過濾器的問題。我有一個自定義ListView與圖像和幾個字符串。當我開始搜索出現搜索的對象時,但ListView中的其他字符串保持在同一位置。我附上照片,所以你可以看到它的麪糊。你有什麼想法,如何解決這個問題?非常感謝:)(代碼如下所示)搜索前搜索過濾器在ListView中出現奇怪的問題

我的ListView: description

我的搜索後的ListView: description

我的適配器:

public class AnimalAdapter extends ArrayAdapter<Animal> implements Filterable{ 
    private Context mContext; 
    private List<Animal> mAnimals; 
    ImageLoader imageLoader; 
    DisplayImageOptions options; 
    Activity activity; 
    AnimalAdapter adapter; 
    private Filter animalFilter; 
    private List<Animal> animaly; 

    @SuppressWarnings("deprecation") 
    public AnimalAdapter(Context context, List<Animal> objects) { 
      super(context, R.layout.animal_row_item, objects); 


      ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context).build(); 

      imageLoader = ImageLoader.getInstance(); 
      imageLoader.init(config); 
      options = new DisplayImageOptions.Builder() 
      .cacheInMemory() 
      .cacheOnDisc() 
      .build(); 

      this.mContext = context; 
      this.mAnimals = objects; 
      this.animaly = objects; 

     } 

    public View getView(int position, View convertView, ViewGroup parent){ 
      if(convertView == null){ 
       LayoutInflater mLayoutInflater = LayoutInflater.from(mContext); 
       convertView = mLayoutInflater.inflate(R.layout.animal_row_item, null); 
      } 


      final Animal animal = mAnimals.get(position); 


      TextView animalView = (TextView) convertView.findViewById(R.id.animal_text); 
      TextView areaView = (TextView) convertView.findViewById(R.id.area_text); 

      final ImageView animalPic = (ImageView)convertView.findViewById(R.id.animal_pic); 
      final ProgressBar indicator = (ProgressBar)convertView.findViewById(R.id.progress); 

      indicator.setVisibility(View.VISIBLE); 
      animalPic.setVisibility(View.INVISIBLE); 

      //Setup a listener we can use to switch from the loading indicator to the Image once it's ready 
      ImageLoadingListener listener = new ImageLoadingListener(){ 



       @Override 
       public void onLoadingStarted(String arg0, View arg1) { 
        // TODO Auto-generated method stub 

       } 

       @Override 
       public void onLoadingCancelled(String arg0, View arg1) { 
        // TODO Auto-generated method stub 

       } 

       @Override 
       public void onLoadingComplete(String arg0, View arg1, Bitmap arg2) { 
        indicator.setVisibility(View.INVISIBLE); 
        animalPic.setVisibility(View.VISIBLE); 
       } 

       @Override 
       public void onLoadingFailed(String arg0, View view, FailReason arg2) { 


       } 

      }; 

      imageLoader.displayImage(getItem(position).getImgUrl(), animalPic,options, listener); 
      animalView.setText(animal.getAnimal()); 
      areaView.setText(animal.getArea()); 


      convertView.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View view) { 

        Intent intent = new Intent(getContext(), MoreActivity.class); 

        intent.putExtra("about", animal.getAbout()); 
        intent.putExtra("animal", animal.getAnimal()); 
        intent.putExtra("imgUrl", animal.getImgUrl()); 
        getContext().startActivity(intent); 
       } 
      }); 

      return convertView; 
     } 




    public int getCount() { 
     return mAnimals.size(); 


    @Override 
    public Filter getFilter() { 
      if (animalFilter == null) 
        animalFilter = new AnimalFilter(); 

      return animalFilter; 
} 
} 

    private class AnimalFilter extends Filter { 



     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 

      FilterResults results = new FilterResults(); 
       // We implement here the filter logic 
       if (constraint == null || constraint.length() == 0) { 
         // No filter implemented we return all the list 
         results.values = animaly; 
         results.count = animaly.size(); 

       } 
       else { 
         // We perform filtering operation 
         List<Animal> nAnimalList = new ArrayList<Animal>(); 
         final int count = nAnimalList.size(); 
         for (Animal p : mAnimals) { 
           if (p.getAnimal().toUpperCase(Locale.getDefault()).startsWith(constraint.toString().toUpperCase())) 

            nAnimalList.add(p); 


         } 

         results.values = nAnimalList; 
         results.count = nAnimalList.size(); 
       } 
       return results; 
     } 

     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence constraint, 
         FilterResults results) { 

       // Now we have to inform the adapter about the new list filtered 
       if (results.count == 0) 
         notifyDataSetInvalidated(); 
       else { 
         mAnimals = (List<Animal>) results.values; 
         notifyDataSetChanged(); 
       } 

     } 

} 


} 

Animal.java

@ParseClassName("Animal") 
public class Animal extends ParseObject{ 

    public Animal(){ 

     } 

     public String getAnimal(){ 
      return getString("animal"); 
     } 

     public void setAnimal(String animal){ 
      put("animal", animal); 
     } 

     public String getArea(){ 
      return getString("area"); 
     } 

     public void setArea(String area){ 
      put("area", area); 
     } 

     public String getImgUrl(){ 
      return getString("imgUrl"); 
     } 

     public void setImgUrl(String imgUrl){ 
      put("imgUrl", imgUrl); 
     } 

     public String getAbout(){ 
      return getString("about"); 
     } 

     public void setAbout(String about){ 
      put("about", about); 
     } 

} 

MainActivity.java(現在不是很重要,我想)

public class MainActivity extends ActionBarActivity{ 
    private ListView mListView; 
    private AnimalAdapter mAdapter; 
    ProgressBar mProgressBar; 
    EditText mEditText; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     // Add your initialization code here 
     Parse.initialize(this, "code", "code"); 
     ParseObject.registerSubclass(Animal.class); 
     ParseAnalytics.trackAppOpened(getIntent()); 
     View header = getLayoutInflater().inflate(R.layout.header, null); 
     header.setPadding(2, 8, 4, 2); 



     mListView = (ListView) findViewById(R.id.animal_list); 
     mListView.setVisibility(View.INVISIBLE); 

     mListView.addHeaderView(header); 


     mProgressBar = (ProgressBar) findViewById (R.id.loading_animals); 
     mProgressBar.setVisibility(View.VISIBLE); 





     RemoteDataTask task = new RemoteDataTask(); 
     task.execute(); 




    } 








    public void updateData(){ 


     ParseQuery<Animal> query = ParseQuery.getQuery(Animal.class); 
     query.setCachePolicy(CachePolicy.CACHE_THEN_NETWORK); 
    query.orderByAscending("animal"); 
     query.findInBackground(new FindCallback<Animal>() { 

      @Override 
      public void done(List<Animal> animals, ParseException error) { 

       if(animals != null){ 
        mAdapter.clear(); 
       mProgressBar.setVisibility(View.INVISIBLE); 
       for (int i = 0; i < animals.size(); i++) { 

         mAdapter.add(animals.get(i)); 


        } 


       } 



      } 
     }); 
    } 


    @Override 
     public boolean onCreateOptionsMenu(Menu menu) { 
      // Inflate the menu; this adds items to the action bar if it is present. 
      getMenuInflater().inflate(R.menu.main, menu); 
      return true; 
     } 


     public boolean onOptionsItemSelected(MenuItem item) { 
      switch (item.getItemId()) { 
       case R.id.action_refresh: 
        Intent refreshIntent = new Intent(MainActivity.this, MainActivity.class); 
        refreshIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); 
        refreshIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

        startActivity(refreshIntent); 
        overridePendingTransition(0,0); 
         return true; 
       } 
      return super.onOptionsItemSelected(item); 
     } 



     private class RemoteDataTask extends AsyncTask<Void, Void, Void> { 




      @Override 
       protected void onPreExecute() { 
        super.onPreExecute(); 
        // Create a progressdialog 





       } 


      @Override 
       protected Void doInBackground(Void... params) { 

        updateData(); 


        return null; 
       } 


      @Override 
       protected void onPostExecute(Void result) { 

       mListView = (ListView) findViewById(R.id.animal_list); 
        // Pass the results into ListViewAdapter.java 
       mAdapter = new AnimalAdapter(MainActivity.this, new ArrayList<Animal>()); 


        mListView.setAdapter(mAdapter); 
        mListView.setVisibility(View.VISIBLE); 
        mListView.setTextFilterEnabled(true); 

        mEditText = (EditText) findViewById(R.id.search_animal); 
         mEditText.addTextChangedListener(new TextWatcher(){ 

         @Override 
         public void afterTextChanged(Editable s) { 
          mListView.setVisibility(View.VISIBLE); 

         } 

         @Override 
         public void beforeTextChanged(CharSequence s, 
           int start, int count, int after) { 
          mListView.setVisibility(View.VISIBLE); 

         } 

         @Override 
         public void onTextChanged(CharSequence s, int start, 
           int before, int count) { 
          mListView.setVisibility(View.VISIBLE); 
          System.out.println("Text ["+s+"]"); 
          mAdapter.getFilter().filter(s.toString()); 


         } 
        }); 

         } 

      } 

     } 
+0

分享您的notifyDataSetChanged方法。另外,爲什麼你不再填充你的ListView?刪除現有的並在搜索後創建新的。 – slhddn

+0

我沒有定義notifyDataSetChanged方法。你是怎麼意思再次添加ListView的?像mAdapter.clear()等? – marson

回答

0

剛剛解決了它。我只將imageLoader.displayImage(getItem(position).getImgUrl(), animalPic,options, listener);更改爲imageLoader.displayImage(animaly.getImgUrl(), animalPic,options, listener);

+0

只需添加:由於適配器的內在性能優化,通常會發生此類錯誤。 Web中的大多數實現嘗試將視圖回收,而不是垃圾郵件findViewByID,並使ListView超慢。這最終導致程序員必須爲複雜的項目佈局執行大量的視圖「內存管理」,並且在getView中明確地詳細描述何時允許重新使用或創建新視圖,而不是單獨地向佈局本身。 Protip:保持ListView行儘可能簡單 – leRobot