AlertDialog with a list - android

I created a alertDialog with a list, but for me keeps indoors.
public class Day extends ListFragment{
private final int IDD_LIST_TIMES = 1;
AlertDialog.Builder builder;
String[] times = { "09:00", "15:00", "19:00", "20:00", "23:00" };
#Override
public void onCreate(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
TimeAdapter myListAdapter = new TimeAdapter(getActivity(), R.layout.text_fragment, times);
setListAdapter(myListAdapter);
myListAdapter.notifyDataSetChanged();}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView =inflater.inflate(R.layout.listview, container, false);
ListView lv = (ListView)rootView.findViewById(android.R.id.list);
lv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) { case android.R.id.list:
showDialog(IDD_LIST_TIMES);
break;
}}
});
return rootView;
}
protected Dialog onCreateDialog(int id) {
switch (id) { case IDD_LIST_TIMES:
final String[] mTimes = {"for 5 minutes", "for 10 minutes", "for 15 minutes"};
builder = new AlertDialog.Builder(this);
builder.setTitle("Alarm clock");
builder.setItems(mTimes, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),
"Alarm clock " + mTimes[item],
Toast.LENGTH_SHORT).show();
}});
builder.setCancelable(false);
return builder.create();
default:
return null;
}
}
}
but an error appears constantly for me, where red line "new AlertDialog.Builder(this)"
Why? Prompt me, how to write.

If you want to display a spinner as dialog you can use below code in XML:
<Spinner android:spinnerMode="dropdown" ... />
OR
if you are doing programatically then use:
Spinner sp = new Spinner(this, Spinner.MODE_DIALOG);
OR
If you want to display an ListActivity as Dialog the put this code in your Manifest file:
<activity android:theme="#android:style/Theme.Dialog" />

You are trying to use wrong context object i.e. 'this' which is not applicable for "new AlertDialog.Builder(this)"
First, get the application context in onCreate method and store it into local variable. Use local variable instead of "this" in "new AlertDialog.Builder(this)"
Declare variable
private Context mContext = null;
initialize it in your OnCreate method
#Override
public void onCreate(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mContext = getActivity().getApplicationContext();
Use it in your method
"new AlertDialog.Builder(mContext)"
Hope this will solve your problem.

Related

Why doesn't progress spinner work after closing alert dialog in android?

My progress bar is just a spinner.
I am showing two options to user and when user clicks an option, I show a dialog, so that user reads and understands it.
This is what I want.
When they click positive, it should show the spinner and keep calling service on background.
When they click negative, it should make the option unchecked.
Here is the code.
This radioGroup.setOnClickListener goes into onCreateView method of a fragment.
public class Choose_CountryFragment extends Fragment {
private RadioGroup radioGroup;
private TextView textView;
private String countryChosen = null;
ConnectionStatus connectionStatus = new ConnectionStatus(getContext());
public Choose_CountryFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
final Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_choose__country, container, false);
radioGroup = (RadioGroup) rootView.findViewById(R.id.country_choice_radio);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
{
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch(checkedId){
case R.id.countryCanada:
// do operations specific to this selection
countryChosen = "Canada";
Intent explicitServiceIntent = new Intent(getActivity(), Service.class);
explicitServiceIntent.putExtra("country", "Canada");
getActivity().startService(explicitServiceIntent);
connectionStatus.showProgress();
break;
case R.id.countryUSA:
countryChosen = "USA";
Dialog dialog = onCreateDialog(savedInstanceState);
dialog.show();
connectionStatus.showProgress();
break;
}
}
});
public Dialog onCreateDialog(final Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
Toast.makeText(getContext(), "Click Got it", Toast.LENGTH_LONG).show();
builder.setMessage(R.string.SignUpWarningInfo)
.setPositiveButton(R.string.gotIt, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent explicitServiceIntentUSA = new Intent(getActivity(), Service.class);
explicitServiceIntentUSA.putExtra("country", countryChosen );
getActivity().startService(explicitServiceIntentUSA);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
return;
}
});
// Create the AlertDialog object and return it
return builder.create();
}
}
}
ConnectionStatus.java
public class ConnectionStatus {
private Context _context;
private ProgressDialog progressDialog = null;
public ConnectionStatus(Context context) {
this._context = context;
}
public void showProgress(){
progressDialog = new ProgressDialog(_context);
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
progressDialog.show();
}
}
Error happens when I click USA.
Error I get
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources$Theme android.content.Context.getTheme()' on a null object reference
at android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:154)
at android.app.AlertDialog.<init>(AlertDialog.java:109)
at android.app.ProgressDialog.<init>(ProgressDialog.java:77)
at com.a2.a2.ConnectionStatus.showProgress(ConnectionStatus.java:66)
at com.a2.a2.signUp.Choose_CountryFragment$1.onCheckedChanged(Choose_CountryFragment.java:73)
Your Context returning null
Change code in Choose_CountryFragment
public class Choose_CountryFragment extends Fragment {
...
protected Context mContext;
private ConnectionStatus connectionStatus
...
public Choose_CountryFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
final Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_choose__country, container, false);
...
connectionStatus = new ConnectionStatus(mContext);// initialize ConnectionStatus here
...
}
}
Override onAttach Inside Choose_CountryFragment
#Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
In Fragment, you have to use:
ProgressDialog progressDialog = new ProgressDialog(getActivity);
From the documentation, the getActivity() method returns the Activity this Fragment is currently associated with it.
Edit:
In Activity class, you have to use like:
ProgressDialog progressDialog = new ProgressDialog(YourActivityClassName.this);

