android对话框单选更改项目搜索

时间:2014-02-04 13:56:16

标签: android search android-alertdialog

我在Android项目中。

我想显示一个AlertDialog,用户可以在其上选择一个项目(大约100个项目,它是动态的)。我想增加搜索的可能性。 我真正的问题是,一旦创建了Dialog,我似乎无法更改项目。 创建代码:

// The List with the beaches with radio buttons, single choice!
public void showBeachesDialog(final Activity context, boolean isFromZonas)
{
    AlertDialog.Builder builder = new AlertDialog.Builder(context);

    searchAdapter = new SearchDialogAdapater(orderedBeaches, orderedBeachesIds, context);

    builder.setSingleChoiceItems(searchAdapter, -1, new DialogInterface.OnClickListener()
    {

        @Override
        public void onClick(DialogInterface dialog, int which)
        {
            index = which;
            if (!((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE).isEnabled())
                ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
        }
    });     

    DialogOkOnClickListener listener = new DialogOkOnClickListener(context, isFromZonas);

    builder.setPositiveButton(R.string.searchOK, listener);

    builder.setNegativeButton(R.string.cancelar, new DialogInterface.OnClickListener()
    {
        public void onClick(DialogInterface dialog, int id)
        {
            // User cancelled the dialog: nothing happens
        }
    });

    builder.setIcon(context.getResources().getDrawable(R.drawable.icon_beach));
    builder.setTitle(StaticUtils.DIALOG_TITLE);

    View dialogView = context.getLayoutInflater().inflate(R.layout.dialog_beaches, null);
    SearchView searchView = (SearchView)dialogView.findViewById(R.id.search_beach);

    searchView.setOnQueryTextListener(new SearchQueryListener(searchAdapter));      

    builder.setView(dialogView);

    AlertDialog dialog = builder.create();
    dialog.show();

    dialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(false);
}

所以,现在我有了我想要的所有元素的对话框(SearchDialogAdapater很好)。 DialogOnClickListener也在工作。 搜索视图出现在对话框中,我的SearchQueryListener工作正常,所以我不会在这里发布代码,但在Debug中我可以看到,如果我输入“d”,那么没有“d”的元素就会被过滤掉。

现在我想不丢弃所有代码并找到一种方法来更改对话框的项目而不显示新的代码......

很抱歉很长的问题,如果有一种显而易见的方式我错过了......

谢谢大家。

2 个答案:

答案 0 :(得分:2)

我使用实现4个接口的类解决了这个问题,因此它可以处理我想要的所有内容。

代码现在是这样的,希望它对想要通过个性化搜索创建自己的Dialog的人有用。

public void showBeachesDialog(final Activity context, boolean isFromZonas)

{
    AlertDialog.Builder builder = new AlertDialog.Builder(context);

searchAdapter = new SearchDialogAdapater
    (orderedBeaches, orderedBeachesIds, context, isFromZonas);

builder.setSingleChoiceItems(searchAdapter, -1, null);
builder.setPositiveButton(R.string.searchOK, searchAdapter);
builder.setNegativeButton(R.string.cancelar, null);
builder.setIcon(context.getResources().getDrawable(R.drawable.icon_beach));
builder.setTitle(StaticUtils.DIALOG_TITLE);

View dialogView = context.getLayoutInflater().inflate
    (R.layout.dialog_beaches, null);

SearchView searchView = SearchView)dialogView.findViewById
(R.id.search_beach);

searchView.setOnQueryTextListener(searchAdapter);

builder.setView(dialogView);

AlertDialog dialog = builder.create();
dialog.show();

dialog.getListView().setOnItemClickListener(searchAdapter);
searchAdapter.setDialog(dialog);
dialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(false);

}

orderedBeaches和orderedBeachesIds是String []和int [],我要显示的数据。 下面是我的适配器,它使用堆栈来处理搜索中任何时刻可用的项目:

