Reading data selected in TimePicker called from a Fragment - android

I have a Fragment that has its own layout and has a Choose Time button along with a TextView beneath it. I am opening a TimePickerFragment from this Fragment when the user clicks this button.
Now when the user selects a time, and clicks done, I want to populate the TextView contained in the fragment. I am not sure how to do this.
All the materials/tutorials online invoke the timepicker from an Activity. I do (obviously) have a Parent Activity, but since this TimePicker is only being used in this Fragment, I would like to limit the scope as much as possible.
So the flow is as follows:
ParentActivity > Fragment (contains TextView and button) > DialogFragment (TimePicker)
Here is my implementation:
public class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int hour = 0;
int minute = 0;
boolean is24Hour = false;
// ... Some code to read shared preference, get the correct time format, theme, etc.
return new TimePickerDialog(getActivity(), dialog_theme, this, hour, minute, is24Hour); //DateFormat.is24HourFormat(getActivity())
}
#Override
public void onTimeSet(TimePicker view, int hour, int minute) {
//TextView textView = (TextView) getView.findViewById(R.id.time_value); //NullPointerException!
TextView textView = (TextView) view.findViewById(R.id.time_value); //Also NullPointerException!
// Do something with the time chosen by the user
textView.setText(TimeAndDate.getDisplayableTime(time));
textView.clearFocus();
}
}

It belongs to the Fragment which invokes the DialogFragment
findViewById looks for a view with the id in the current view hierarchy. The TextView is not a child of TimerView.
So you need to initialize TextView in Fragment not DialogFragment.
All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly. Use interface as a call back to the Activity and then communciate the time to the Fragment.
http://developer.android.com/training/basics/fragments/communicating.html
DialogFragment --> ParentActivtiy --> Fragment
You can check the example #
Simple timepicker for a fragment activity

Related

DatePicker and TimePicker code not working together ("protected Dialog onCreateDialog(int id)" is already defined)

I have created an app, in which I have a DatePicker and a TimePicker. First I made the Datepicker and I displayed it when I selected the Date textview, this worked perfectly fine. Then I wanted to do the same for the Time EditText but instead of displaying a DatePicker it is supposed to display a TimePicker when selected.
After I implemented the code for the TimePicker: The error is that the "protected Dialog onCreateDialog(int id)" is already defined and I cannot use this method twice.
Any help would be appreciated,
Thanks in Advance
I assume that you have only one DialogFragment for both date and time pickers... this will create a conflict as you have already implemented the onCreateDialog.
what I usually do is I create another class for each component that i would like to have a different implementation of onCreateDialog.
public class DatePickerDialog extends DialogFragment implements DatePickerDialog.OnDateSetListener{
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
...
}
public class TimePickerDialog extends DialogFragment implements
TimePickerDialog.OnTimeSetListener{
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
...
}
then I would call it in the activity like ...
DatePickerDialog dialog = new DatePickerDialog();
FragmentManager fm = getSupportFragmentManager();
dialog.show(fm, "Date Picker");
this way you could also add custom callbacks or listeners for each picker and use them multiple times in one activity.

Fragment over Fragment issue

My requirement is :
In one Fragment, had textview, by clicking on that one DialogFragment is appearing with a list of values. By clicking on value, The dialog fragment should be closed and selected values should be displayed in textview in the first fragment.
But here the problem is accessing textview object is null.
Communicating between fragments using interface i.e., By clicking on list in dialogFragment one interface is calling. That interface method implemented in first fragment.
So, How to access the textview object?
Here code is:
FragmentManager manger = getFragmentManager();
listDialogFragment.show(manger, null);
public interface onOkClickListener {
void setOnOkClickListener(int pos,String selectedID,MainActivity actv);
}
#Override
public void setOnOkClickListener(int pos,String id,MainActivity actv) {
textView object// accessing null
}
Thanks In advance..

Android- Getting the Fragment instance in Activity with Multiple Tabs

I am having problems referencing an already instantiated Fragment from within my Activity.
I have two tabs as part of the Action Bar and for each Tab I am instantiating an instance of the same fragment....
Fragment = Player
Tab1 = Player1 (Player Fragment with details from DB of Player 1)
Tab2 = Player2 (Player Fragment with details from DB of Player 2)
The Player fragment includes a field (Games played) which is amendable using a Number Picker.
So... I have created an interface which I have implemented on my activity. When the button is clicked on the Fragment it calls the interface which on the activity creates a Dialog Fragment to display the number picker. Once the number picker has been closed and passed back the number of Games Played to the Activity I then want to update this value on the correct Fragment (So if the button was pressed on Tab 2 then the value on the Player2 should get updated.)
This is where I am drawing a blank.
I am using actionBar.addTab to add each tab and using a TabsListener Class implementing ActionBar.TabListener to do a replace of the correct Fragment when each tab is pressed.
ActionBar handles the FragmentManager stuff for you...
What I think I need to do here within my Activity is get the Current Fragment so that I can make a call to a method in this fragment to update it. But when Adding the Fragment through the TabListener I cannot see a way that I can either get and store the ID of the Fragment instance or set a Tag for it. If I could then I could use getFragmentByID or getFragmentByTag to find it.
Any ideas on how I should do this.
I thought I had a completely different solution whereby I made by database update in the Number Picker itself and then simply let onResume() update the value in my Visible Fragment when the DialogFragment closes but it seems that onResume() is not called when the DialogFragment is closed.
I have not posted code examples as I hope the above simplifies the question.
Both the 'add' and 'replace' methods of FragmentTransaction have a number of overloads. Using the one with the parameters:
(int containerViewId, Fragment fragment, String tag)
...allows you to provide a tag name for the fragment that you can subsequently use to retrieve it with a call to findFragmentByTag.
You can specify the TabListener (http://developer.android.com/reference/android/app/ActionBar.TabListener.html) and get notified when tab is reselected and here you can update the UI.
In my opinion you should update the database after user selects the value from the dialog. You can specify OnClickListener for different buttons on dialog and get notified when something is selected or cancelled.
Example at http://developer.android.com/reference/android/app/DialogFragment.html#AlertDialog,
public static class MyAlertDialogFragment extends DialogFragment {
public static MyAlertDialogFragment newInstance(int title) {
MyAlertDialogFragment frag = new MyAlertDialogFragment();
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(R.drawable.alert_dialog_icon)
.setTitle(title)
.setPositiveButton(R.string.alert_dialog_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((FragmentAlertDialog)getActivity()).doPositiveClick();
}
}
)
.setNegativeButton(R.string.alert_dialog_cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((FragmentAlertDialog)getActivity()).doNegativeClick();
}
}
)
.create();
}
}

