I have implemented Custom Spinner using Button following wildnove's answer. Everything works fine, but I am not able to display the highlighted radio button for the selected button.
Below is the code.
((Button) findViewById(R.id.btnSpinnerPlanets)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// How to highlight Radio button of a selected Item???
final String[] items = view.getResources().getStringArray(R.array.planets__entries);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MyFormActivity.this, android.R.layout.simple_spinner_dropdown_item, items);
new AlertDialog.Builder(MyFormActivity.this).setTitle("the prompt").setAdapter(adapter, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
((Button) findViewById(R.id.btnSpinnerPlanets)).setText(items[which]);
dialog.dismiss();
}
}).create().show();
}
});
Can somebody help me how to highlight selected Item's Radio button ...
Unfortunately this behavior is not natively implemented in Spinner component, however, you can always create your own BaseAdapter to show whatever you need weather is in the spinner it self or in the dropdown like this:
private class ExampleAdapter extends BaseAdapter{
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int arg0) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//Here is where you actually get the chance to return whatever you want in the spinner component (the single bar with the arrow)
return yourCommonView;
}
#Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
//Here is where you get the chance to return whatever you want in the dropdown menu so here you should validate what's the currently selected element and return an image accordingly...
return yourSelectedView;
}
}
The important method here is, getDropDownView that is the one that gives you the chance to return an element with a checked CheckBox, or any mark you want to use, of course you have to create your own layout and validate if the element currently created need to be marked or not...
Regards!
The problem with this code is that you are creating the Spinner each time the Button is clicked. Try the following code:
#Override
protected Dialog onCreateDialog(int id) {
Dialog dialog;
AlertDialog.Builder builder;
switch(id) {
case 1:
Button b=((Button) findViewById(R.id.btnSpinnerPlanets));
builder = new AlertDialog.Builder(MyFormActivity.this).setTitle("the prompt").setAdapter(get_the_adapter(b), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
b.setText(b.getResources().getStringArray(R.array.planets__entries)[which]);
dismissDialog(1);
}
})
dialog = builder.create();
break;
default:
dialog = null;
}
return dialog;
}
}
public ArrayAdapter<String> get_the_Adapter(Button view){
String[] items = view.getResources().getStringArray(R.array.planets__entries);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MyFormActivity.this, android.R.layout.simple_spinner_dropdown_item, items);
return adapter;
}
And for the Button's onClick():
((Button) findViewById(R.id.btnSpinnerPlanets)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showDialog(1);
}
});
Related
OK so I am creating an ArrayAdapter and using it in my Alert Dialog because I don't want to show the default radio buttons on SingleItemSelection dialog.
Instead I want to change the background of the item that is selected, and then when the user presses the positive button I will perform the action related to the item that has been selected.
private void showAlertDialog()
{
final String[] options = getResources().getStringArray(R.array.dialog_options);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, options);
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setTitle("My Dialog");
dialogBuilder.setAdapter(adapter, new OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
Toast.makeText(getApplicationContext(), "item clicked at index " + which, Toast.LENGTH_LONG).show();
// Here I need to change the background color of the item selected and prevent the dialog from being dismissed
}
});
//String strOkay = getString(R.string.okay);
dialogBuilder.setPositiveButton("OK", null); // TODO
dialogBuilder.setNegativeButton("Cancel", null); // nothing simply dismiss
AlertDialog dialog = dialogBuilder.create();
dialog.show();
}
There are two problems I'm trying to tackle.
How do I prevent the dialog from being dismissed when the user clicks on an item
How do I change the background of the item that has been selected when the user clicks on it
To prevent dialog from dismissing on item click you can use AdapterView.OnItemClickListener instead of DialogInterface.OnClickListener.
Like this:
dialogBuilder.setAdapter(adapter, null);
...
AlertDialog dialog = dialogBuilder.create();
alertDialog.getListView().setOnItemClickListener(
new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// do your stuff here
}
});
You can set custom ListView as content of AlertDialog and set OnItemClickListener
AlertDialog.Builder builder = new AlertDialog.Builder(this);
String[] items = ...;
ListView list = new ListView(this);
list.setAdapter(new ArrayAdapter<String>(this, android.R.layout.select_dialog_item, items));
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view, int pos, long id) {
...
}
});
builder.setView(list);
and then save reference to dialog
mDialog = builder.show();
in order to dismiss it if necessary
mDialog.dismiss();
How do I prevent the dialog from being dismissed when the user clicks on an item
How do I change the background of the item that has been selected when the user clicks on it
Here is example
public class MainActivity extends AppCompatActivity {
private static final String listFragmentTag = "listFragmentTag";
private static final String data[] = {"one", "two", "three", "four"};
public MainActivity() {
super();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void btnClick(View v) {
ListFragment lf = new ListFragment();
lf.show(getSupportFragmentManager(), listFragmentTag);
}
public static class ListFragment extends DialogFragment {
#Override #NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder adb = new AlertDialog.Builder(getActivity());
adb.setIcon(android.R.drawable.ic_dialog_info)
.setTitle("List")
.setItems(data, null)
.setPositiveButton("OK", null); // pass your onClickListener instead of null
// to keep dialog open after click on item
AlertDialog ad = adb.create();
ad.getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
private int colorOrg = 0x00000000;
private int colorSelected = 0xFF00FF00;
private View previousView;
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// restoring color of previous view
if(previousView != null) {
previousView.setBackgroundColor(colorOrg);
}
// changing items's BG color
view.setBackgroundColor(colorSelected);
previousView = view;
}
});
return ad;
}
#Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
}
}
}
You can use setCanceledOnTouchOutside(false) or setCanceleable(false).
Set selector for the root element tag of the dialog layout xml.
I have a ListView with each row consisting of a textview and a checkbox.
The user is allowed to click on each TextView, and once he does a DialogBox is presented to him where he is expected to either choose Yes or No.
When he chooses No, the CheckBox next to the TextView the user clicked needs to be ticked automatically.
The problem that I am facing is that no matter which TextBox the user chooses, the last CheckBox of the list gets ticked all the time, and not the one next to the chosen TextView.
After debugging I noticed that this is happening because the getView() method of the adapter class stops on the last row, thus the last row always gets selected. I tried setting up tags for each row so that I can than tick the checkbox accordingly but then neither Checkboxes get ticked.
I would appreciate any help on this matter.
....
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
.....
holder.text.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(final View v)
{
final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("Materials");
builder.setMessage("Did you require any materials to fix this error?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
String clickedError;
clickedError = holder.text.getText().toString();
Intent intent = new Intent(mContext, Material.class);
intent.putStringArrayListExtra("materialList", materialList);
intent.putExtra("clickedError", clickedError);
intent.putExtra("repairID", repairID);
((Activity)mContext).startActivityForResult(intent, 1);
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
//holder.chk.setChecked(true); // This ticks the last checkbox of the list.
if(holder.chk.getTag() == v.getTag())
{
holder.chk.setChecked(true);
}
}
});
builder.show();
}
});
Try passing the checkbox for the row into your on click listener:
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
.....
holder.text.setOnClickListener(new MyClickListener(holder.chk);
}
private class MyClickListener implements OnClickListener
{
Checkbox checkbox = null;
public MyClickListener(final Checkbox checkbox)
{
this.checkbox = checkbox;
}
#Override
public void onClick(final View v)
{
final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("Materials");
builder.setMessage("Did you require any materials to fix this error?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
String clickedError;
clickedError = holder.text.getText().toString();
Intent intent = new Intent(mContext, Material.class);
intent.putStringArrayListExtra("materialList", materialList);
intent.putExtra("clickedError", clickedError);
intent.putExtra("repairID", repairID);
((Activity)mContext).startActivityForResult(intent, 1);
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
//checkbox.setChecked(true); // This ticks the last checkbox of the list.
if(checkbox.getTag() == v.getTag())
{
checkbox.setChecked(true);
}
}
});
builder.show();
}
});
CheckBox extends TextView. Use CheckBox.setText(CharSequence | int) to set text into CheckBox and remove the TextView (that will not solve your check problem, of course). Regarding your problem - it's because most AdapterView's re-use Views. Store the checked item information somewhere and in getView call setChecked(checkedItems.get(pos)).
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
.....
holder.chk.setChecked(checkedItems.get(position))
.....
builder.setNegativeButton("No", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
//holder.chk.setChecked(true); // This ticks the last checkbox of the list.
if(holder.chk.getTag() == v.getTag())
{
holder.chk.setChecked(true);
checkedItems.put(position, true);
}
}
});
}
Where checkedItems is a SparseBooleanArray
I have a DialogFragment that shows a list of items to pick from (similar to the attach dialog in Messaging).
My problem is that I cannot get this dialog to dismiss when an item is selected. I've tried calling dismiss() and getDialog().dismiss() inside the OnItemClickListener, no luck. I've tried to remove the dialog through the FragmentManager, I've tried fragmentManager.popBackStack(), all to no avail. I cannot get this dialog to dismiss. It goes away fine when clicking outside the dialog or hitting the back button, but nothing in my code will make it go away.
Has anyone seen this before? How do I get the dialog to dismiss correctly?
Dialog Code:
public class ShareDialog extends DialogFragment {
public enum ShareType {
Camera, Gallery, Web, Whiteboard, Browse,
}
BaseAdapter mShareAdapter = new BaseAdapter() {
#Override
public View getView(int position, View contentView, ViewGroup parent) {
TextView view = null;
if (contentView == null) {
view = (TextView) getLayoutInflater(null).inflate(android.R.layout.simple_list_item_1, parent, false);
} else {
view = (TextView) contentView;
}
int draw = 0;
switch (ShareType.values()[position]) {
case Browse:
view.setText("Browse Content...");
draw = R.drawable.ic_share_browse;
break;
case Camera:
view.setText("Image from Camera...");
draw = R.drawable.ic_share_camera;
break;
case Gallery:
view.setText("Image from Gallery...");
draw = R.drawable.ic_share_gallery;
break;
case Web:
view.setText("New Browsing Session");
draw = R.drawable.ic_share_web;
break;
case Whiteboard:
view.setText("New Whiteboard");
draw = R.drawable.ic_share_whiteboard;
break;
}
view.setCompoundDrawablesWithIntrinsicBounds(draw, 0, 0, 0);
view.setCompoundDrawablePadding(8);
return view;
}
#Override
public long getItemId(int position) {
return ShareType.values()[position].ordinal();
}
#Override
public Object getItem(int position) {
return ShareType.values()[position];
}
#Override
public int getCount() {
return ShareType.values().length;
}
};
public Dialog onCreateDialog(android.os.Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Share which?");
ListView list = new ListView(getActivity());
list.setAdapter(mShareAdapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long itemId) {
dismiss(); // WHY DOESN'T THIS WORK???
if (listener != null)
listener.newShare((ShareType) mShareAdapter.getItem(position));
}
});
builder.setView(list);
return builder.create();
}
public interface ShareDialogListener {
void newShare(ShareType type);
}
private ShareDialogListener listener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Verify that the host activity implements the callback interface
try {
// Instantiate the AutoconnectListener so we can send events to the host
listener = (ShareDialogListener) activity;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString() + " must implement ShareDialogListener");
}
}
}
Why not use the methods available on AlertDialog.Builder to build the list, instead of creating your own ListView and populating it?
I have modified your sample code to show how this would work, and in this example the dialog dismiss() functions fine.
public Dialog onCreateDialog(android.os.Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setSingleChoiceItems(mShareAdapter, 0, new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if (listener != null) {
listener.newShare((ShareType) mShareAdapter.getItem(which));
}
}
});
builder.setTitle("Share which?");
return builder.create();
}
For some - unknown to me - reason, the dialog reference you get back from getDialog() isn't the one you want to work with when inside the listener. You need a reference to the dialog as provided you when you call builder.create();
For example:
final AlertDialog dialog = builder.create();
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
dialog.dismiss();
}
});
return dialog;
HA....
I've found it...
The reason for this is actually ours... we were trying to inflate an xml, and have called:
DialogFragment.this.getLayoutInflater(null).inflate(...);
This call causes, like I've stated in the comment to create 4 dialogs, and then everything gets messed up.
The proper way to do this would be to call:
LayoutInflater layoutInflater = (LayoutInflater) getActivity().getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater.inflate(...);
This fix solved the annoying bug for me on the first go!
I have a ListView and I populated it dinamically through an Adapter. Each row of my ListView have a button and I want to show a DialogBox when it is clicked. However I dunno how to pass the context to my AlertDialog, so it can show up on my activity. What I have is something like this:
....//ADAPTER
public View getView(int position, View view, ViewGroup parent) {
....
pay.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
AlertDialog.Builder ad = new AlertDialog.Builder();
ad.setMessage("Are you sure?");
ad.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog dialog = ad.create()();
dialog.show();
}
});
....
}
I guess I must add some kind of listener at the activity which extends my ListView but Im lost on how do it and the documentation is way too large, couldn't find the solution.
You can pass an activity context to your adapter in a constructor and then use it in your adapter class:
public class MyAdapter {
Context context;
public MyAdapter(Context context, ... ) {
this.context = context;
}
}
I have my ListActivity that when you tap on an item, it pops up a Dialog that ask the user for user and password. How can I get the selected position from the dialog?
Here's how I initialize the ListActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView listView = getListView();
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
showDialog(DIALOG_USER_PASSWORD);
}
});
}
The Dialog I pop up is a simple AlertDialog with 2 EditText which I inflate from an xml file
protected Dialog onCreateDialog(int id) {
switch (id) {
...
case DIALOG_USER_PASSWORD:
LayoutInflater factory = LayoutInflater.from(this);
final View dialogView = factory.inflate(R.layout.alert_dialog_text_entry, null);
return new AlertDialog.Builder(MyListActivity.this)
.setIcon(R.drawable.alert_dialog_icon)
.setTitle(R.string.ask_user_password)
.setView(dialogView)
.setPositiveButton(R.string.ok_text, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String userName = ((EditText) findViewById(R.id.username_edit_alert_dialog))
.getText().toString();
String password = ((EditText) findViewById(R.id.password_edit_alert_dialog))
.getText().toString();
Credentials cred = new CredentialsL1(userName, password);
/* HERE IS WHERE i NEED THE SELECTED ITEM
mId IS THE OBJECT ASSOCIATED TO THE SELECTED POSITION */
mService.connect(mId, cred);
}
})
// Cancel button
.setNegativeButton(R.string.cancel_text,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
}
})
.create();
}
return null;
}
The only I've come up with is creating a new field "mId" and setting it when the user taps and using it when the user taps OK in the Dialog. Any more elegant idea?
Thanks
private int selectedPosition;
...
protected void onCreate(Bundle savedInstanceState) {
....
// inside the item listener...
selectedPosition = position;
showDialog(DIALOG_USER_PASSWORD);
/* HERE IS WHERE i NEED THE SELECTED ITEM
mId IS THE OBJECT ASSOCIATED TO THE SELECTED POSITION */
// just use selectedPosition var
Any more elegant idea?
It seems that you use a normal ListView (not a checkbox one)... so, it's fine to do it this way.