I am opening timepicker in dialogfragment in my fragment class.
var dialog = new TimePickerDialogFragment(_activity, DateTime.Now, new OnTimeSetListener());
dialog.Cancelable = false;
dialog.Show(_fg, null);
Here TimePickerDialogFragment extends DialogFragment.
public class TimePickerDialogFragment : DialogFragment
{
private Activity _activity;
private DateTime _date;
private readonly TimePickerDialog.IOnTimeSetListener _listener;
public TimePickerDialogFragment(Activity activity, DateTime date, TimePickerDialog.IOnTimeSetListener listener)
{
_activity = activity;
_date = date;
_listener = listener;
}
public override Dialog OnCreateDialog(Bundle savedState)
{
var dialog = new TimePickerDialog(_activity, _listener, _date.Hour, _date.Minute, true);
dialog.SetTitle("Enter Time"+ DateTime.Now.ToString());
return dialog;
}
}
Here is my listener class
public class OnTimeSetListener : Java.Lang.Object, TimePickerDialog.IOnTimeSetListener
{
public void OnTimeSet(TimePicker view, int hourOfDay, int minute)
{
}
}
Now I want to update the title as soon as user selects a new time while the pop up is opened. The OnTimeSet is called when I click on set button on popup.I don't want to update there. How can I achieve this?
Is there any other way to open timepicker dialog apart from this that I can try?
I am new to android. Any help is appreciated.
In order to get notified when time is changed you need to create a subclass of TimePickerDialog and override OnTimeChanged method which is called when user changes time in the picker. Add a TimeChanged event in the new subclass and trigger it from the overridden method. In the event handler you will be able to set the dialog title based on the new time.
Related
I am opening different date picker fragments in my android app.
The fragement is opened like this.
DialogFragment datePicker = new DatePickerFragment();
datePicker.show(getSupportFragmentManager(), "MY_TAG");
The I implemented the onDateSet method which has the picked date and a DatePicker object. Now I tried to get the tag from the DatePicker object to check which picker has been shown.
There is a method datePicker.getTag(), but this returns null.
Is there a way to get the tag which has been commited in the show method?
By calling datePicker.getTag(), you are getting the wrong tag; which is the DatePicker tag, not the DatePickerFragment tag.
To see the right tag, just use getTag() inside your custom DatePickerFragment
getTag() inside my Fragement class works fine. But how to I pass the
tag back to my activity where I called show() My Fragement currently
only contains the onCreateDialog method where I return a new
DatePickerDialog instance
You can pass a listener to your DatePickerFragment constructor, and trigger its callback with the Fragment tag whenever you set a date.
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
interface OnDateAdjustedListener {
void onDateAdjusted(String tag);
}
private OnDateAdjustedListener mOnDateAdjustedListener;
// Constructor with a Listener
public DatePickerFragment(OnDateAdjustedListener onDateAdjustedListener) {
mOnDateAdjustedListener = onDateAdjustedListener;
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// .... Handle onCreateDialog
}
#Override
public void onDateSet(DatePicker datePicker, int year, int month, int dayOfMonth) {
// .... Handle onDateSet
// callback with fragment tag
mOnDateAdjustedListener.onDateAdjusted(getTag());
}
}
And in your activity modify the constructor, and implement the interface
public class MainActivity extends AppCompatActivity implements View.OnClickListener, DatePickerFragment.OnDateAdjustedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatePickerFragment dateFragment = new DatePickerFragment(this);
}
#Override
public void onDateAdjusted(String tag) {
Toast.makeText(this, tag, Toast.LENGTH_SHORT).show();
}
}
how to update recyclerview from a dialog which is in another class?
My dialog is as a separate class which is called from mainActivity. When I do changes in database, I would like to update recyclerview, which is on mainActivity.
Dialog:
public class Dialog {
DatabaseExecutor databaseExecutor = new DatabaseExecutor();
private final Activity activity;
private final List<Passenger> passengers;
private final int position;
public Dialog (final Activity activity, final List<Passenger> passengers, final int position){
this.activity = activity;
this.passengers = passengers;
this.position = position;
}
public void showDialog (){
final BottomSheetDialog dialog = new BottomSheetDialog(activity);
dialog.setContentView(R.layout.custom_dialog);
final AppCompatImageView dial, message, info, paid, edit, delete;
final AppCompatTextView name;
name = dialog.findViewById(R.id.dialog_name);
paid = dialog.findViewById(R.id.dialog_paid);
name.setText(passengers.get(position).getName());
if(passengers.get(position).isPaid())
paid.setImageResource(R.drawable.money_paid_72);
else
paid.setImageResource(R.drawable.money_unpaid_72);
paid.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Passenger passenger = passengers.get(position);
if (!passengers.get(position).isPaid()){
passenger.setPaid(true);
passenger.setTumblr(R.drawable.money_paid);
passenger.setUser(R.drawable.user_icon);
paid.setImageResource(R.drawable.money_paid_72);
}
else {
passenger.setPaid(false);
passenger.setTumblr(R.drawable.money_unpaid);
passenger.setUser(R.drawable.user_icon_unpaid);
paid.setImageResource(R.drawable.money_unpaid_72);
}
databaseExecutor.updatePassenger(activity, passenger);
}
});
dialog.show();
}
}
P.s. when this dialog was in mainActivity, I just called populateData method and it worked. But how to refresh it from this Dialog class?
You can use callback with dialog in MainActivity,
public interface DialogCallback {
public void onDialogCallback();
}
Your Dialog constructor should be,
DialogCallback callback;
public Dialog (final Activity activity, final List<Passenger> passengers, final int position, DialogCallback callback){
this.activity = activity;
this.passengers = passengers;
this.position = position;
this.callback = callback;
}
In your Dialog button click use below code,
paid.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Passenger passenger = passengers.get(position);
if (!passengers.get(position).isPaid()){
passenger.setPaid(true);
passenger.setTumblr(R.drawable.money_paid);
passenger.setUser(R.drawable.user_icon);
paid.setImageResource(R.drawable.money_paid_72);
}
else {
passenger.setPaid(false);
passenger.setTumblr(R.drawable.money_unpaid);
passenger.setUser(R.drawable.user_icon_unpaid);
paid.setImageResource(R.drawable.money_unpaid_72);
}
databaseExecutor.updatePassenger(activity, passenger);
callback.onDialogCallback(); // Add this line
}
});
In your MainActivity use below code,
Dialog dialog = new Dialog(this, passengers, position, new DialogCallback() {
#Override
public void onDialogCallback() {
// Update recycler view code here
}
});
dialog.showDialog();
In Dialog :
Have an interface
public interface onDialogFinishCallback
{
void refreshRecyclerView();
}
Now implement the above in your activity.
before dismiss the dialog or after the db change operation call
callback.refreshRecyclerView
A direct solution would be to call method on activity you passed to the dialog. There refresh data of recyclerview and notifyDataSetChanged() or appropriate.
A more general and imo better, architecture-related solution is to use Room or similar db, where you can observe data for changes. Let's say data in the db is changed anywhere. All the places where this data is observed (like with LiveData), data is refreshed. If you also use Paging library, data is refreshed and animated in recyclerview too.
Dialog shouldn't refresh RecyclverView directly. Instead you should pass listener from activity. Activity can refresh recycler if needed with notifyDataSetChanged.
Usually dialog should be 'dumb' ui and you shouldn't give it too much control, especially not over elements that are not shown inside dialog. Such approach will make your dialogs more reusable and easy to maintain.
Write an interface in your dialog
public interface onClickInterface{
public void updateRecyclerView(int position);
}
declare new variable for this interface in your dialog class
private onClickInterface mOnClickInterface;
then call method updateRecyclerView() from dialog class where you want to update recyclerview
mOnClickInterface.updateRecyclerView(position);
then implement your MainActivity for this interface and override this method
#override
public void updateRecyclerView(int position){
//alter your list which you are passing to your adapter
Passenger passenger = passengers.get(position);
passenger.setPaid(true);
rAdapter.notifyDatasetChanged();
}
i using a specific date library(https://github.com/mohamad-amin/PersianMaterialDateTimePicker)
now i want using it in a button in Recycler View.
now my problem is I have to define two options in library codes :
1 - I should refer to the activity.
2 - i need to use getSupport FragmentManager().
but this page has been extends with Recycler View.Adapter and I do not know how to call these two options on this page.
RecyclerViewAdapter page :
PersianCalendar persianCalendar = new PersianCalendar();
DatePickerDialog datePickerDialog = DatePickerDialog.newInstance( StudentList.this ,
persianCalendar.getPersianYear() ,
persianCalendar.getPersianMonth() ,
persianCalendar.getPersianDay());
datePickerDialog.show( getSupportFragmentManager() , "datePickerDialog" );
In these pictures you can easily understand me :
enter image description here
enter image description here
enter image description here
You activity must implements TimePickerDialog.OnTimeSetListener and implement the abstact methode onTimeSet:
public class StudentList extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener {
#Override
public void onTimeSet(TimePickerDialog view, int hourOfDay, int minute, int second) {
}
}
and inside onClick
DatePickerDialog datePickerDialog = DatePickerDialog.newInstance((((StudentList)view.getContext()), persianCalendar.getPersianYear(),
persianCalendar.getPersianMonth(),
persianCalendar.getPersianDay());
OR :
DatePickerDialog datePickerDialog =DatePickerDialog.newInstance(new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
}
}, persianCalendar.getPersianYear(),
persianCalendar.getPersianMonth(),
persianCalendar.getPersianDay());
You could try passing the Activity's context when creating an instance of the adapter:
//Code in your Activity
MyAdapter myAdapter = new MyAdapter(this, ...);
Your adapter:
private Context context;
public MyAdapter(Context context, ...){
this.context = context;
//Rest of the constructor...
}
By doing that, you could just add do this:
datePickerDialog.show(context.getSupportFragmentManager(), "datePickerDialog");
You just need an activity context passed in your constructor. Be sure to call new Adapter(this,...) from activities and new Adapter(getActivity(),...) from fragments.
private Context context;
#Override
public void onClick(View v) {
FragmentManager manager = ((Activity) context).getFragmentManager();
FragmentManager manager = ((AppCompatActivity)context).getSupportFragmentManager();
}
try this
I have created a Custom Dialog in DiscussionFragment. Dialog is Successfully working.
//Dialog in Fragment Class
final Dialog dialog = new Dialog(getActivity());
dialog.setContentView(R.layout.create_post_layout);
dialog.setTitle("Post");
I am calling a TimePickerFragment from dialog's Button OnClick which is successfully opening.
setTimeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DialogFragment newFragment = new TimePickerFragment();
newFragment.show(getFragmentManager(), "create_post_layout");
//(getFragmentManager(),"post_layout");
}
});
Now i want to access TextView of Dialog in TimePickerFragment Class like this,
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
//Do something with the user chosen time
//Get reference of host activity (XML Layout File) TextView widget
View dialogView = getActivity().getLayoutInflater().inflate(R.layout.create_post_layout, null);
TextView tv = (TextView) dialogView.findViewById(R.id.postTimeTV);
tv.setText("String");
String min = String.valueOf(minute);
setText is not working returning E/textview: initAddtionalStyle default
no NullPointerException
For Just Activity not Dialog i can access TextView as follows in OnTimeSet
TextView tv = (TextView) getActivity().findViewById(R.id.postTimeTV);
tv.setText("String");
String min = String.valueOf(minute);
You might want to post more code of TimePickerFragment for better answers.
As far as i can see you'r inflating a layoutfile in onTimeSet() without using it as content view for your Dialog.
Then you get the TextView of this new inflated view wich is not the Dialog's view.
I would access the Textview in DialogFragments onCreateDialog() to ensure you use the correct View and save it in a global variable.
Like:
private TextView tv;
#Override
public Dialog onCreateDialog(){
....
tv = (TextView) ... findById(...)
}
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
tv.setText(...);
}
I have I Fragment that show DialogFragment .. The DialogFragment creates and shows a TimePickerDialog dialog.
I want the calling Fragment to implement the imePickerDialog.OnTimeSetListener listener. but I don't know how to pass this listener to the Called fragment (The DialogFragment) ..
I have found the following code that passes a listener from ACTIVITY to the DialogFragment.
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
// This error will remind you to implement an OnTimeSetListener
// in your Activity if you forget
try {
mListener = (OnTimeSetListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnTimeSetListener");
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the current time as the default values for the picker
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
// Create a new instance of TimePickerDialog and return it
return new TimePickerDialog(getActivity(), mListener, hour, minute,
true);
}
How to pass it from FRAGMENT ?
Can't you just use getTargetFragment and setTargetFragment?
And then first check if the targetFragment is an instance of your Listener:
if (getTargetFragment() instanceof OnTimeSetListener) {
mListener.updateTime(); }