public class SearchDialogAdapater implements ListAdapter, OnQueryTextListener,
OnItemClickListener, OnClickListener {
protected Stack<String[]> stackBeaches;
protected Stack<int[]> stackBeachesIds;

protected Activity context;
protected TreeMap<String, Integer> orderedBeaches;

protected ListView listView;

protected String lastFilter = "";

public SearchDialogAdapater(String[] bs, int[] bIds, Activity cont) {
this.stackBeaches = new Stack<String[]>();
this.stackBeachesIds = new Stack<int[]>();
this.stackBeaches.push(bs);
this.stackBeachesIds.push(bIds);
this.context = cont;
}

@Override
public boolean onQueryTextChange(String newText) {
filter(newText);
this.listView.setAdapter(this);
return true;
}

public void filter(String search) {
// no longer valid the previous selected, must clean selections
selectedPosition = -1;
lastView = null;
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
// hitted "backspace"
if (search.length() < lastFilter.length()) {
    if (stackBeaches.size() > 1) {
    stackBeaches.pop();
    stackBeachesIds.pop();
    }
    lastFilter = search;
    return;
}

// filter
ArrayList<String> filtBs = new ArrayList<String>();
ArrayList<Integer> filtBsIds = new ArrayList<Integer>();

for (int i = 0; i < stackBeaches.peek().length; i++) {
    String beach = new String(stackBeaches.peek()[i]);

    if (Pattern
        .compile(Pattern.quote(search), Pattern.CASE_INSENSITIVE)
        .matcher(beach).find()) {
    filtBs.add(beach);
    filtBsIds.add(stackBeachesIds.peek()[i]);
    }
}

String[] beaches = new String[filtBs.size()];
int[] ids = new int[filtBsIds.size()];
int size = filtBs.size();
for (int i = 0; i < size; i++) {
    ids[i] = filtBsIds.remove(0);// head
    beaches[i] = filtBs.remove(0);
}

stackBeachesIds.push(ids);
stackBeaches.push(beaches);

lastFilter = search;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
    String beach = stackBeaches.peek()[position];

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

    convertView = inflater.inflate(R.layout.dialog_item, null);
    TextView txtBeach = (TextView) convertView
        .findViewById(R.id.dialBeach);
    txtBeach.setText(beach);
}

if (position == selectedPosition)// the same color below
    convertView.setBackgroundColor(Color.argb(128, 0, 64, 192));

return convertView;
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return stackBeachesIds.peek()[position];
}

@Override
public int getCount() {
return stackBeaches.peek().length;
}

@Override
public boolean isEmpty() {
return stackBeaches.peek().length == 0;
}

private View lastView;
private int selectedPosition = -1;

@Override
public void onItemClick(AdapterView<?> adapterView, View view,
    int position, long arg3) {
// some color...
view.setBackgroundColor(Color.argb(128, 133, 181, 255));
selectedPosition = position;
if (lastView != null)
    lastView.setBackground(null);
lastView = view;

((SurfApplication) context.getApplication()).setBeachId(stackBeachesIds
    .peek()[position]);

if (!dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled())
    dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
}

protected AlertDialog dialog;

public void setDialog(AlertDialog dial) {
this.dialog = dial;
this.listView = dialog.getListView();
}

@Override
public void onClick(DialogInterface dialog, int which) {
((ProgressBar) context.findViewById(R.id.pBar))
    .setVisibility(ProgressBar.VISIBLE);
int beachId = stackBeachesIds.peek()[selectedPosition];
String beach = stackBeaches.peek()[selectedPosition];

// do something... Here I am creating a new Intent and starting
// the new activity within my context
}

}

这里没有相同的方法,因为它们返回null或什么都不做。 很抱歉很长的帖子,但我需要正确回答。

谢谢大家,我希望有人觉得这很有用。

答案 1 :(得分:1)

您的适配器需要实现Filterable或从适配器类扩展。已经实现此接口的适配器(如ArrayAdapter)应自动为您进行过滤。

只需调用Adapter.getFilter()。filter(...);使用搜索视图中的值。