after doing a lot of research and trying (i think) every lifecycle method i could find, i´m really stuck:
What i want: Basically i have this DialogFragment ("ProfileUsernameDialogFragment")which should present my layout file ("fragment_profile_header_username_dialog").
in this layout file i have some TextViews and some EditTexts. I want to set the text of these EditTexts to some value i obtain in my programm, so setting it beforehand is not possible.
What i have:
public class ProfileUsernameDialogFragment extends DialogFragment {
...
#Override
public void onActivityCreated(Bundle savedInstanceState) {
EditText usernameText = (EditText) this.getView().findViewById(R.id.username_field);
usernameText.setText("TEST");
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Log.d(AppController.LOG_STRING, this.getClass().toString() + " - onCreateDialog - START");
AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
View view = this.getActivity().getLayoutInflater().inflate(R.layout.fragment_profile_header_username_dialog, null);
builder.setView(view);
builder.setPositiveButton(SAVE_SETTINGS, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int whichButton) {
// Tried this too:
// EditText usernameText = (EditText)
// ProfileUsernameDialogFragment.this.getView().findViewById(R.id.forename_label);
// usernameText.setText("TEST");
}
});
builder.setNegativeButton(ABORT_ACTION, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
builder.setTitle(CHANGE_NAME_SETTINGS);
Dialog dialog = builder.create();
return dialog;
}
}
What i get: is a NullPointerException, no matter which position for the findViewById(R.id.username_field) i tried.
(I also tried onCreate and some other methods, i start thinking i might have another problem than the code location, but i really hav no clue) I tried to follow at least 6 similar questions about NullPointers in DialogFragments so i guess i need advanced help ^^
i should add i´m completely new to android so please be nice, but convention tipps etc. are very welcome! thx in advance :)
Following is what you need:
mAlertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(final DialogInterface dialog) {
final Button b = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
v.findViewById(R.id...)
}
});
}
});
});
}
});
Another option in addition to #David's answer is to use the onStart() method.
It looks like you were thinking along these lines in your question, except you used the onActivityCreated() method.
So for example:
#Override
public void onStart()
{
super.onStart();
EditText usernameText = (EditText) this.getDialog().findViewById(R.id.username_field);
usernameText.setText("TEST");
}
Android documentation has good example
So, if You wont set text in Your layout You need set it in onCreateView() method, for example:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup cont,
Bundle savedInstanceState) {
// Inflate the layout to use as dialog or embedded fragment
View view = inflater.inflate(R.layout.app_info, cont, false);
TextView title = (TextView)view.findViewById(R.id.dialog_header);
TextView content = (TextView)view.findViewById(R.id.dialog_content);
Button button = (Button)view.findViewById(R.id.dialog_button);
title.setText(this.dialogTitle);
content.setText(this.dialogContent);
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
getDialog().dismiss();
}
});
return view;
}
Related
I have been searching for this for days and to no avail whatsoever. I have the following problem: I have a MainActivity which is mostly indiferent to this problem. Inside this main activity I have a fragment. This fragment holds a viewpager whose element is also a fragment. Now, I have a button declared in the viewpager fragment layout, which I would like to call in the "parent" fragment. Any ideas???
Now, moving on to what I have already tried. I have tried to call directly, then I tried to declare an OnClickListener inside either fragment, and I also tried to use callbaciks. However none of these solutions worked...
I have tons of code useless to you, so I will only highlight the important parts
Parent Fragment (ScheduleFragment)
button_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Are you Sure?")
.setMessage("There's no coming back!")
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton("yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
deleteThis(viewPager2.getCurrentItem());
SharedPreferences preferences = getActivity().getSharedPreferences("Settings", Context.MODE_PRIVATE);
SharedPreferences.Editor sEditor = preferences.edit();
Integer position = preferences.getInt("Number of Days", 3) + 1;
sEditor.putInt("Number of Days", position);
sEditor.apply();
}
});
builder.show();
}
});
My Child Fragment (ViewPager_ScheduleObject
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
Bundle args = getArguments();
((TextView) view.findViewById(R.id.textview_viewpager_schedule))
.setText("Day " + args.getInt(ARG_OBJECT));
ViewPager2_Schedule_Adapter viewPager2_schedule_adapter= new ViewPager2_Schedule_Adapter(this);
SharedPreferences sharedPreferences = getActivity().getSharedPreferences("Settings", Context.MODE_PRIVATE);
Button button_cancel = view.findViewById(R.id.button_cancel_day);
button_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
If you need any more code, be sure to let me know! Any help is apprecciated!
Use Interface, Make Something Like this
public interface OurClient {
public void myButton(View view);
}
then Implement the interface in your main class
Long press
When I long-click on an item of the message, the item will display and the layout changes like the picture. I want to make this , but i don't have a keyword to find this solution. I need a keyword or some example to make it.
Many ways you can do. I am going to share one example.
Implement View.OnLongClickListener as follows
private void setupLongPress() {
imageButton.setOnLongClickListener(new View.OnLongClickListener(){
#Override
public boolean onLongClick(View v){
// here your staff
// we added dialog method here as follows
createPreviewDialog();
return false;
}
});
}
Now use LayoutInflater to inflate new layout as a popup windows
private Dialog createPreviewDialog() {
View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_preview, null);
LinearLayout closeButton = view.findViewById(R.id.close);
closeButton.setOnClickListener (new View.OnClickListener (){
#Override
public void onClick ( View view ) {
dismiss();
}
});
View okButton = view.findViewById(R.id.ok);
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dismiss();
// here your staff
}
});
builder.setView(view);
return builder.create();
}
I spent all day trying to make this up, but I can't..
This is the problem: I want an yes/no AlertDialog that doesn't disappear on orientation change, so I decided to use DialogFragment.
So I prepared the code and for the first use, everything with it is just perfect, but if I hit the button (that should show the dialog) once more (second, third and further times) the dialog doesn't show up! Though I can see from logs it actually makes instances and I have no errors, it's there, I just can't see it!
If I fold the app, or turn off / on the screen (I believe it's about calling onResume() method) the dialogs shows up, all of them (depending how much time I hit the button), it seems like a some displaying issue or refreshing problem maybe.. I don't know, so I came here hoping to get some help.
About my code:
I have a ListView with custom adapter, and in that adapter I have the code to show the an AlertDialog (DialogFragment) - as part of an ImageButton onClickListener.
The code for DialogFragment that I use:
public static class cMyDialogFragment extends DialogFragment {
public static cMyDialogFragment newInstance(int title) {
cMyDialogFragment frag = new cMyDialogFragment();
Bundle args = new Bundle();
args.putInt("title", title);
frag.setArguments(args);
return frag;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int title = getArguments().getInt("title");
this.setCancelable(true);
setRetainInstance(true);
return new AlertDialog.Builder(getActivity())
// .setIcon(R.drawable.alert_dialog_icon)
.setTitle(title)
.setPositiveButton(R.string.yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((ActAudiorecords) getActivity()).doPositiveClick();
}
}
)
.setNegativeButton(R.string.no,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((ActAudiorecords) getActivity()).doNegativeClick();
}
}
)
.create();
}
}
The code for calling the dialog to show up (within the custom ListView adapter):
public View getView(final int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (vi == null)
vi = inflater.inflate(R.layout.recordings_row, null);
TextView tvDate = (TextView) vi.findViewById(R.id.tv_Recordings_r_date);
tvDate.setText(ainfo.get(position).getDate());
ImageButton ibtn_play = (ImageButton) vi.findViewById(R.id.ibtnPlay);
final String localPath = dPath + File.separator + ainfo.get(position).getFName();
ImageButton ibtn_remove = (ImageButton) vi.findViewById(R.id.ibtnRecordings_r_remove);
ibtn_remove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
curFName = ainfo.get(position).getFName();
curID = ainfo.get(position).getID();
showDialog();
}
});
ibtn_play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
play(localPath);
}
});
return vi;
}
The additional functions:
void showDialog() {
DialogFragment newFragment = cMyDialogFragment.newInstance(
R.string.do_you_want_to_remove_the_file);
newFragment.show(getFragmentManager(), "dialog");
}
public void doPositiveClick() {
// Do stuff here.
ps_db.delete(const_audiorecords_tname, "id = " + curID, null);
new File(dPath + File.separator + curFName).delete();
Toast.makeText(ActAudiorecords.this, getString(R.string.audiorecord_has_been_removed), Toast.LENGTH_LONG).show();
ActAudiorecords.this.onCreate(null); //Restarting the Activity to refresh the LV
Log.i("FragmentAlertDialog", "Positive click!");
}
public void doNegativeClick() {
// Do stuff here.
Toast.makeText(ActAudiorecords.this, getString(R.string.the_operation_has_been_cancelled), Toast.LENGTH_LONG).show();
Log.i("FragmentAlertDialog", "Negative click!");
}
I have no onResume() in my code.
I tried to use different codes for DialogFragment but it doesn't matter.
It was all due to the line:
ActAudiorecords.this.onCreate(null);
So after calling onCreate() with null as savedInstance it have been removing link to the DialogFragment (as I can understand), it was the line for refreshing the Activity, I solved the problem by splitting the code in onCreate() to which should be called only once (at a start of Activity) and the part that should be called in every refreshing point (such as GUI settings and etc).
I believe I could also save the current Bundle and pass it to onCreate() instead of null and it would work as good as now, but I thought that calling an function is much better for data updating than calling onCreate() over and over, so that's it, thank you all who wanted to help.
The original code has been deleted, the new working code is shown. The idea behind the code is to create a new textView within a layout that has a custom name to it that the user provides. Previously, a NPE error was happening. This is a fix. Any questions, please feel free to ask.
EDIT: Found the solution
The fix needs to be as followed:
accountEdit = new EditText(this); // accountEdit needs to be a global variable
then within the builder.setPositiveButton
builder.setPositiveButton(R.string.btn_save, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dInterface, int whichButton)
{
LinearLayout lineLayout = (LinearLayout)findViewById(R.id.linear_layout);
String newAccountName = accountEdit.getText().toString();
newTextView = new TextView( getBaseContext() );
newTextView.setVisibility(View.VISIBLE);
newTextView.setText( newAccountName );
newTextView.setId(id);
newTextView.setTextSize(35);
newTextView.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
onClickNew(view);
}
});
newTextView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
Toast.makeText(getBaseContext(), "Testing" , Toast.LENGTH_LONG).show();
return true;
}
});
This will create the button, as well as set the name of the button to the information that is in the EditText within the Dialog Box. Previously, the EditText was from another activity, and was being called wrong, which caused the NPE. Thank you for all the help.
As Wenhui metioned, you call the finViewById inside the onclick listener of the button, so the wrong context is used. Do it like in the following example:
final EditText accountEdit = (EditText)findViewById(R.id.newAccountButton);
final String newAccountName = accountEdit.getText().toString();
final LinearLayout lineLayout = (LinearLayout)findViewById(R.id.linear_layout);
builder.setPositiveButton(R.string.btn_save, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dInterface, int whichButton)
{
newTextView = new TextView(getBaseContext());
newTextView.setVisibility(View.VISIBLE);
newTextView.setText("Test");
newTextView.setId(id);
newTextView.setTextSize(35);
newTextView.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
onClickNew(view);
}
});
lineLayout.addView(newTextView);
id++;
}
});
Is it possible to show multiple Dialogs one over another? Is there something like Dialog Z-Level?
I am using DialogFragment where user chooses elements, when he comfirms his choice, it is saved to database and sent on server. if the save action fails I would like to inform user with ... another dialog is it possible? And will it not clear off my first dialog?
Thanks in advance.
Indeed, it's possible to show multiple dialog Fragments one inside another one. The z-order depends on the order they are created.
In the code below there is an example of a FragmentActivity with the behavior that you require.
public class MyActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
//...
}
public void onSave(View view) {
Intent intent = getIntent();
this.setResult(RESULT_OK, intent);
finish();
}
public void onCancel(View view) {
finish();
}
public void SelectWeekDay(View view) {
DialogFragment selectWeekDayFragment = new SelectWeekDayFragment();
selectWeekDayFragment.show(getSupportFragmentManager(), "WeekDayDialog");
}
public class SelectWeekDayFragment extends DialogFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.week_day_dialog, container, true);
Button saveButton = (Button) view.findViewById(R.id.button_save);
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CheckBox checkboxMonday = (CheckBox) getDialog().findViewById(R.id.checkBox_monday);
if (!checkboxMonday.isChecked()) {
DialogFragment saveErrorFragment = new SaveErrorFragment();
saveErrorFragment.show(getSupportFragmentManager(), "SaveErrorFragment");
}
else {
SaveToDb(); //Perform actions to store on db or what you wish
dismiss();
}
}
});
Button cancelButton = (Button) view.findViewById(R.id.button_cancel);
cancelButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
return view;
}
}
public class SaveErrorFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setMessage("You must select Monday").setPositiveButton("Ok", null).create();
}
}
}
My advice is to use a custom layout with a ViewFlipper inside your dialog so you can easily switch between a progress-bar or whatever different layouts you want to show. If you want to show multiple Dialogs my guess is that the z-order depends on the order they were created the latest beeing shown on top.
You usually can, however, just be a little careful. Use the dialog's lifecycle to your advantage to avoid side-effects. For example: you can do a check on a function like onStop() to see if the child dialog is open, and if so, close it.
Ideally, cutting down on the amount of layers of dialogs you have is ideal, as long as it's sane (for example: doing it ends up being hundreds of lines of code more)