Calling a method in a Fragment from an AlertDialog

Could you please help with the below:
I am trying to call the method deletePlayer inside the fragment PlayersActivityFragment from the alertdialog NameAlertDialogFragment.
The code is below:
public static class PlayersActivityFragment extends Fragment {
ArrayList<Player> arrayPlayers;
ListView listViewPlayers;
//PlayerAdapter adapter;
public PlayersActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
arrayPlayers = new ArrayList<Player>();
View rootView = inflater.inflate(R.layout.fragment_activity_players, container, false);
Button buttonAddPlayer = (Button) rootView.findViewById(R.id.button_addplayers);
buttonAddPlayer.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
arrayPlayers.add(new Player("Player", 0));
Player selectedPlayer = arrayPlayers.get(arrayPlayers.size()-1);
((PlayersActivity)getActivity()).showNameDialogFragment(selectedPlayer);
}
});
listViewPlayers = (ListView) rootView.findViewById(R.id.listView_playername);
return rootView;
}
public void deletePlayer(){
arrayPlayers.remove(arrayPlayers.size()-1);
}
}
void showNameDialogFragment(Player player) {
mDialog = NameAlertDialogFragment.newInstance(player);
mDialog.show(getFragmentManager(),"SCORE DIALOG");
}
// Class that creates the AlertDialog
public static class NameAlertDialogFragment extends DialogFragment {
static Player selectedPlayer;
public static NameAlertDialogFragment newInstance(Player player) {
selectedPlayer = player;
return new NameAlertDialogFragment();
}
// Build AlertDialog using AlertDialog.Builder
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
final View view = inflater.inflate(R.layout.alertdialog_name, null);
final EditText editTextName = (EditText) view.findViewById(R.id.edittext_name);
return new AlertDialog.Builder(getActivity())
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
.setView(view)
.setMessage("Enter Player's Name:")
//Set up Yes Button
.setPositiveButton("Done", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, int id) {
mName = editTextName.getText().toString().trim();
selectedPlayer.setName(mName);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//PlayersActivityFragment playersActivityFragment = (PlayersActivityFragment) getFragmentManager().findFragmentById(R.id.container);
//playersActivityFragment.deletePlayer();
//((PlayersActivityFragment)getTargetFragment()).deletePlayer();
NameAlertDialogFragment.this.getDialog().cancel();
}
})
.create();
}
}
The two different ways I have tried to call the methods are commented out in the .setNegativeButton onClickListener:
PlayersActivityFragment playersActivityFragment = (PlayersActivityFragment) getFragmentManager().findFragmentById(R.id.container);
playersActivityFragment.deletePlayer();
and
((PlayersActivityFragment)getTargetFragment()).deletePlayer();
Thank you!
First of all, why are all of your classes static? Anyway, here's an answer that should work...
Try using an interface as a callback. For example:
First create an interface.
public interface NameAlertDialogListener {
public void onNegativeClick();
}
Then have PlayersFragment implement NameAlertDialogListener.
public static class PlayersActivityFragment extends Fragment implements NameAlertDialogListener
Next, in the PlayersFragment, create a method called onNegativeClick.
#Override
public void onNegativeClick() {
//delete or whatever you want to do.
}
Create a member variable for the listener:
static Player selectedPlayer;
static NameAlertDialogListener mCallBack;
Next create a method in the dialog fragment called setListener.
public void setListener(NameAlertDialogListener callback) {
try {
mCallBack = callback;
} catch (ClassCastException e){
throw new ClassCastException(callback.toString() + " must implement NameAlertDialogListener" );
}
}
Then, when you create the dialog fragment call the setListener method.
void showNameDialogFragment(Player player) {
mDialog = NameAlertDialogFragment.newInstance(player);
mDialog.setListener(this);
mDialog.show(getFragmentManager(),"SCORE DIALOG");
}
Lastly, in your negative click listener:
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mCallBack.onNegativeClick() ;
NameAlertDialogFragment.this.getDialog().cancel();
}
})
I am not sure if this is the correct way of doing things, but I have come to a working solution.
First I moved ArrayList<Player> arrayPlayers; outside of the PlayersActivityFragment fragment.
Then I moved the method:
public void deletePlayer(){
arrayPlayers.remove(arrayPlayers.size()-1);
}
outside of the PlayersActivityFragment fragment.
I then called the deletePlayer() method inside the alertdialog with the line ((PlayersActivity)getActivity()).deletePlayer();.
Actually, I have a little hack, it's not really good, but it's easy to implement: declare PlayersActivityFragment variable in your DialogFragment. Then change your constructor to:
public static NameAlertDialogFragment newInstance(Player player,PlayersActivityFragment fragment ){
selectedPlayer = player;
NameAlertDialogFragment test = new NameAlertDialogFragment();
test.playerActivityFragment = fragment;
return test;
}
Then you can call playerActivityFragment.deletePlayer() everywhere in your DialogFragment.
P/s: The best way is implement interface, but for lazy coder like me, the method above is better lol!