After screen orientation change the dialogFragment appears apparently without any call

here there is part of the Activity where the screen orientation change:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = (EditText) findViewById(R.id.editText1);
et.setOnLongClickListener(new View.OnLongClickListener()
{
#Override
public boolean onLongClick(View v)
{
Fragment1 dialogFragment = new Fragment1();
dialogFragment.show(getFragmentManager(), null);
dialogFragment.setTextDialog(et.getText().toString());
return true;
}
});
}
Apparentely it seems that the dialog that will appear inside the DialogFragment should appear just after the onLongClick over the editText
(I know that when the screen orientation change the Activity is restarted, but it shouldn't start normally like the first time that is created?)
My problem:
when I open at least once the dialog and I close it, after the screen orientation change I have the dialog displayed again on the screen, like if I long-Clicked the editText.
I don't absolutely know why this happens.
I attach also the structure of dialog fragment:
public Dialog onCreateDialog(Bundle savedInstanceState)
{
final Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
LayoutInflater adbInflater = LayoutInflater.from(getActivity());
View eulaLayout = adbInflater.inflate(R.layout.dialog_crypt, null);
Button btn_OK = (Button) eulaLayout.findViewById(R.id.btnOK);
dialog.setContentView(eulaLayout);
final EditText et = (EditText)eulaLayout.findViewById(R.id.editText2);
et.setText(textDialog);
if(et.length()>0)
{
et.setText(et.getText().toString() + " ");
}
et.setSelection(et.length());
btn_OK.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
textDialog = et.getText().toString();
((Main)getActivity()).setTextOnEditText(textDialog);
dialog.dismiss();
}
});
return dialog;
}
Thanks so much for the help.
Try removing the dialog from stack using fragment manager instead of just dismissing it.
getFragmentManager().beginTransaction().remove(dialogFragment.this).commit();
By the way, instead of just using a Fragment for your dialog, you should use DialogFragment itself. Checkout: DialogFragment
Also, don't ever call your activity methods like this ( ((Main)getActivity()).setTextOnEditText(textDialog);
unless your fragment is a static inner class. Instead, create an interface to talk between fragments and activity.
When screen changes orientation, it calls onSaveInstanceState method, and it saves the state in the Bundle object including the stack. If you dismiss the dialog without clearing this stack, it will then show the dialog when you rotate the phone since this is in the saveInstanceState bundle.
You must clear dialog off the stack with:
getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
if you use support library for dialog fragment, or
getActivity().getFragmentManager().beginTransaction().remove(this).commit();
When a config change (like rotation) occurs the old Fragment isn't destroyed - it just adds itself back to the Activity when it's recreated (android retains fragments by default). So if you have your DialogFragment shown before rotation, it will instantly show up after rotation.

How to have multiple datepickers on one Android screen?

I created one screen in my Android app which contains a datepicker like so:
TextView userDateView = (TextView) getView().findViewById(R.id.text_user_date);
userDateView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatePickerFragment newFragment = new DatePickerFragment();
newFragment.setListner(OverviewFragment.this);
newFragment.show(getFragmentManager(), "datePicker");
}
});
and I created a callback which receives the date back and updates the userDateView, which all works fine. In another screen I now want to have two dates next to eachother which the user can both select. Unfortunately the callback doesn't know from which of the two dates the user started the datepicker fragment.
Does anybody know how I can somehow know from which button the datepickerFragment was started? All tips are welcome!
A simple approach is to supply a parameter to each DatePickerFragment and send this parameter back to your callback, like requestCode on Activity.onActivityResult.
See how to supply parameters to Fragments:
http://developer.android.com/reference/android/app/Fragment.html#setArguments(android.os.Bundle)
Btw, you can find a different approach here:
Multiple DatePickers in same activity
Try something like this:
DatePickerFragment newFragment = new DatePickerFragment();
newFragment.setListner(new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {}
});
newFragment.show(getFragmentManager(), "datePicker");

Categories

Resources