2014-02-05 110 views
71

我需要創建從我arrayList<String>SearchView,並顯示在下拉列表中相同的建議,這實施搜索查看行動吧

enter image description here

我尋找解釋一步一步如何建立一個教程SearchView在一個操作欄中。

我已閱讀the documentation並遵循谷歌示例,但對我無用。

我創建了搜索

<?xml version="1.0" encoding="utf-8"?> 

<menu xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:id="@+id/action_search" 
      android:title="Search" 
      android:icon="@android:drawable/ic_menu_search" 
      android:showAsAction="always" 
      android:actionViewClass="android.widget.SearchView" /> 
</menu>` 

但我不知道如何設置字符串數組的參數。 我試圖在不同的Activity中檢索結果,但不起作用。

+6

您應該儘可能詳細地發佈您嘗試過的所有內容。使用示例代碼的具體問題往往會得到更快,更有意義的答案。 –

+0

@matteo可以分享代碼 – Erum

+0

查看用戶的答案 – Matteo

回答

115

爲了解決這個問題,我們花了一段時間才找到解決方案,但發現這是最簡單的方式讓它按照您描述的方式工作。有可能是更好的方式來做到這一點,但因爲你還沒有發佈你的活動代碼,我將不得不即興發揮,並假設你在你活動的開始有這樣的名單:

private List<String> items = db.getItems(); 

ExampleActivity.java

private List<String> items; 

private Menu menu; 

@Override 
@TargetApi(Build.VERSION_CODES.HONEYCOMB) 
public boolean onCreateOptionsMenu(Menu menu) { 

    getMenuInflater().inflate(R.menu.example, menu); 

    this.menu = menu; 

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 

     SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); 

     SearchView search = (SearchView) menu.findItem(R.id.search).getActionView(); 

     search.setSearchableInfo(manager.getSearchableInfo(getComponentName())); 

     search.setOnQueryTextListener(new OnQueryTextListener() { 

      @Override 
      public boolean onQueryTextChange(String query) { 

       loadHistory(query); 

       return true; 

      } 

     }); 

    } 

    return true; 

} 

// History 
@TargetApi(Build.VERSION_CODES.HONEYCOMB) 
private void loadHistory(String query) { 

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 

     // Cursor 
     String[] columns = new String[] { "_id", "text" }; 
     Object[] temp = new Object[] { 0, "default" }; 

     MatrixCursor cursor = new MatrixCursor(columns); 

     for(int i = 0; i < items.size(); i++) { 

      temp[0] = i; 
      temp[1] = items.get(i);replaced s with i as s not used anywhere. 

      cursor.addRow(temp); 

     } 

     // SearchView 
     SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); 

     final SearchView search = (SearchView) menu.findItem(R.id.search).getActionView(); 

     search.setSuggestionsAdapter(new ExampleAdapter(this, cursor, items)); 

    } 

} 

現在,你需要創建一個CursorAdapter擴展適配器:

ExampleAdapter.java

public class ExampleAdapter extends CursorAdapter { 

    private List<String> items; 

    private TextView text; 

    public ExampleAdapter(Context context, Cursor cursor, List<String> items) { 

     super(context, cursor, false); 

     this.items = items; 

    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) { 

     text.setText(items.get(cursor.getPosition())); 

    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup parent) { 

     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

     View view = inflater.inflate(R.layout.item, parent, false); 

     text = (TextView) view.findViewById(R.id.text); 

     return view; 

    } 

} 

一個更好的辦法來做到這一點是如果你的列表數據是從數據庫中,你可以通過按數據庫函數返回的Cursor直接ExampleAdapter和使用相關的列選擇顯示在引用的TextView列文在適配器中。

請注意:在導入CursorAdapter時請勿導入Android支持版本,請改爲導入標準android.widget.CursorAdapter

適配器還需要自定義佈局:

RES /佈局/ item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 

    <TextView 
     android:id="@+id/item" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 

</RelativeLayout> 

現在,您可以通過添加額外的文本或圖像視圖佈局定製列表項和用適配器中的數據填充它們。

這應該是所有的,但如果你還沒有這樣做了,你需要一個搜索查看菜單項:

RES /菜單/的example.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item 
     android:id="@+id/search" 
     android:title="@string/search" 
     android:showAsAction="ifRoom" 
     android:actionViewClass="android.widget.SearchView" /> 

</menu> 

然後創建一個可搜索的配置:

res/xml /可搜索。XML

<searchable xmlns:android="http://schemas.android.com/apk/res/android" 
    android:label="@string/search" 
    android:hint="@string/search" > 
</searchable> 

最後,在清單文件中的相關活動標籤中添加此:

AndroidManifest.xml中

<intent-filter> 
    <action android:name="android.intent.action.SEARCH" /> 
</intent-filter> 

<meta-data 
    android:name="android.app.default_searchable" 
    android:value="com.example.ExampleActivity" /> 
<meta-data 
    android:name="android.app.searchable" 
    android:resource="@xml/searchable" /> 

請注意:在示例中使用的@string/search字符串應該是定義在values/strings.xml,同樣不要忘記更新對你的引用com.example項目。

+1

嗨,但有一個疑問,我希望你能幫助我。如果我在過濾器上鍵入一個字母,雖然我有過濾器結果,但如果超過一個,將不顯示任何內容。那麼只有它顯示。爲什麼? – Naruto

+0

嗨,也許檢查您的樣式與EditText或AutoCompleteTextView相關的任何事情,因爲您可以設置默認數量的字符,需要輸入之前它會顯示自動完成。實際上,我認爲默認值是2個字符,所以可能會出現這種情況,您需要將其添加到樣式中以進行更改。 – tpbapp

+0

嗨,雖然發展我來橫跨一個問題的searchview。如果我在下拉菜單中顯示更多項目,例如:3個文字視圖,則項目大小會增加,因此如果我像http://i.stack.imgur.com/d7t3A.png一樣滾動,則搜索項目會在鍵盤上流動。如果我增加文本的大小或在項目中添加更多視圖,會發生這種情況。它是默認行爲嗎? – Naruto

35

如果其他人是否有在搜索查看變量nullptr,我發現,該項目的設置是一點點不同:

老:

android:showAsAction="ifRoom" 
android:actionViewClass="android.widget.SearchView" 

新:

app:showAsAction="ifRoom|collapseActionView" 
app:actionViewClass="android.support.v7.widget.SearchView" 

欲瞭解更多信息,它的更新文件是located here

+2

謝謝。正是我錯過了什麼。 :-) –

+0

謝謝你,這很簡單,樂於助人。 – Muhammad

0
*** 

For serachview use these code 
--------------- 

1. For XML 

<android.support.v7.widget.SearchView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/searchView"> 

    </android.support.v7.widget.SearchView> 


*** 

2. In your Fragment or Activity 

package com.example.user.salaryin; 

import android.app.ProgressDialog; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.view.MenuItemCompat; 
import android.support.v7.widget.GridLayoutManager; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.support.v7.widget.SearchView; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Toast; 

import com.example.user.salaryin.Adapter.BusinessModuleAdapter; 
import com.example.user.salaryin.Network.ApiClient; 
import com.example.user.salaryin.POJO.ProductDetailPojo; 
import com.example.user.salaryin.Service.ServiceAPI; 

import java.util.ArrayList; 
import java.util.List; 

import retrofit2.Call; 
import retrofit2.Callback; 
import retrofit2.Response; 

/** 
* Created by USer on 24-08-2017. 
*/ 

public class OneFragment extends Fragment implements SearchView.OnQueryTextListener { 

    RecyclerView recyclerView; 
    RecyclerView.LayoutManager layoutManager; 
    ArrayList<ProductDetailPojo> arrayList; 
    BusinessModuleAdapter adapter; 
    private ProgressDialog pDialog; 
    GridLayoutManager gridLayoutManager; 
    SearchView searchView; 

    public OneFragment() { 
     // Required empty public constructor 
    } 

    @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.one_fragment,container,false); 

     pDialog = new ProgressDialog(getActivity()); 
     pDialog.setMessage("Please wait..."); 


     searchView=(SearchView)rootView.findViewById(R.id.searchView); 
     searchView.setQueryHint("Search BY Brand"); 
     searchView.setOnQueryTextListener(this); 

     recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView); 
     layoutManager = new LinearLayoutManager(this.getActivity()); 
     recyclerView.setLayoutManager(layoutManager); 
     gridLayoutManager = new GridLayoutManager(this.getActivity().getApplicationContext(), 2); 
     recyclerView.setLayoutManager(gridLayoutManager); 
     recyclerView.setHasFixedSize(true); 
     getImageData(); 


     // Inflate the layout for this fragment 
     //return inflater.inflate(R.layout.one_fragment, container, false); 
     return rootView; 
    } 


    private void getImageData() { 
     pDialog.show(); 
     ServiceAPI service = ApiClient.getRetrofit().create(ServiceAPI.class); 
     Call<List<ProductDetailPojo>> call = service.getBusinessImage(); 

     call.enqueue(new Callback<List<ProductDetailPojo>>() { 
      @Override 
      public void onResponse(Call<List<ProductDetailPojo>> call, Response<List<ProductDetailPojo>> response) { 
       if (response.isSuccessful()) { 
        arrayList = (ArrayList<ProductDetailPojo>) response.body(); 
        adapter = new BusinessModuleAdapter(arrayList, getActivity()); 
        recyclerView.setAdapter(adapter); 
        pDialog.dismiss(); 
       } else if (response.code() == 401) { 
        pDialog.dismiss(); 
        Toast.makeText(getActivity(), "Data is not found", Toast.LENGTH_SHORT).show(); 
       } 

      } 

      @Override 
      public void onFailure(Call<List<ProductDetailPojo>> call, Throwable t) { 
       Toast.makeText(getActivity(), t.getMessage(), Toast.LENGTH_SHORT).show(); 
       pDialog.dismiss(); 

      } 
     }); 
    } 

    /* @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     getActivity().getMenuInflater().inflate(R.menu.menu_search, menu); 
     MenuItem menuItem = menu.findItem(R.id.action_search); 
     SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuItem); 
     searchView.setQueryHint("Search Product"); 
     searchView.setOnQueryTextListener(this); 
    }*/ 

    @Override 
    public boolean onQueryTextSubmit(String query) { 
     return false; 
    } 

    @Override 
    public boolean onQueryTextChange(String newText) { 
     newText = newText.toLowerCase(); 
     ArrayList<ProductDetailPojo> newList = new ArrayList<>(); 
     for (ProductDetailPojo productDetailPojo : arrayList) { 
      String name = productDetailPojo.getDetails().toLowerCase(); 

      if (name.contains(newText)) 
       newList.add(productDetailPojo); 
      } 
     adapter.setFilter(newList); 
     return true; 
    } 
} 

3. In adapter class 

public void setFilter(List<ProductDetailPojo> newList){ 
     arrayList=new ArrayList<>(); 
     arrayList.addAll(newList); 
     notifyDataSetChanged(); 
    } 
+1

它使用daynamic searchview使用這些代碼 –