Creating listener of a CustomDialog out of the class in Android

I am trying to create a listener of a button of a customdialog which extends DialogFragment class and I want to locate the listener of custom buttons out of customdialog fragment class .However when I try to call the view of CustomDialog Fragment then I am getting null exception. What I do is to create an new instance of the customdialog fragment in somewhere else and say
customdialog.getView().findViewById(R.id.custombutton);
but I am getting null.
public class CustomDialog extends DialogFragment {
public final int RES_NONE = -1;
private TextViewCustomFont dialogTitle, view2, dialogBodyBottom,
dialogBodyTop;
private EditTextCustomFont dialogEditText;
private ButtonCustomFont dialogLeftButton;
private ButtonCustomFont dialogRightButton;
private Typeface GothamBold, GothamMedium, GothamUltra;
private static int title1, bodyTop1, bodyBottom1, EditTextHint1,
leftButton1, rightButton1;
onSubmitListener mListener;
private Dialog dialog;
interface onSubmitListener {
void setOnSubmitListener(String arg);
}
public static CustomDialog newInstance(int title, int bodyTop,
int bodyBottom, int EditTextHint, int leftButton, int rightButton) {
title1 = title;
bodyTop1 = bodyTop;
bodyBottom1 = bodyBottom;
EditTextHint1 = EditTextHint;
leftButton1 = leftButton;
rightButton1 = rightButton;
CustomDialog frag = new CustomDialog();
return frag;
}
public ButtonCustomFont getDialogLeftButton() {
return dialogLeftButton;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
dialog = new Dialog(getActivity());
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//dialog.setContentView(R.layout.dialog_layout);
//dialog.show();
initLayout();
return dialog;
}
private void initLayout(){
dialog.setContentView(R.layout.dialog_layout);
setDialogView();
setCustomDialog();
}
public void setDialogView(){
//Create an java object of each dialog view item
dialogTitle = (TextViewCustomFont) dialog.findViewById(R.id.custom_dialog_title);
dialogBodyTop = (TextViewCustomFont) dialog.findViewById(R.id.custom_dialog_body_top);
dialogBodyBottom = (TextViewCustomFont) dialog.findViewById(R.id.custom_dialog_body_bottom);
dialogEditText = (EditTextCustomFont) dialog.findViewById(R.id.custom_dialog_body_et);
dialogLeftButton = (ButtonCustomFont) dialog.findViewById(R.id.custom_dialog_body_btn_left);
dialogRightButton = (ButtonCustomFont) }
public class LoginSelectionFragment extends Fragment {
public static LoginSelectionFragment newInstance() {
LoginSelectionFragment fragment = new LoginSelectionFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_loginselection,
container, false);
}
I am trying to pull the dialogLeftButton of CustomDialog Fragment and assing a listener on it inside the LoginSelectionFragment.
Here is how it looks like after I added method 2. This a part of LoginSelectionFragment
private void TwoButtonTextEditTextDialog(){
String title = getResources().getString(R.string.invalid_info_header);
String body = getResources().getString(R.string.invalid_info_body);
String body2 = getResources().getString(R.string.hint_newemail);
String btn1 = getResources().getString(R.string.cancel_uppercase);
String btn2 = getResources().getString(R.string.ok_alert);
fragmentDialog = CustomDialog.newInstance(title, body, body2, RES_NONE, btn1, btn2);
fragmentDialog.setCustomDialogFragmentListener(mDialogClickListener);
fragmentDialog.show(getFragmentManager(), "");
}
private CustomDialog.CustomDialogFragmentListener mDialogClickListener = new CustomDialog.CustomDialogFragmentListener(){
#Override
public void onNegativeClick() {
// TODO Auto-generated method stub
fragmentDialog.dismiss();
}
#Override
public void onPositiveClick() {
// TODO Auto-generated method stub
fragmentDialog.dismiss();
}
};
#Override
public void onNegativeClick() {
// TODO Auto-generated method stub
}
#Override
public void onPositiveClick() {
// TODO Auto-generated method stub
}
You could create a method as setDialogButtonClickListener(CustomDialog.OnButtonClickListener clickListener); where CustomDialog.OnButtonClickListener is an inner static interface , that way you could listen to click events of the buttons from anywhere.
An example of this could look as below,
public class CustomDialog extends DialogFragment {
.....
public static CustomDialog newInstance(int title, int bodyTop,
int bodyBottom, int EditTextHint, int leftButton, int rightButton) {
CustomDialog frag = new CustomDialog();
Bundle args = new Bundle();
args.putInt("title", title);
......
frag.setArguments(args);
return frag;
}
...
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int title = getArguments().getInt("title");
return new AlertDialog.Builder(getActivity())
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(title)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
....
.create();
}
#Override
public void onClick(DialogInterface dialog, int which) {
if (listener != null) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
listener.onRightButtonClick();
default:
listener.onLeftButtonClick();
}
}
}
...
private CustomDialog.OnButtonClickListener mClickListener;
....
public void setDialogButtonClickListener(CustomDialog.OnButtonClickListener clickListener){
mClickListener = clickListener;
}
...
public static interface OnButtonClickListener {
public void onLeftButtonClick();
public void onRightButtonClick();
}
}
If you notice from the above sample I posted , I have besides solving your problem of setting the click listener on buttons also have introduced you with the Factory Design Pattern on Android , You can see that instead of creating static fields for the button title and Dialog title I've set them in the Bundle Argument and then Retrieve them in the Dialogs onCreate() method.
For more Best Practices of Fragment You can take a look here
Edit
Ok , for your help I am providing you a Glimpse of what your LoginSelectionFragment should look like.
public class LoginSelectionFragment extends Fragment implements CustomDialog.OnButtonClickListener {
......// Method 1
public void showDialog(String title , String message .....) {
CustomDialog dialog = CustomDialog.getInstance(title , message...);
dialog.setDialogButtonClickListener(this);
dialog.show(getSupportFragmentManager(), null);
}
public void onLeftButtonClick(){
...// do something on left button click of dialog
}
public void onRightButtonClick(){
// do something on right button click of dialog
..
}
// Method 2
public void showDialog2(String title , String message .....) {
CustomDialog dialog = CustomDialog.getInstance(title , message...);
dialog.setDialogButtonClickListener(mDialogClickListener);
dialog.show(getSupportFragmentManager(), null);
}
private final CustomDialog.OnButtonClickListener mDialogClickListener = new CustomDialog.OnButtonClickListener() {
public void onLeftButtonClick(){
...// do something on left button click of dialog
}
public void onRightButtonClick(){
// do something on right button click of dialog
..
}
}
}
Now If you look at Method 1 , we have given parameters to showDialog() method so that you could reuse it for showing multiple times with different arguments ie., you could use this approach when you want to show the same dialog with different title , message etc
and in Method 2 we have provided an anonymous inner class for handling click events you could as many anonymous inner classes as you have different varieties of dialog ie dialog with different UI and different Event listeners in the same activity/fragment.
Enjoy!
Try to use this, (did not test this)
public class MyDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.input_warning)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return builder.create();
}
}
and in your Activity fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.workout_a_fragment, container, false);
Button button = (Button)view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fm = getActivity().getFragmentManager();
MyDialogFragment dialog = new MyDialogFragment();
dialog.show(fm, DIALOG_WARNING);
}
});}

