AlertDialog with builder.setSingleChoiceItems. Dis

2019-02-26 01:25发布

问题:

I am using the following method do set the mapType of a GoogleMap object named mMap.

private void setMapType() {
    final CharSequence[] MAP_TYPE_ITEMS =
            {"Road", "Satellite", "Hybrid"};

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Set map type");

    int checkItem = 0;

    builder.setSingleChoiceItems(
            MAP_TYPE_ITEMS,
            checkItem,
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int item) {
                        switch (item) {
                            case 0:
                                mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                                break;
                            case 1:
                                mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
                                break;
                            case 3:
                               mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                                break;
                        }

                    dialog.dismiss();
                }
            }
    );

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

}

What I am trying to do is disable one of the choices, let's say the 1st one (Road). How could I do that?

P.S.1 I read this AlertDialog with single choice list - I need some items nonclickable but I don't understand how could I make it work in my case.

P.S.2 I tried, this solution too: Android: AlertDialog - how to disable certain choices that are not available Nothing happens. All options are enabled.

回答1:

It is possible to do this in a standard AlertDialog, but using a custom list adapter. Perhaps the reason the first link you posted did not work for you is because it is important that the list items are updated prior to the dialog being populated.

Creating your dialog:

    final CharSequence[] MAP_TYPE_ITEMS =
        {"Road", "Satellite", "Hybrid"};

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Set map type");

    int checkItem = 0;



    ArrayList<Integer> list = new ArrayList<Integer>();
    //specify index 1 is disabled, 0 and 2 will be enabled as normal
    list.add(Integer.valueOf(1));
    final MyCustomAdapter adapter = new MyCustomAdapter(MAP_TYPE_ITEMS, list);
    builder.setAdapter(adapter, null );
    builder.setSingleChoiceItems(
            MAP_TYPE_ITEMS,
            checkItem,
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int item) {
                        switch (item) {
                            case 0:
                                Toast.makeText(InitialActivity.this, "Item 0 clicked ", Toast.LENGTH_SHORT).show();
                                break;
                            case 1:
                                Toast.makeText(InitialActivity.this, "Item 1 clicked ", Toast.LENGTH_SHORT).show();
                                break;
                            case 2:
                                Toast.makeText(InitialActivity.this, "Item 2 clicked ", Toast.LENGTH_SHORT).show();
                                break;
                        }
                    if( adapter.getItemViewType(item) == 0 ){
                        dialog.dismiss();
                    }
                }
            }
        );
    AlertDialog fMapTypeDialog = builder.create();
    fMapTypeDialog.show();

The custom adapter:

  private class MyCustomAdapter extends BaseAdapter {

    private ArrayList<String> mData = new ArrayList<String>();
    private ArrayList<Integer> mDisabled = new ArrayList<Integer>();
    private LayoutInflater mInflater;

    public MyCustomAdapter(CharSequence[] items, 
                           ArrayList<Integer> disabledItems) {
        mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mDisabled = disabledItems;
        for( int i = 0; i< items.length; ++i ){
            addItem( items[i].toString());
        }
    }

    public void addItem(final String item) {
        mData.add(item);

        notifyDataSetChanged();
    }

    @Override
    public int getItemViewType(int position) {
        if( mDisabled.contains(position))
            return 1; //disabled
        return 0; //enabled as normal
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

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

    @Override
    public String getItem(int position) {
        return mData.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;

        int type = getItemViewType(position);
        if (convertView == null) {
            holder = new ViewHolder();
            switch(type) {
                case 1:
                    convertView = mInflater.inflate(android.R.layout.simple_list_item_1, null);
                    holder.textView = (TextView)convertView.findViewById(android.R.id.text1);
                    convertView.setEnabled(false);
                    convertView.setClickable(false);
                    break;
                case 0:
                    convertView = mInflater.inflate(android.R.layout.simple_list_item_1, null);
                    holder.textView = (TextView)convertView.findViewById(android.R.id.text1);
                    break;
            }
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }
        holder.textView.setText(mData.get(position));
        return convertView;
    }

}


回答2:

Basically, you cann't do it, with simple AlertDialog and Builder. What you trying to do, it's exchange your Views during some interaction, but that items doesn't have such behavior.

But it isn't problem to do it with Custom Dialog. Just for Example...

                // create a Dialog component
                final Dialog dialog = new Dialog(context);

                //Tell the Dialog to use the dialog.xml as it's layout description 
                // With your own Layouts and CheckBoxs
                dialog.setContentView(R.layout.dialog);
                dialog.setTitle("Android Custom Dialog Box");

                TextView headerTextView = (TextView) dialog.findViewById(R.id.txt);
                headerTextView .setText("This is an Android custom Dialog Box Example! Enjoy!");

                Button dialogButton1 = (Button)  dialog.findViewById(R.id.dialogButton1);

                dialogButton1.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dialogButton1.setEnabled(false);
                        dialog.dismiss();
                    }
                });

                // And so on, with other buttons

                dialog.show();


回答3:

I answered a pretty similar question here. Basically you can set a listener when a view is added in a given ListView and disable it.