Spinner
的代码如下:
String[] countryNames = {"Select Country", "India", "China", "Australia", "Portugle", "America", "New Zealand"};
Spinner spinner = (Spinner) findViewById(R.id.simpleSpinner);
hintAdapter = new CustomArrayAdapter(getApplicationContext(), R.layout.simple_row,countriesList,getApplicationContext());
spinner.setAdapter(hintAdapter);
我想在Spinner
中实施搜索。
我怎样才能做到这一点?
答案 0 :(得分:10)
使用SearchableSpinner Lib,有可用的SearchableSpinner库列表,只需选择其中一个更好的https://github.com/search?utf8=%E2%9C%93&q=searchable+spinner
答案 1 :(得分:2)
转到AutocompleteTextview this example will help you
答案 2 :(得分:0)
我找到了以下解决方案here:
/**
* A modified Spinner that doesn't automatically select the first entry in the list.
*
* Shows the prompt if nothing is selected.
*
* Limitations: does not display prompt if the entry list is empty.
*/
public class NoDefaultSpinner extends Spinner {
public NoDefaultSpinner(Context context) {
super(context);
}
public NoDefaultSpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NoDefaultSpinner(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void setAdapter(SpinnerAdapter orig ) {
final SpinnerAdapter adapter = newProxy(orig);
super.setAdapter(adapter);
try {
final Method m = AdapterView.class.getDeclaredMethod(
"setNextSelectedPositionInt",int.class);
m.setAccessible(true);
m.invoke(this,-1);
final Method n = AdapterView.class.getDeclaredMethod(
"setSelectedPositionInt",int.class);
n.setAccessible(true);
n.invoke(this,-1);
}
catch( Exception e ) {
throw new RuntimeException(e);
}
}
protected SpinnerAdapter newProxy(SpinnerAdapter obj) {
return (SpinnerAdapter) java.lang.reflect.Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
new Class[]{SpinnerAdapter.class},
new SpinnerAdapterProxy(obj));
}
/**
* Intercepts getView() to display the prompt if position < 0
*/
protected class SpinnerAdapterProxy implements InvocationHandler {
protected SpinnerAdapter obj;
protected Method getView;
protected SpinnerAdapterProxy(SpinnerAdapter obj) {
this.obj = obj;
try {
this.getView = SpinnerAdapter.class.getMethod(
"getView",int.class,View.class,ViewGroup.class);
}
catch( Exception e ) {
throw new RuntimeException(e);
}
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
try {
return m.equals(getView) &&
(Integer)(args[0])<0 ?
getView((Integer)args[0],(View)args[1],(ViewGroup)args[2]) :
m.invoke(obj, args);
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
protected View getView(int position, View convertView, ViewGroup parent)
throws IllegalAccessException {
if( position<0 ) {
final TextView v =
(TextView) ((LayoutInflater)getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE)).inflate(
android.R.layout.simple_spinner_item,parent,false);
v.setText(getPrompt());
return v;
}
return obj.getView(position,convertView,parent);
}
}
}
答案 3 :(得分:0)
尝试了许多库和方法之后,我终于创建了自定义可搜索微调器。我要附加的代码处于非常初步的水平,我将在项目中进行更新。我也在写有关如何使用它的完整方法。
所有布局 searchable_spinner.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/spinner_search_bar"
android:layout_width="match_parent"
android:layout_height="35dp"
android:hint="Select A Company"
android:cursorVisible="false"
android:background="@drawable/white_rect_fillet_border"
android:paddingHorizontal="10dp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/ledger_list"
android:layout_width="match_parent"
android:layout_height="300dp"
android:visibility="gone"
android:layout_marginHorizontal="10dp"/>
</LinearLayout>
</FrameLayout>
actity_or_frag_layout.xml 请记住最后添加它,并根据您的父级布局进行对齐。
<FrameLayout
android:id="@+id/spinner_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:background="@drawable/white_rect_fillet_border"
app:layout_constraintTop_toTopOf="parent">
<include layout="@layout/searchable_spinner" />
</FrameLayout>
list_adapter_element.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TableRow>
<TextView
android:id="@+id/txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical=5dp"
android:gravity="center_vertical"/>
</TableRow>
</TableLayout>
所有可绘制对象 white_rect_fillet_border.xml
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/white"/>
<corners android:radius="5dp" />
<stroke android:color="@android:color/darker_gray"
android:width="1dp" />
</shape>
CustomListAdapter.java
public class CustomListAdapter extends
RecyclerView.Adapter<CustomListAdapter.ViewHolder> {
private final Activity context;
private Fragment fragment;
private ArrayList<LedgerListObject> ledgerlist; //replace LedgerListObject with your object or simply String everywhere in this code.
public CustomListAdapter(Activity context, Fragment fragment,
ArrayList<LedgerListObject> ledgerlist) {
this.context = context;
this.fragment = fragment;
this.ledgerlist = ledgerlist;
}
public void updateList(ArrayList<LedgerListObject> newList){
ledgerlist = newList;
notifyDataSetChanged();
}
@NonNull
@Override
public CustomListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView= inflater.inflate(R.layout.list_adapter_element, null, true);
return new ViewHolder(rowView);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
holder.txtTitle.setText(ledgerlist.get(position).LedgerName);
holder.txtTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MyFragment.LedgerID = ledgerlist.get(position).LedgerID; //MyFragment can be replaced with the name of your activity or fragment
MyFragment.ledgerListView.setVisibility(View.GONE);
MyFragment.spinnerSearch.setText(ledgerlist.get(position).LedgerName);
MyFragment.spinnerSearch.setCursorVisible(false);
}
});
}
@Override
public int getItemCount() {
return ledgerlist.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView txtTitle;
ViewHolder(@NonNull View itemView) {
super(itemView);
txtTitle = (TextView) itemView.findViewById(R.id.txt);
}
}
}
MyFragment.java
public class MyFragment extends Fragment{
ArrayList<LedgerListObject> ledgerlist = new ArrayList<LedgerListObject>();
public static int LedgerID = 0;
CustomListAdapter ledgerAdapter;
FrameLayout spinnerFrame;
public static EditText spinnerSearch;
public static RecyclerView ledgerListView;
@SuppressLint("ClickableViewAccessibility")
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState){
View root = inflater.inflate(R.layout.fragment_ledger, container, false);
super.onCreate(savedInstanceState);
spinnerFrame = root.findViewById(R.id.spinner_frame);
spinnerSearch = root.findViewById(R.id.spinner_search_bar);
ledgerListView = root.findViewById(R.id.ledger_list);
spinnerSearch.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
ledgerListView.setVisibility(View.VISIBLE);
spinnerSearch.setCursorVisible(true);
return false;
}
});
spinnerSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
try{
filter(s.toString());
}catch (Exception e){e.printStackTrace();}
}
});
GridLayoutManager listgridLayoutManager = new GridLayoutManager(getContext(), 1,
RecyclerView.VERTICAL, false);
ledgerListView.setLayoutManager(listgridLayoutManager);
//todo: your method of adding objects to your ledgerlist
ledgerAdapter = new CustomListAdapter(getActivity(), LedgerFragment.this, ledgerlist);
ledgerListView.setAdapter(ledgerAdapter);
return root;
}
}
尝试一下,如果有任何问题,请随时提出,我会解决的