Android: How to create a Detail alertdialog

I've been playing around with alert dialogs. I want to show a dialog that shows particular information about a list item in listview. Just like the android's file manager's detail dialog.
Picture: https://dl.dropbox.com/u/20856352/detailsbox.jpg
Interesting thing about this Details dialog is that it shows list items which are very similar to Preference item in a Preferences Screen. They can be clicked upon, they're showing a very nicely laid out two-line item listitem.
I need to create a similar dialog box but I've no clue how to accomplish this. I've played around a bit. Preference XML cannot be used as alertdialog's layout. And I'm unable to develop a layout that looks similar to the above pic. Need help / guideline how to achieve this.
Faraz Azhar
You probably don't want to use a custom dialog because it will be difficult to replicate the look of the AlertDialog. An AlertDialog can display a list of items using AlertDialog.setListAdapter. You can customize the list of items to show two rows of text per item by using a custom implementation of ListAdapter. The attached screenshot was produced by the below code and xml.
public class Temp extends Activity
{
private String[] listItemsFirstRow = {"item 1", "item 2", "item 3"};
private String[] listItemsSecondRow = {"item 1", "item 2", "item 3"};
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setAdapter(new MyAdapter(), null);
builder.setTitle("Title");
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.show();
}
class MyAdapter extends BaseAdapter
{
#Override
public int getCount()
{
return listItemsFirstRow.length;
}
#Override
public Object getItem(int position)
{
//this isn't great
return listItemsFirstRow[position];
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
if(convertView == null)
{
convertView = getLayoutInflater().inflate(R.layout.main, null);
}
((TextView)convertView.findViewById(R.id.text1)).setText( listItemsFirstRow[position]);
((TextView)convertView.findViewById(R.id.text2)).setText( listItemsSecondRow[position]);
return convertView;
}
}
}
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:minHeight=![enter image description here][2]"?android:attr/listPreferredItemHeight"
android:orientation="vertical"
android:gravity="center_vertical"
android:paddingLeft="15dip"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Just made your xml file same as regular screen/page
then put this code on your onCreate()
AlertDialog.Builder builder;
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.toast_info,
(ViewGroup) findViewById(R.id.toast_layout_root));
builder = new AlertDialog.Builder(this);
builder.setView(layout);
alertDialog = builder.create();
which r.layout.toast_info is your xml file
and r.id.toast_layout_root is your root xml id (eg. '<'linearlayout android:id="+#id...."'>' )
and when you want to show it just write this line
alertDialog.show();
My suggestion would be to use an Activity as a dialog. This way it is pretty easy to create a custom dialog. Here is a small example which I think you can build upon.
**Activity**
public class CustomDialogEx extends Activity implements OnClickListener {
private Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(this);
}
#Override
public void onClick(View v) { // pass your string data via this intent to the custom view
// show the custom dialog
Intent i = new Intent();
// i.putExtra(<your key/value pairs here>
i.setClass(this, DialogActivity.class);
startActivity(i);
}
}
****************************************************************************
**Custom Dialog**
// The Activity will serve as the Dialog
public class DialogActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.your_dialog_layout);
Intent i = new Intent();
Bundle b = getIntent().getExtras();
b.getString(<your key>)
}
}
*****************************************************************************
**AndroidManifest**
<activity
android:name="DialogActivity"
android:configChanges="keyboardHidden|orientation"
android:theme="#android:style/Theme.Dialog" >
</activity>
this may also help you
public class ShareDialog extends Dialog implements android.view.View.OnClickListener{
Context mcontContext;
Button btnok;
Listview lstview;
public ShareDialog(Context context) {
super(context);
mcontContext= context;
//pls replace with your dialog.xml file
setContentView(R.layout.sharedialog);
bindComponent();
addListener();
}
private void bindComponent() {
// TODO Auto-generated method stub
lstview=(Listview) findViewById(R.id.lstdetail);
btnok=(Button) findViewById(R.id.btnok);
//bind here listview with your adpter
}
private void addListener()
{
btnshareviwifi.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnok:
dismiss();
break;
default:
break;
}
}
}
and where you want to show
ShareDialog shobje=new ShareDialog (context);
shobje.show()

