2015-03-02 90 views
0

我已經根據SearchView輸入實現了精確的ONE ListView(帶有附加頭)過濾。現在我打算讓SearchView篩選多個ListView,我想知道如何去做。我卡住了,沒有任何想法。過濾的主要原理是這樣的: 我們有幾個類別(即住宿,感興趣的地方),它們作爲標題(基本上是類別的圖片)顯示,併爲每個類別附上ListView。當用戶輸入搜索查詢時,應用程序需要立即過濾所有ListView。窗口的結構是這樣的:通過SearchView過濾多個ListViews

- >標題當前類別的

的ListView#1

當用戶進入輸入,則顯示所有可用的類別和所述過濾器被應用於它們:

- >頭當前類別的

過濾的ListView#1

- >標題#2

過濾的ListView#2

...

- >標題#8

過濾的ListView#8

我尋求執行這種清晰的/最天才要比的方式。值得一提的是,我們知道類別的確切數量。

我發佈了我的代碼片段(ONE ListView(帶有標題附加)根據SearchView輸入過濾)。此外,如果搜索沒有返回結果,我會打印該消息,以便用戶如果願意,可以與我們聯繫。 list_header.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical"> 

    <LinearLayout 
     android:id="@+id/top" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginBottom="10dp" 
     android:layout_weight="1" 
     android:gravity="center"> 

     <View 
      android:id="@+id/line_left1" 
      android:layout_width="0dp" 
      android:layout_height="1dp" 
      android:layout_weight="0.45" 
      android:background="#FFFFFF" /> 

     <ImageView 
      android:id="@+id/small_icon" 
      android:layout_width="60dp" 
      android:layout_height="80dp" 
      android:layout_weight="0.1" 
      android:src="@drawable/pavalgyk" /> 

     <View 
      android:id="@+id/line_left2" 
      android:layout_width="0dp" 
      android:layout_height="1dp" 
      android:layout_weight="0.45" 
      android:background="#FFFFFF" /> 

    </LinearLayout> 
</LinearLayout> 

alllists.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    android:paddingBottom="5dp" 
    android:background="@drawable/background" 
    android:paddingLeft="5dp" 
    android:paddingRight="5dp" 
    android:paddingTop="5dp"> 


    <ListView 
     android:id="@+id/list" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" /> 

    <RelativeLayout 
     android:id="@+id/relativeLayout" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <TextView 
      android:layout_centerHorizontal="true" 
      android:layout_alignParentTop="true" 
      android:background="@drawable/card" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="@string/search_window_text" 
      android:textSize="16dp" 
      android:textStyle="normal" 
      android:autoLink="email" 
      android:fontFamily="sans-serif-light" /> 

    </RelativeLayout> 
</LinearLayout> 

AllLists.java

public class AllLists extends android.support.v4.app.Fragment { 

