It seems TimePicker is made of three inner NumberPickers. Is it possible to access them? it's needed to access and modify each of them.
public static class TimePickerFragment extends DialogFragment
implements TimePickerDialog.OnTimeSetListener {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
TimePicker dialog = new TimePicker(getActivity(), this, 22, 30,
DateFormat.is24HourFormat(getActivity()));
// Create a new instance of TimePickerDialog and return it
return dialog;
}
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
// Do something with the time chosen by the user
}
}
In dialog, I've created a TimePicker to be shown, but I have to modify TimePicker minutes column(spinner) and add 15min intervals. I want to know if there is any way to access those NumberPickers alone.
UPDATE
i posted answer below, however it was one of the hardest modification in android built-in components for me, i finally found the answer and shared it here but idk why it got down-vote?
finally i found a solution. i'm getting minute column here and setting a 15 minute interval there.
changeTimepicker(R.id.from_time_picker, 15);
method implementation:
try {
Class<?> rClass = Class.forName("com.android.internal.R$id");
// Field timePicker = rClass.getField(name);
TimePicker mTimePicker = (TimePicker) findViewById(id);
Field m = rClass.getField("minute");
NumberPicker mMinuteSpinner = (NumberPicker) mTimePicker.findViewById(m.getInt(null));
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue((60 / increment) - 1);
List<String> displayedValues = new ArrayList<String>();
for (int i = 0; i < 60; i += increment) {
displayedValues.add(String.format("%02d", i));
}
mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));
} catch (Exception e) {
e.printStackTrace();
}
}
Related
I want to reset my horizontal progressbar to 0 every night at 12.
Here is my code.
public class MainActivity extends AppCompatActivity {
private TextView textView;
Button btn;
private int Counter counter;
Progressbar progressbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.txtvw);
progressbar = findViewById(R.id.progressbar_Horizontal);
progressbar.setMax(10);
btn = findViewById(R.id.btn_clc);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
counter++;
textView.setText(String.valueOf(counter));
progressbar.setProgress(counter)
}
});
Calendar calendar = Calendar.getInstance();
int hour = 23;
int minute = 59;
int second = 59;
int curHour = calendar.get(Calendar.HOUR_OF_DAY);
int curMinute = calendar.get(Calendar.MINUTE);
int curSecond = calendar.get(Calendar.SECOND);
if (hour==curHour && minute==curMinute && second==curSecond) {
progressbar.setProgress(0);
}
}
}
In this method at the output there is no response to the progressbar! Is this the right way to do or is there any other way?
You don't get any response because you're defining the action in OnCreate method. This method is executed one time when you enter the Activity. So this action defined only works if you launch your Ativity exactly at 23:59:59.
If you want to do it right, implement AlarmManager. You can set the time you want (23:59:59) and do whatever you want (reset the bar) at that moment. You can implement it also when the app is closed, in the background or when the screen is off.
Take a look at this: Alarm Manager Example
New to JAVA and Android coding and trying my first practical project.
I don't understand how to make processing wait until timekeeperdialog returns a value.
In my Main Activity I have created getters and setters to variables (first time doing this btw):
private int pickhour;
private int pickminute;
public MainActivity(){
pickhour = 0;
pickminute = 0;
}
public void setpickhour(int pickhour) {
this.pickhour = pickhour;
}
public int getpickhour(){
return this.pickhour;
}
public void setpickminute(int pickminute) {
this.pickminute = pickminute;
}
public int getPickminute(int pickminute) {
return this.pickminute;
}
I call the dialog box with this, and then expecting processing to pause until the TimePicker returns a value, I have a Toast to show results. The Toast fires as soon as the Timepicker appears.
DialogFragment newFragment = new TimePickerFragment();
newFragment.show(getFragmentManager(),"TimePicker");
Toast.makeText(getApplicationContext(), "Time Picker" + String.valueOf(pickhour) + ":" + String.valueOf(pickminute), Toast.LENGTH_LONG).show();
And my fragment looks like this :
public class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener{
private MainActivity ma = new MainActivity();
#Override
public Dialog onCreateDialog(Bundle savedInstanceState){
//Use the current time as the default values for the time picker
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
//Create and return a new instance of TimePickerDialog
return new TimePickerDialog(getActivity(),this, hour, minute,
DateFormat.is24HourFormat(getActivity()));
}
//onTimeSet() callback method
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
ma.setpickhour(hourOfDay);
ma.setpickminute(minute);
}
}
I tried looping through a boolean set by the ontimeset method to force waiting on a return value, but my application just hung.
What fundamental concept am I missing? I'm on vacation, so spent a day & a half trying to figure this out.
You can try this -
public class TimePickerFragment extends DialogFragment implements
TimePickerDialog.OnTimeSetListener{
private MainActivity ma = new MainActivity();
#Override
public Dialog onCreateDialog(Bundle savedInstanceState){
//Use the current time as the default values for the time picker
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
//Create and return a new instance of TimePickerDialog
return new TimePickerDialog(getActivity(),this, hour, minute,
DateFormat.is24HourFormat(getActivity()));
}
//onTimeSet() callback method
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
ma.setpickhour(hourOfDay);
ma.setpickminute(minute);
Toast.makeText(getApplicationContext(), "Time Picker" + String.valueOf(pickhour) + ":" + String.valueOf(pickminute), Toast.LENGTH_LONG).show();
}
}
And if you are only using fragment for timePicker there is no need of the fragment.
In this case you can try this in MainActivity -
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
TimePickerDialog mTimePicker;
mTimePicker = new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() {
#Override
public void onTimeSet(TimePicker timePicker, int hourOfDay, int minute) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
cal.set(Calendar.MINUTE, minute);
setpickhour(hourOfDay);
setpickminute(minute);
}
}, hour, minute, true);//Yes 24 hour time
mTimePicker.setTitle("Time Picker");
mTimePicker.show();
Does your code work? Because you cannot pass "this" as second argument in TimePickerDialog constructor.
I'm kind of new to Android, and I'm currently struggling with the TimePicker. So, I've got the TimePicker here:
public class TimePickerFragment extends DialogFragment
implements TimePickerDialog.OnTimeSetListener {
public String time;
#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(), this, hour, minute,
DateFormat.is24HourFormat(getActivity()));
}
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
// Do something with the time chosen by the user
time = hourOfDay + ":" + minute;
//update global variable
MockDB.setCheckout(time);
}
}
This is working, but after the user selects a time I want to call a function in the activity the picker is in to change the button colors and text. This is in a function called ReserveProduct that extends AppCompatActivity.
public void animateButtons() {
//picker disappears until next button is clicked
Button picker = (Button) findViewById(R.id.button6);
picker.setVisibility(View.GONE);
Button picker1 = (Button) findViewById(R.id.button7);
picker1.setVisibility(View.GONE);
if (settingReturn == false) {
//first button turns gray
Button bttn1 = (Button) findViewById(R.id.buttonCheckIn);
bttn1.setBackgroundResource(R.drawable.button_inactive);
String time = ((MockDB) this.getApplication()).getCheckout();
bttn1.setText("Check Out: 12:27 PM");
//new button appears
Button bttn2 = (Button) findViewById(R.id.buttonCheckOut);
bttn2.setVisibility(View.VISIBLE);
settingReturn = true;
} else {
//make 2nd button inactive
Button bttn2 = (Button) findViewById(R.id.buttonCheckOut);
bttn2.setBackgroundResource(R.drawable.button_inactive);
String time = ((MockDB) this.getApplication()).getReturn();
bttn2.setText("Return: 1:27 PM");
//show new buttons
Button set = (Button) findViewById(R.id.buttonSet);
set.setVisibility(View.VISIBLE);
Button home = (Button) findViewById(R.id.buttonHome);
home.setVisibility(View.VISIBLE);
}
}
My issue is that this function is not static, so I'm not able to simply call it from the TimePicker class. I can't move the button changing functionality to the TimePicker class because I need to be able to extend AppCompatActivity, but AppCompatActivity and DialogFragment have a conflicting class. I also can't make the animateButtons() class static because then the findViewById() functionality throws an error.
Please help!!
Instantiate the class first, i.e.
(new SomeClass()).someMethod();
Let me preface that I'm new to programming for Android. I've been doing my due diligence to research to no avail. I have the source code below and I'm having issues with returning the value for returning.
I have the code laid out on eclipse and it's not triggering any errors. But when I build the code below, it comes back with an error. After inspecting the values in debug view, I can see the proper values just not binded to the TextView.
public class MyFirstActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
calculateResult(2012, 9, 29);
}
private void calculateResult(int year, int month, int day) {
long days = 0L;
int returning = 0;
java.util.Calendar cal = new java.util.GregorianCalendar(year, month-1, day);
long todayMI = new java.util.Date().getTime();
long calMI = cal.getTimeInMillis();
long millDiff = calMI - todayMI;
if (millDiff < 0) {
returning = 0;
} else {
days = millDiff / 1000 / 60 / 60;
returning = (int) Math.ceil(days / 24f);
}
TextView days_int_remaining = (TextView) findViewById(R.id.days_int_remaining);
days_int_remaining.setText(returning);
}
}
If it helps, here's the TextView on my layout XML:
<TextView
android:id="#+id/days_int_remaining"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:shadowColor="#5000"
android:shadowDx="4"
android:shadowDy="3"
android:shadowRadius="1"
android:textColor="#fff"
android:textSize="70dip"
android:textStyle="bold"
/>
It may be something simple that I'm missing. Anything to help me further understand the code is appreciated!
I believe that the error you get is "runtime-error - close application".
If you look at method setText(...) that is overloaded you will see that it takes arguments with CharSequence (this is probably what you want) and int resId (this is what you provide).
resId - will seek if there is an resource in /values/strings.xml with given name attribute.
The resolution is to provide String:
days_int_remaining.setText(String.valueOf(returning));
just use
TextView days_int_remaining = (TextView) findViewById(R.id.days_int_remaining);
days_int_remaining.setText(String.valueOf(returning));
instead of
TextView days_int_remaining = (TextView) findViewById(R.id.days_int_remaining);
days_int_remaining.setText(returning);
Turn your returning int into a string.
Try this code :
Basically you have to convert your int value to a string before calling setText();
public class MyFirstActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView days_int_remaining = (TextView) findViewById(R.id.days_int_remaining);
int resultat = calculateResult(2012, 9, 29);
days_int_remaining.setText(Integer.toString(resultat));
}
private int calculateResult(int year, int month, int day) {
long days = 0L;
int returning = 0;
java.util.Calendar cal = new java.util.GregorianCalendar(year, month-1, day);
long todayMI = new java.util.Date().getTime();
long calMI = cal.getTimeInMillis();
long millDiff = calMI - todayMI;
if (millDiff < 0) {
returning = 0;
} else {
days = millDiff / 1000 / 60 / 60;
returning = (int) Math.ceil(days / 24f);
}
return returning;
}
}
I have got a TimePickerDialog working to set time which is set to a TextView in order to display it. Now, I need help to set that TimePicker (inside the TimePickerDialog) minutues interval to 15 minutes. I have seen there is a post with 15 minutes interval issue related to TimePicker, but I don't know how to apply it to the TimePickerDialog because I don't know how to use the TimePicker that it is created inside the TimePickerDialog. I am new to Android and completely lost in this matter. Thanks in advance.
Using a combination of this from #Rizwan and this other thread, I came up with a combined solution that allows arbitrary minute increments in a TimePickerDialog. The main issue is that most of the functionality is hidden by the android TimePickerDialog and TimePicker classes and it doesn't appear to allow
Extend TimePickerDialog to allow us easier access
Use reflection to reach inside the display and access the required bits (see below)
rewire the minute 'NumberPicker' to display our values
rewire the TimePicker to receive and return values form the NumberPicker honoring our custom increment.
block onStop() so that it doesn't reset the value on close.
Warning
The main issue with reaching inside the UI is that elements are referenced by ids which are likely to change, and even the name of the id is not guaranteed to be the same forever. Having said that, this is working, stable solution and likely to work for the foreseeable future. In my opinion the empty catch block should warn that the UI has changed and should fall back to the default (increment 1 minute) behaviour.
Solution
private class DurationTimePickDialog extends TimePickerDialog
{
final OnTimeSetListener mCallback;
TimePicker mTimePicker;
final int increment;
public DurationTimePickDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView, int increment)
{
super(context, callBack, hourOfDay, minute/increment, is24HourView);
this.mCallback = callBack;
this.increment = increment;
}
#Override
public void onClick(DialogInterface dialog, int which) {
if (mCallback != null && mTimePicker!=null) {
mTimePicker.clearFocus();
mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
mTimePicker.getCurrentMinute()*increment);
}
}
#Override
protected void onStop()
{
// override and do nothing
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
try
{
Class<?> rClass = Class.forName("com.android.internal.R$id");
Field timePicker = rClass.getField("timePicker");
this.mTimePicker = (TimePicker)findViewById(timePicker.getInt(null));
Field m = rClass.getField("minute");
NumberPicker mMinuteSpinner = (NumberPicker)mTimePicker.findViewById(m.getInt(null));
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue((60/increment)-1);
List<String> displayedValues = new ArrayList<String>();
for(int i=0;i<60;i+=increment)
{
displayedValues.add(String.format("%02d", i));
}
mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
constructor accepts the increment value and retains some other references. Note that this omits error checking and we'd prefer 60%increment==0
onCreate uses the name of the UI fields and reflection to discover the current location. Again this omits error checking and should be 'fail-safe' ie revert to default behaviour if something goes wrong.
onClick overridden to return the correct minute value to the callback listener
onStop overridden to prevent the (incorrect) index value being returned a second time, when the dialog closes. Go on, try it yourself.
Most of this comes from digging into the TimePickerDialog source.
UPDATE FOR ANDROID 11+
The reflection used in the example above was marked as greylist-max-q, meaning it would no longer be possible after Android 10 (API 29 - Q). In the short term (until August 2021) it is possible to drop the target version back to API 29 while still building against Android 11 (API 30 - R) but after this date the Play Store will no longer accept these builds and will require API 30 as the build target. This eventual failure was anticipated and noted in the warning above.
well thats fine if you used time-picker instead of time-picker-dialog. But there is a solution for this actually.. here is what I used to meet the same requirement.. I used CustomTimePickerDialog. Every thing will be same, only TimePickerDialog will change to CustomTimePickerDialog in the code.
CustomTimePickerDialog timePickerDialog = new CustomTimePickerDialog(myActivity.this, timeSetListener,
Calendar.getInstance().get(Calendar.HOUR),
CustomTimePickerDialog.getRoundedMinute(Calendar.getInstance().get(Calendar.MINUTE) + CustomTimePickerDialog.TIME_PICKER_INTERVAL),
false
);
timePickerDialog.setTitle("2. Select Time");
timePickerDialog.show();
Here is my CustomTimePickerDialog class... Just use this class in your project and change TimePickerDialog to CustomTimePickerDialog..
public class CustomTimePickerDialog extends TimePickerDialog{
public static final int TIME_PICKER_INTERVAL=10;
private boolean mIgnoreEvent=false;
public CustomTimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute,
boolean is24HourView) {
super(context, callBack, hourOfDay, minute, is24HourView);
}
/*
* (non-Javadoc)
* #see android.app.TimePickerDialog#onTimeChanged(android.widget.TimePicker, int, int)
* Implements Time Change Interval
*/
#Override
public void onTimeChanged(TimePicker timePicker, int hourOfDay, int minute) {
super.onTimeChanged(timePicker, hourOfDay, minute);
this.setTitle("2. Select Time");
if (!mIgnoreEvent){
minute = getRoundedMinute(minute);
mIgnoreEvent=true;
timePicker.setCurrentMinute(minute);
mIgnoreEvent=false;
}
}
public static int getRoundedMinute(int minute){
if(minute % TIME_PICKER_INTERVAL != 0){
int minuteFloor = minute - (minute % TIME_PICKER_INTERVAL);
minute = minuteFloor + (minute == minuteFloor + 1 ? TIME_PICKER_INTERVAL : 0);
if (minute == 60) minute=0;
}
return minute;
}
}
After using this CustomTimePickerDialog class, All you will need to do is use CustomTimePickerDialog instead of TimePickerDialog in your code to access/override default functions of TimePickerDialog class. In the simple way, I mean your timeSetListener will be as following after this...
private CustomTimePickerDialog.OnTimeSetListener timeSetListener = new CustomTimePickerDialog.OnTimeSetListener() {
#Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
}
}// using CustomTimePickerDialog
You can use a regular AlertDialog and use setView to include a custom TimePicker view.
/**
* Set TimePicker interval by adding a custom minutes list
* TIME_PICKER_INTERVAL = Enter your Minutes;
* #param timePicker
*/
private void setTimePickerInterval(TimePicker timePicker) {
try {
int TIME_PICKER_INTERVAL = 10;
NumberPicker minutePicker = (NumberPicker) timePicker.findViewById(Resources.getSystem().getIdentifier(
"minute", "id", "android"));
minutePicker.setMinValue(0);
minutePicker.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
List<String> displayedValues = new ArrayList<String>();
for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
displayedValues.add(String.format("%02d", i));
}
minutePicker.setDisplayedValues(displayedValues.toArray(new String[0]));
} catch (Exception e) {
Log.e(TAG, "Exception: " + e);
}
}