Android Dialog reopen after rotate device

I'm writing a very simple application to open my custom share dialog.
XML layout contains only 1 button:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/white"
android:gravity="center_horizontal">
<Button android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_margin="20dip"
android:text="Click here to open Share Dialog"
android:onClick="onBtnShareClick"/>
</LinearLayout>
And on Activity, I create a custom sharing Dialog
public class CustomDialog extends Activity {
private static final int SHOW_DIALOG_SHARE = 1;
private ArrayAdapter<ShareItem> mShareAdapter;
#Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
setContentView(R.layout.custom_dialog);
final ShareItem[] items = {
//new Item("Menu item", R.drawable.icon_assistance),
new ShareItem("Banbe", R.drawable.ic_banbe),
new ShareItem("Facebook", R.drawable.ic_facebook),
new ShareItem("Twitter", R.drawable.ic_twitter),
new ShareItem("Gmail", R.drawable.ic_gmail),
new ShareItem("Other sharing options...", 0)
};
mShareAdapter = new ArrayAdapter<ShareItem>(
this,
android.R.layout.select_dialog_item,
android.R.id.text1,
items){
public View getView(int position, View convertView, ViewGroup parent) {
//User super class to create the View
View v = super.getView(position, convertView, parent);
TextView tv = (TextView)v.findViewById(android.R.id.text1);
//Put the image on the TextView
tv.setCompoundDrawablesWithIntrinsicBounds(items[position].icon, 0, 0, 0);
//Add margin between image and text (support various screen densities)
int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
tv.setCompoundDrawablePadding(dp5);
return v;
}
};
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case SHOW_DIALOG_SHARE:
return new AlertDialog.Builder(this)
.setIcon(R.drawable.icon)
.setTitle(R.string.app_name)
.setAdapter(mShareAdapter, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(CustomDialog.this, "Click on item " + item, Toast.LENGTH_SHORT).show();
}
})
.show();
}
return null;
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
}
public void onBtnShareClick(View v) {
showDialog(SHOW_DIALOG_SHARE);
}
protected class ShareItem {
public final String text;
public final int icon;
public ShareItem(String text, Integer icon) {
this.text = text;
this.icon = icon;
}
#Override
public String toString() {
return text;
}
}
}
When click the button, my Sharing Dialog will be opened. All good.
Now, I rotate the device to portrait mode, click the button to open the Dialog. After that, press back to close Sharing Dialog. Rotate device to landscape mode. Suddenly Sharing Dialog is re-opened although I didn't click on the button.
When I try using the native Sharing Dialog I don't see this bug. Maybe a custom Sharing Dialog is the cause?
Can anyone tell me what's wrong here?
Hi You have to add screen orientation support in your application manifest file.
<activity android:name=".TestApp"
android:label="#string/app_name" android:configChanges="orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
And also override the following method ,
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
use create() method instead of show() method
new AlertDialog.Builder(this).create()
Try use own class that will be extends from DialogFragment
For example:
public class QuestionDialogFragment extends DialogFragment
{
public final static String BF_TITLE = "QuestionDialogFragment.BF_TITLE";
public final static String BF_QUESTION = "QuestionDialogFragment.BF_QUESTION";
private Callback mCallback;
public static void init(FragmentManager fragmentManager, String title, String question, Callback callback)
{
Bundle bundle = new Bundle();
bundle.putString(BF_TITLE, title);
bundle.putString(BF_QUESTION, question);
QuestionDialogFragment dialog = new QuestionDialogFragment();
dialog.setCallbackListener(callback);
dialog.setArguments(bundle);
dialog.show(fragmentManager, null);
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setCancelable(false);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
Bundle bundle = getArguments();
String title = null;
String question = null;
if (bundle != null)
{
if (bundle.containsKey(BF_TITLE))
{
title = bundle.getString(BF_TITLE);
}
if (bundle.containsKey(BF_QUESTION))
{
question = bundle.getString(BF_QUESTION);
}
}
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
alertDialogBuilder.setTitle(title);
alertDialogBuilder.setMessage(question);
//null should be your on click listener
alertDialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
mCallback.success();
dialog.dismiss();
}
});
alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
mCallback.cancel();
dialog.cancel();
}
});
return alertDialogBuilder.create();
}
public void setCallbackListener(Callback callback)
{
this.mCallback = callback;
}
public static interface Callback
{
void success();
void cancel();
}
}
And use it anywhere in your code:
QuestionDialogFragment.init(
getFragmentManager(),
"Some title",
"Some question?",
new QuestionDialogFragment.Callback()
{
#Override
public void success()
{
// #TODO if user choice YES;
}
#Override
public void cancel()
{
// #TODO if user choice CANCEL;
}
});
If you want create own view instead standard dialog window just instead:
Dialog onCreateDialog(Bundle savedInstanceState)
use
View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
For example:
need create values/layout/your_fragment_layout.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/kom_purchase_dialog_root_view">
<TextView
android:id="#+id/kom_purchase_dialog_message_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="some text"/>
<LinearLayout
android:layout_gravity="bottom"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/kom_purchase_dialog_negative_button"
android:layout_alignParentBottom="true"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Cancel"/>
<Button
android:id="#+id/kom_purchase_dialog_positive_button"
android:layout_toRightOf="#+id/kom_purchase_dialog_negative_button"
android:layout_alignParentBottom="true"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Ok"/>
</LinearLayout>
</FrameLayout>
and for this layout change own class as:
public class QuestionDialogFragment2 extends DialogFragment
{
public final static String BF_TITLE = "QuestionDialogFragment.BF_TITLE";
public final static String BF_QUESTION = "QuestionDialogFragment.BF_QUESTION";
private Callback mCallback;
public static void init(FragmentManager fragmentManager, String title, String question, Callback callback)
{
Bundle bundle = new Bundle();
bundle.putString(BF_TITLE, title);
bundle.putString(BF_QUESTION, question);
QuestionDialogFragment2 dialog = new QuestionDialogFragment2();
dialog.setCallbackListener(callback);
dialog.setArguments(bundle);
dialog.show(fragmentManager, null);
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setCancelable(false);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Bundle bundle = getArguments();
String title = null;
String question = null;
if (bundle != null)
{
if (bundle.containsKey(BF_TITLE))
{
title = bundle.getString(BF_TITLE);
}
if (bundle.containsKey(BF_QUESTION))
{
question = bundle.getString(BF_QUESTION);
}
}
View view = super.onCreateView(inflater, container, savedInstanceState);
if (view == null)
{
view = inflater.inflate(R.layout.your_fragment_layout, null, false);
view.setTag(new Holder(view));
}
Holder holder = (Holder) view.getTag();
holder.messageTextView.setText(question);
holder.positiveButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mCallback.success();
}
});
holder.negativeButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mCallback.cancel();
}
});
return view;
}
public void setCallbackListener(Callback callback)
{
this.mCallback = callback;
}
public static interface Callback
{
void success();
void cancel();
}
private final class Holder
{
public TextView messageTextView;
public Button positiveButton;
public Button negativeButton;
private Holder(View view)
{
messageTextView = (TextView) view.findViewById(R.id.question_dialogfragment_message_textview);
positiveButton = (Button) view.findViewById(R.id.question_dialogfragment_positive_button);
negativeButton = (Button) view.findViewById(R.id.question_dialogfragment_negative_button);
}
}
}
and the same usage:
QuestionDialogFragment2.init(
getFragmentManager(),
"Some title",
"Some question?",
new QuestionDialogFragment2.Callback()
{
#Override
public void success()
{
// #TODO if user choice YES;
}
#Override
public void cancel()
{
// #TODO if user choice CANCEL;
}
});
For both approaches will work void onSaveInstanceState(Bundle outState) and save state after rotation. I think it's better and universal approach then user the simple dialog.
It doesn't matter if Dialog or AlertDialog was used. In order to avoid closing the dialog when you rotate screen, use this code:
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

Categories

Resources