    private TypedArray navMenuIcons; 
    private Context context = null; 
    private int position = 0; 
    private String location; 
    private List<Item> items = new ArrayList<Item>(); 
    private List<Item> tmp_items = new ArrayList<Item>(); 
    private ListView listView; 
    private CustomListAdapter adapter; 
    private SearchView mSearchView; 
    private String tmp_s = ""; 
    private static Locale myLocale; 
    private EasyTracker easyTracker = null; 
    private RelativeLayout relativeLayout; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.alllists, container, false); 
     View header = inflater.inflate(R.layout.list_header, null); 
     ImageView image = (ImageView) header.findViewById(R.id.small_icon); 
     relativeLayout = (RelativeLayout) rootView.findViewById(R.id.relativeLayout); 
     relativeLayout.setVisibility(View.GONE); 
     setLanguage(); 
     navMenuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons); 
     Bundle bundle = getArguments(); 
     position = bundle.getInt("position"); 
     location = bundle.getString("location"); 
     image.setImageDrawable(navMenuIcons.getDrawable(position)); 
     context = getActivity().getApplicationContext(); 
     easyTracker = EasyTracker.getInstance(context); 
     DatabaseHandler db = new DatabaseHandler(context); 
     items = db.getAllItems(location); 
     tmp_items = db.getAllItems(location); 
     listView = (ListView) rootView.findViewById(R.id.list); 
     adapter = new CustomListAdapter(context, items); 
     listView.addHeaderView(header, "", false); 
     listView.setAdapter(adapter); 
     listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int list_position, long id) { 
       easyTracker.send(MapBuilder.createEvent("List", 
         location, adapter.getItems().get(list_position - 1).getName(), null).build()); 
       if (location.equals("accommodation") || location.equals("eat") || location.equals("events") 
         || location.equals("entertainment") || location.equals("places") || location.equals("cinema")) { 
        Intent i = new Intent(context, ItemScreen.class); 
        i.putExtra("position", list_position - 1); 
        i.putExtra("location", location); 
        i.putExtra("name", adapter.getItems().get(list_position - 1).getRealName()); 
        startActivity(i); 
       } else if (location.equals("taxi")) { 
        Intent intent = new Intent(Intent.ACTION_DIAL); 
        intent.setData(Uri.parse("tel:" + adapter.getItems().get(list_position - 1).getType())); 
        PackageManager manager = context.getPackageManager(); 
        List<ResolveInfo> infos = manager.queryIntentActivities(intent, 0); 
        if (infos.size() > 0) 
         startActivity(intent); 
        else 
         Toast.makeText(context, R.string.cant_handle, Toast.LENGTH_SHORT).show(); 
       } 
      } 
     }); 
     setHasOptionsMenu(true); 
     return rootView; 
    } 

    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     super.onCreateOptionsMenu(menu, inflater); 
     MenuItem searchItem = menu.findItem(R.id.action_search); 
     mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem); 
     mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 
      @Override 
      public boolean onQueryTextSubmit(String s) { 
       return false; 
      } 

      @Override 
      public boolean onQueryTextChange(String s) { 
       easyTracker.send(MapBuilder.createEvent("Search", 
         "search", s, null).build()); 
       if (TextUtils.isEmpty(s)) { 
        adapter = new CustomListAdapter(context, tmp_items); 
        listView.setAdapter(adapter); 
       } 
       if (tmp_s.length() > s.length()) { 
        adapter.getFilter(tmp_items, true).filter(s, new Filter.FilterListener() { 
         public void onFilterComplete(int count) { 
          if (count == 0) 
           relativeLayout.setVisibility(View.VISIBLE); 
          else 
           relativeLayout.setVisibility(View.GONE); 
         } 
        }); 
       } else { 
        adapter.getFilter(tmp_items, false).filter(s, new Filter.FilterListener() { 
         @Override 
         public void onFilterComplete(int count) { 
          if (count == 0) 
           relativeLayout.setVisibility(View.VISIBLE); 
          else 
           relativeLayout.setVisibility(View.GONE); 
         } 
        }); 
       } 
       tmp_s = s; 
       return false; 
      } 
     }); 
    } 

    @Override 
    public void onPrepareOptionsMenu(Menu menu) { 
     super.onPrepareOptionsMenu(menu); 
     mSearchView.setQuery("", false); 
    } 
} 

CustomListAdapted.java

public class CustomListAdapter extends BaseAdapter { 

    private Context context; 
    private List<Item> items; 
    private LayoutInflater inflater; 
    private ImageLoader imageLoader = AppController.getInstance().getImageLoader(); 

    public CustomListAdapter(Context context, List<Item> items) { 
     this.context = context; 
     this.items = items; 
    } 

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

    @Override 
    public Object getItem(int position) { 
     return items.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     if (inflater == null) 
      inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     if (convertView == null) 
      convertView = inflater.inflate(R.layout.list_item, null); 
     if (imageLoader == null) 
      imageLoader = AppController.getInstance().getImageLoader(); 
     NetworkImageView image = (NetworkImageView) convertView.findViewById(R.id.image); 
     TextView name = (TextView) convertView.findViewById(R.id.name); 
     TextView type = (TextView) convertView.findViewById(R.id.type); 
     Item i = items.get(position); 

     image.setImageUrl(i.getIcon(), imageLoader); 
     if(items.get(0).getName().contains("taksi")) 
      image.setDefaultImageResId(R.drawable.telefonas); 
     else 
      image.setDefaultImageResId(R.drawable.be_fono); 
     name.setText(i.getRealName()); 
     type.setText(i.getType()); 
     return convertView; 
    } 

    public List<Item> getItems(){ 
     return items; 
    } 

    public Filter getFilter(final List<Item> all_items, final boolean deleted) { 
     return new Filter() { 
      @Override 
      protected FilterResults performFiltering(CharSequence charSequence) { 
       FilterResults results = new FilterResults(); 
       if (charSequence == null || charSequence.length() == 0) { 
        results.values = items; 
        results.count = items.size(); 
       } else { 
        List<Item> filtered_items = new ArrayList<Item>(); 
        if(deleted) 
         items = all_items; 
        for (int i = 0; i < items.size(); i++) { 
         String modifiedName = items.get(i).getRealName().toLowerCase(); 
         String modifiedQuery = charSequence.toString().toLowerCase(); 
         modifiedName = encode_lithuanian(modifiedName); 
         modifiedQuery = encode_lithuanian(modifiedQuery); 
         if (modifiedName.contains(modifiedQuery)) 
          filtered_items.add(items.get(i)); 
        } 
        results.values = filtered_items; 
        results.count = filtered_items.size(); 
       } 
       return results; 
      } 

      @Override 
      protected void publishResults(CharSequence charSequence, FilterResults filterResults) { 
       items = (List<Item>) filterResults.values; 
       notifyDataSetChanged(); 
      } 

      public int show_size(){ 
       return items.size(); 
      } 
     }; 
    } 
} 

回答

0

創建不同的列表視圖適配器。 然後在edittext中,aftertextchange偵聽器爲所有適配器應用文本過濾器。看一看:

http://www.androidbegin.com/tutorial/android-search-listview-using-filter/

adapter1 = new ListViewAdapter(this, arraylist1); 
list1.setAdapter(adapter1); 
adapter2 = new ListViewAdapter(this, arraylist2); 
list2.setAdapter(adapter2);  

editsearch.addTextChangedListener(new TextWatcher() { 

@Override 
public void afterTextChanged(Editable arg0) { 
    //TODO Auto-generated method stub 
    String text = editsearch.getText().toString().toLowerCase(Locale.getDefault()); 
    adapter1.filter(text); 
    adapter2.filter(text); 
    .... 
} 
0

@ Riasat的回答啓發了我,我認爲這可能是可能做到這一點,沒有任何代碼重複:當然每個列表視圖,你就會有一個適配器與或多或少是一樣的。但創建一個通告程序可能會很好,它會對所有適配器進行刷新。喜歡的東西:

的接口去遠一點作爲你唯一的要求:

/** 
* Created by laurentmeyer on 03/03/15. 
*/ 
public interface RefreshInterface { 
    void refresh(); 
    void searchForText(String searchedText); 
    void searchWithSomethingElse(Object SomethingElse); 
} 

然後修改了一下適配器:

import android.content.Context; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.Filter; 
import android.widget.Filterable; 

/** 
* Created by laurentmeyer on 03/03/15. 
*/ 
public class CustomListAdapter extends BaseAdapter implements RefreshInterface{ 
    private Context context; 
    private List<Item> items; 
    private LayoutInflater inflater; 
    private ImageLoader imageLoader = AppController.getInstance().getImageLoader(); 

    public CustomListAdapter(Context context, List<Item> items) { 
     this.context = context; 
     this.items = items; 
    } 

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

    @Override 
    public Object getItem(int position) { 
     return items.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     if (inflater == null) 
      inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     if (convertView == null) 
      convertView = inflater.inflate(R.layout.list_item, null); 
     if (imageLoader == null) 
      imageLoader = AppController.getInstance().getImageLoader(); 
     NetworkImageView image = (NetworkImageView) convertView.findViewById(R.id.image); 
     TextView name = (TextView) convertView.findViewById(R.id.name); 
     TextView type = (TextView) convertView.findViewById(R.id.type); 
     Item i = items.get(position); 

     image.setImageUrl(i.getIcon(), imageLoader); 
     if(items.get(0).getName().contains("taksi")) 
      image.setDefaultImageResId(R.drawable.telefonas); 
     else 
      image.setDefaultImageResId(R.drawable.be_fono); 
     name.setText(i.getRealName()); 
     type.setText(i.getType()); 
     return convertView; 
    } 

    public List<Item> getItems(){ 
     return items; 
    } 

    public Filter getFilter(final List<Item> all_items, final boolean deleted) { 
     return new Filter() { 
      @Override 
      protected FilterResults performFiltering(CharSequence charSequence) { 
       FilterResults results = new FilterResults(); 
       if (charSequence == null || charSequence.length() == 0) { 
        results.values = items; 
        results.count = items.size(); 
       } else { 
        List<Item> filtered_items = new ArrayList<Item>(); 
        if(deleted) 
         items = all_items; 
        for (int i = 0; i < items.size(); i++) { 
         String modifiedName = items.get(i).getRealName().toLowerCase(); 
         String modifiedQuery = charSequence.toString().toLowerCase(); 
         modifiedName = encode_lithuanian(modifiedName); 
         modifiedQuery = encode_lithuanian(modifiedQuery); 
         if (modifiedName.contains(modifiedQuery)) 
          filtered_items.add(items.get(i)); 
        } 
        results.values = filtered_items; 
        results.count = filtered_items.size(); 
       } 
       return results; 
      } 

      @Override 
      protected void publishResults(CharSequence charSequence, FilterResults filterResults) { 
       items = (List<Item>) filterResults.values; 
       notifyDataSetChanged(); 
      } 

      public int show_size(){ 
       return items.size(); 
      } 
     }; 
    } 

    // What you'll do when you'll want to refresh (why not?) 
    @Override 
    public void refresh() { 

    } 

    // What you'll do when you'll want to search from SearchView 
    @Override 
    public void searchForText(String searchedText) { 
    } 

    // What you'll do when you'll want to have a look with another cool Object like a LatLong or some other stuff (optional, of course) 
    @Override 
    public void searchWithSomethingElse(Object SomethingElse) { 

    } 
} 

然後你的片段也將改變一些,但不如在其他解決方案中那麼多:

import java.util.ArrayList; 

/** 
* Created by laurentmeyer on 03/03/15. 
*/ 
public class AllLists extends android.support.v4.app.Fragment { 

    private TypedArray navMenuIcons; 
    private Context context = null; 
    private int position = 0; 
    private String location; 
    private List<Item> items = new ArrayList<Item>(); 
    private List<Item> tmp_items = new ArrayList<Item>(); 
    private ListView listView; 
    private CustomListAdapter adapter; 
    private SearchView mSearchView; 
    private String tmp_s = ""; 
    private static Locale myLocale; 
    private EasyTracker easyTracker = null; 
    private RelativeLayout relativeLayout; 
    /* 
    Here is a modification 
    */ 
    // Create a ArrayList containing all the adapters (which are directly connected to the listViews) 
    // which will need to be refreshed by the search view. I made it static because maybe you can use 
    // it in other instances and it could be easier. 
    public static ArrayList<RefreshInterface> toBeRefreshed; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.alllists, container, false); 
     View header = inflater.inflate(R.layout.list_header, null); 
     ImageView image = (ImageView) header.findViewById(R.id.small_icon); 
     relativeLayout = (RelativeLayout) rootView.findViewById(R.id.relativeLayout); 
     relativeLayout.setVisibility(View.GONE); 
     setLanguage(); 
     navMenuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons); 
     Bundle bundle = getArguments(); 
     position = bundle.getInt("position"); 
     location = bundle.getString("location"); 
     image.setImageDrawable(navMenuIcons.getDrawable(position)); 
     context = getActivity().getApplicationContext(); 
     easyTracker = EasyTracker.getInstance(context); 
     DatabaseHandler db = new DatabaseHandler(context); 
     items = db.getAllItems(location); 
     tmp_items = db.getAllItems(location); 
     listView = (ListView) rootView.findViewById(R.id.list); 
     adapter = new CustomListAdapter(context, items); 
     /* 
     Here is a modification 
     */ 
     toBeRefreshed.add(adapter); 
     listView.addHeaderView(header, "", false); 
     listView.setAdapter(adapter); 
     listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int list_position, long id) { 
       easyTracker.send(MapBuilder.createEvent("List", 
         location, adapter.getItems().get(list_position - 1).getName(), null).build()); 
       if (location.equals("accommodation") || location.equals("eat") || location.equals("events") 
         || location.equals("entertainment") || location.equals("places") || location.equals("cinema")) { 
        Intent i = new Intent(context, ItemScreen.class); 
        i.putExtra("position", list_position - 1); 
        i.putExtra("location", location); 
        i.putExtra("name", adapter.getItems().get(list_position - 1).getRealName()); 
        startActivity(i); 
       } else if (location.equals("taxi")) { 
        Intent intent = new Intent(Intent.ACTION_DIAL); 
        intent.setData(Uri.parse("tel:" + adapter.getItems().get(list_position - 1).getType())); 
        PackageManager manager = context.getPackageManager(); 
        List<ResolveInfo> infos = manager.queryIntentActivities(intent, 0); 
        if (infos.size() > 0) 
         startActivity(intent); 
        else 
         Toast.makeText(context, R.string.cant_handle, Toast.LENGTH_SHORT).show(); 
       } 
      } 
     }); 
     setHasOptionsMenu(true); 
     return rootView; 
    } 

    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     super.onCreateOptionsMenu(menu, inflater); 
     MenuItem searchItem = menu.findItem(R.id.action_search); 
     mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem); 
     mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 
      @Override 
      public boolean onQueryTextSubmit(String s) { 
       return false; 
      } 

      @Override 
      public boolean onQueryTextChange(String s) { 
       easyTracker.send(MapBuilder.createEvent("Search", 
         "search", s, null).build()); 
       if (TextUtils.isEmpty(s)) { 
        adapter = new CustomListAdapter(context, tmp_items); 
        listView.setAdapter(adapter); 
       } 
       if (tmp_s.length() > s.length()) { 
        /* 
        Here call the logic you implemented in your adapter functions like: 
        for (RefreshInterface r : toBeRefreshed){ 
         r.filter(String) 
        } 
        */ 
       } else { 
        /* 
        Same as above 
        */ 
       } 
       tmp_s = s; 
       return false; 
      } 
     }); 
    } 

    @Override 
    public void onPrepareOptionsMenu(Menu menu) { 
     super.onPrepareOptionsMenu(menu); 
     mSearchView.setQuery("", false); 
    } 
}