The bounty expires in 7 days. Answers to this question are eligible for a +50 reputation bounty.
MARSH is looking for an answer from a reputable source:
Please help me this is happening because of Localisation but i have debug code i am seeing its going in English language but its showing spanish language
This is popup for time picker.
when I click on keyboard icon it's showing like below screen.
I am using localization in our APP and below code I have written to open Time picker Popup
private fun openTimePickerDialog(datetime: String) {
val mHour: Int = datetime.substring(8, 10).toInt()
val mMinute: Int = datetime.substring(10, 12).toInt()
setDefaultLanguage()
Log.i("TAG", "openTimePickerDialog: $mHour $mMinute")
val timePickerDialog = TimePickerDialog(
activity,
{ _, hourOfDay, minute ->
var selectedMinute = minute.toString()
var selectedHour = hourOfDay.toString()
if (minute < 10) {
selectedMinute = "0$selectedMinute"
}
if (hourOfDay < 10) {
selectedHour = "0$selectedHour"
}
isClickedDate = ""
val date: String = datetime.substring(0, 8)
val time = selectedHour + selectedMinute + "00"
Log.i("TAG", "onTimeSet: $date$time")
roveR3SettingFragmentViewModel.setDateTime(date + time)
// txtTime.setText(hourOfDay + ":" + minute);
}, mHour, mMinute, false
)
timePickerDialog.setButton(
DatePickerDialog.BUTTON_POSITIVE,
getString(R.string.ok),
timePickerDialog
)
timePickerDialog.setButton(
DatePickerDialog.BUTTON_NEGATIVE,
getString(R.string.txt_cancel),
timePickerDialog
)
timePickerDialog.show()
}
private fun setDefaultLanguage() {
if (appPreference.appLanguage == LANGAUGE_ES) {
val locale1 = Locale("en")
Locale.setDefault(locale1)
val config = requireContext().resources.configuration
config.setLocale(locale1)
requireContext().createConfigurationContext(config)
} else if (appPreference.appLanguage == LANGAUGE_ES) {
val locale1 = Locale("ja")
Locale.setDefault(locale1)
val config = requireContext().resources.configuration
config.setLocale(locale1)
requireContext().createConfigurationContext(config)
}
}
Can any one please help me how to fix the language issue which is coming when i click on keyboard icon of time picker dialogue. I want it in english language I have selected it for English only other all thing coming in english but time picker is coming in Spanish language. Thanks.
Check the setDefaultLanguage() method in your code carefully.
Conditions for both if & else if looks the same, so always it will run the functions in the else if section.
Try to use a different condition for else if
Check the example code here,
private fun setDefaultLanguage() {
if (appPreference.appLanguage == CONDITION_1) {
val locale1 = Locale("en")
Locale.setDefault(locale1)
val config = requireContext().resources.configuration
config.setLocale(locale1)
requireContext().createConfigurationContext(config)
} else if (appPreference.appLanguage == CONDITION_2) {
val locale1 = Locale("ja")
Locale.setDefault(locale1)
val config = requireContext().resources.configuration
config.setLocale(locale1)
requireContext().createConfigurationContext(config)
}
}
In your scenario, both condition 1 and 2 are same. So, always the popup using the language from else if
Related
How can I get the dates of the current week using kotlinx.datetime KMM library?
eg. I want to get a list of current week's date like:
("Monday, 07", "Tuesday, 08", "Wednesday, 09", ... )
This is a similar impementation using Calendar:
fun getDaysOfWeek(): Array<String?> {
val dateFormat = SimpleDateFormat("EEEEE\ndd", Locale.getDefault())
val calendar = Calendar.getInstance()
calendar.firstDayOfWeek = Calendar.MONDAY
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY)
val days = arrayOfNulls<String>(7)
for (i in 0..6) {
days[i] = dateFormat.format(calendar.time)
calendar.add(Calendar.DAY_OF_MONTH, 1)
}
return days
}
val today = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date
val days = mutableListOf<LocalDate>()
val firstWeekDay = today.daysShift(-DayOfWeek.values().indexOf(today.dayOfWeek))
for (i in 0 until DayOfWeek.values().count()) {
days.add(firstWeekDay.daysShift(i))
}
val dayStrings = days.map { "${it.dayOfWeek}, ${it.dayOfMonth}" }
println("$dayStrings")
fun LocalDate.daysShift(days: Int): LocalDate = when {
days < 0 -> {
minus(DateTimeUnit.DayBased(-days))
}
days > 0 -> {
plus(DateTimeUnit.DayBased(days))
}
else -> this
}
I am creating android library. In lib there is screen with 3 edittexts. User enters day, month and year. I have to find out is user older than 18.
I don't have any documentation for error handling or anything for this task. So I did something on my own.
My function for checking is user older than 18 is like this:
fun isUserAdult(birthDay: String, birthMonth: String, birthYear: String): Boolean {
val year = Integer.parseInt(birthDay)
val month = Integer.parseInt(birthMonth)
val day = Integer.parseInt(birthYear)
val c1 = Calendar.getInstance()
c1.set(year, month - 1, day, 0, 0)
val c2 = Calendar.getInstance()
var diff = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR)
if (c1.get(Calendar.MONTH) > c2.get(Calendar.MONTH) ||
(c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH) && c1.get(Calendar.DATE) > c2.get(
Calendar.DATE
))
) {
diff--
}
return diff >= 18
}
My error handling is based just on my logic. It looks something like this:
fun isDataValid(birthDay: String, birthMonth: String, birthYear: String): Boolean {
return !(birthDay.startsWith("0") && birthMonth.startsWith("0") && birthYear.startsWith("0") || Integer.parseInt(
birthMonth
) > 12 || Integer.parseInt(birthDay) > 31 || Calendar.getInstance()
.get(Calendar.YEAR) < Integer.parseInt(birthYear) || Integer.parseInt(birthYear)< 1880)
}
This looks fine on the first look but I believe there are a lot of cases when considering date that makes my code error-prone.
Is there any other way to do this or has anyone some advice on how to improve my way?
I'm building an Android App with Kotlin that uses various NYTimes APIs to fetch different news data..
Here I have a search screen where I want the user to be able to enter a search query (i.e. "Japan") and check off any checkbox and they will even be able to add a begin or end date to refine their search :
Typing something in the search query and checking off at least one box are the only requirements, everything else will be mandatory. And once they hit "Search", it will pass the data they entered to a second activity which will use the data to put together an api call, make the api call, and populate a recyclerview , like so:
Now here is my issue...
I have the SEARCH button only sending data if the search query has been entered and if the travel checkbox has been checked, and as you can imagine there are a TON of combinations.. I don't know how I can pass over all of those combinations and make each API Call accordingly without having an extremely long If/Else Block that'll take forever...
Using Kotlin, there has to be a more efficient way right ?
Here is my Search Activity:
class SearchActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search)
search_query_edittext.getBackground().clearColorFilter();
actionBar?.setDisplayHomeAsUpEnabled(true)
Enter_Begin_Date.setPaintFlags(Enter_Begin_Date.getPaintFlags())
Enter_End_Date.setPaintFlags(Enter_End_Date.getPaintFlags())
// Calendar
val c = Calendar.getInstance()
val year = c.get(Calendar.YEAR)
val month = c.get(Calendar.MONTH)
val day = c.get(Calendar.DAY_OF_MONTH)
// TextView Clicked to show Date Picker Dialog
Enter_Begin_Date.setOnClickListener {
val dpd = DatePickerDialog(
this,
DatePickerDialog.OnDateSetListener { view, Year, Month, Day ->
// set to textView
if (Day < 10 && Month < 10) {
Enter_Begin_Date.text =
"0" + Day + "/0" + Month.toInt().plus(1) + "/" + Year
} else if (Day < 10 && Month >= 10) {
Enter_Begin_Date.text = "0" + Day + "/" + Month.toInt().plus(1) + "/" + Year
} else if (Day >= 10 && Month < 10) {
Enter_Begin_Date.text = "" + Day + "/0" + Month.toInt().plus(1) + "/" + Year
}
},
year,
month,
day
)
// show dialog
dpd.show()
}
Enter_End_Date.setOnClickListener {
val dpd = DatePickerDialog(
this,
DatePickerDialog.OnDateSetListener { view, Year, Month, Day ->
// set to textView
if (Day < 10 && Month < 10) {
Enter_End_Date.text = "0" + Day + "/0" + Month.toInt().plus(1) + "/" + Year
} else if (Day < 10 && Month >= 10) {
Enter_End_Date.text = "0" + Day + "/" + Month.toInt().plus(1) + "/" + Year
} else if (Day >= 10 && Month < 10) {
Enter_End_Date.text = "" + Day + "/0" + Month.toInt().plus(1) + "/" + Year
}
},
year,
month,
day
)
// show dialog
dpd.show()
}
searchButton.setOnClickListener {
if ((search_query_edittext.text.isNotEmpty()
&& Enter_Begin_Date.text.isEmpty()
&& Enter_End_Date.text.isEmpty()) && TravelTextBox.isChecked && !SportsTextBox.isChecked && !PoliticsTextBox.isChecked && !EntrepreneursTextBox.isChecked && !BusinessTextBox.isChecked && !ArtsCheckBox.isChecked
) {
val searchQuery: String = search_query_edittext.text.toString()
val query = searchQuery
val travelCategory: String = "Travel"
val intent = Intent(this#SearchActivity, ResultsActivity::class.java)
intent.putExtra("query", query)
intent.putExtra("travelCategory", travelCategory)
startActivity(intent)
}
}
}
}
My Result Activity:
class ResultsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_results)
val bundle: Bundle? = intent.extras
val myQuery = bundle!!.getString("query")
val myTravelCategory = bundle!!.getString("travelCategory")
if (bundle.containsKey("query") && bundle.containsKey("travelCategory")) {
lifecycleScope.launch(IO) {
val result = ApiClient.getClient.getSearchResultWithCheckbox(query = myQuery!!,
category = myTravelCategory!!,
api_key = (MYAPIKEY)
withContext(Main) {
SearchResultsRecyclerView.apply {
layoutManager = LinearLayoutManager(this#ResultsActivity)
adapter = SearchResultsAdapter(result.response.docs)
}
}
}
}
}
}
As you can see, I only have coded enough to cover for the user to enter in the search query , to check the travel checkbox and to hit enter, there are like 145 more combinations (search query + begin date + politics checkbox, search query + end date + sports checkbox, etc etc..)
How can I add in all of the other combinations without using an extremely long If/Else block?
Anything to push me in the right direction would be highly appreciated , thanks!
check for the condition you want, not the combinations that produce it.
Check if the search query is filled and that at least one checkbox is checked. Without knowing how the API works is hard to recommend a particular way to pass the data but taking advantage of nullable types and/or optional paramaters with something like this should work:
private fun getCheckedCategories() : List<String> = listOfNotNull(
"Travel".takeIf { TravelTextBox.isChecked },
...
)
private fun atLeastOneCheckBoxChecked() = getCheckedCategories().isNotEmpty()
With this helper functions you can build a listener similar to this:
searchButton.setOnClickListener {
if (search_query_edittext.text.isNotEmpty() && atLeastOneCheckBoxChecked()) {
val searchQuery: String = search_query_edittext.text.toString()
val checkedCategories = getCheckedCategories()
val beginDate : String? = TODO()
val endDate : String? = TODO()
val intent = Intent(this#SearchActivity, ResultsActivity::class.java)
intent.putExtra("query", searchQuery)
intent.putStringArrayList("checkedCategories", ArrayList(checkedCategories))
intent.putExtra("beginDate", beginDate)
intent.putExtra("endDate", endDate)
startActivity(intent)
}
}
In the other end the bundle?.getString("beginDate") will return null if not passed, and whatever value it has if passed. Or retrieve the list of passed checkboxes with bundle?getStringArrayList("checkedCategories").orEmpty()
I have a date in the future and have to format the remaining time until this day like so.
4 days
1 month, 4 days
1 year, 1 month
I have looked at the DateUtils documentation but haven't seen this exact format.
I'm also fine using an external library like threetenabp.
Is there a library that can handle both the time calculation and the localization of the strings?
I wrote this blog a while ago, it shows how to do the opposite of what you are asking :-) https://blog.blundellapps.co.uk/creating-comments-with-timestamps-like-youtube/ i.e. given a time, say how long ago that was.
Android also offers this solution for times in the past: https://developer.android.com/reference/android/text/format/DateUtils.html#getRelativeDateTimeString(android.content.Context,%20long,%20long,%20long,%20int).
So you need the opposite of these!
It should not be too hard to inverse. Instead of using the time now and negating the difference of a time in the past. You use the time now and add the time in the future.
So the inverse of: https://github.com/blundell/YouTubeTimeStamps/blob/master/app/src/main/java/com/blundell/tut/TimeStampFormatter.kt
The main difference being you want a difference between now and a date in the future, like so:
private fun getMillisFromNow(futureTime: Date): Long {
val futureTimeMillis = futureTime.time
val nowMillis = System.currentTimeMillis()
return futureTimeMillis - nowMillis
}
And then format it. Something like this:
fun format(timestamp: Date): String {
val millisFromNow = getMillisFromNow(timestamp)
val minutesFromNow = TimeUnit.MILLISECONDS.toMinutes(millisFromNow)
if (minutesFromNow < 1) {
return "about now"
}
val hoursFromNow = TimeUnit.MILLISECONDS.toHours(millisFromNow)
if (hoursFromNow < 1) {
return formatMinutes(minutesFromNow)
}
val daysFromNow = TimeUnit.MILLISECONDS.toDays(millisFromNow)
if (daysFromNow < 1) {
return formatHours(hoursFromNow)
}
val weeksFromNow = TimeUnit.MILLISECONDS.toDays(millisFromNow) / 7
if (weeksFromNow < 1) {
return formatDays(daysFromNow)
}
val monthsFromNow = TimeUnit.MILLISECONDS.toDays(millisFromNow) / 30
if (monthsFromNow < 1) {
return formatWeeks(weeksFromNow)
}
val yearsFromNow = TimeUnit.MILLISECONDS.toDays(millisFromNow) / 365
return if (yearsFromNow < 1) {
formatMonths(monthsFromNow)
} else formatYears(yearsFromNow)
}
private fun getMillisFromNow(futureTime: Date): Long {
val futureTimeMillis = futureTime.time
val nowMillis = System.currentTimeMillis()
return futureTimeMillis - nowMillis
}
private fun formatMinutes(minutes: Long): String {
return format(minutes, " minute to go", " minutes to go")
}
private fun formatHours(hours: Long): String {
return format(hours, " hour to go", " hours to go")
}
private fun formatDays(days: Long): String {
return format(days, " day to go", " days to go")
}
private fun formatWeeks(weeks: Long): String {
return format(weeks, " week to go", " weeks to go")
}
private fun formatMonths(months: Long): String {
return format(months, " month to go", " months to go")
}
private fun formatYears(years: Long): String {
return format(years, " year to go", " years to go")
}
private fun format(hand: Long, singular: String, plural: String): String {
return if (hand == 1L) {
hand.toString() + singular
} else {
hand.toString() + plural
}
}
Just sanity checked it with this test:
#Test
fun test() {
val twoDaysInMillisInstant = Instant.now().plusMillis(TimeUnit.HOURS.toMillis(50))
val result = format(Date.from(twoDaysInMillisInstant))
assertEquals("2 days to go", result)
}
For the localization, you can convert this to using Strings.xml.
using threeten's LocalDate you can get the remaining years, months and day from one date to another. Having that values you can 0-check them and show only ones that are > 0.
Simple example:
val futureDate = LocalDate.of(2020,2,20)
val todayDate = LocalDate.now()
val remainingYears = futureDate.year - todayDate.year //output 0
val remainingMonth = futureDate.monthValue - todayDate.monthValue //output 0
val remainingDays = futureDate.dayOfMonth - todayDate.dayOfMonth // output 16
I hope that is what you wanted, cheers!
I'm trying to build an age calculator application. When I didn't enter a number in one of the EditTexts and click on calculate Button, my app is crashed! "App has stopped" and click the photo
I tried to set yearbirth.isEmpty() || yearbirth.equals("") || yearbirth == null , but nothing worked.
CODE:-
class MainActivity : AppCompatActivity() {
var yearage:Int?= null
var monthage:Int?= null
var dayage:Int?= null
#SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
buGetAge.setOnClickListener({
val year= Calendar.getInstance().get(Calendar.YEAR)
val month= Calendar.getInstance().get(Calendar.MONTH)
val day= Calendar.getInstance().get(Calendar.DAY_OF_MONTH)
var yearage = year - Integer.parseInt(yearbirth.text.toString()) -1
val monthage:Int?
val dayage:Int?
if (yearbirth== null) {
Toast.makeText(this, "You have to enter your year berth", Toast.LENGTH_LONG).show()
} else {
if (month < Integer.parseInt(monthbirth.text.toString())){
monthage=(Integer.parseInt(monthbirth.text.toString())- month- 12)* -1
}else if (month > Integer.parseInt(monthbirth.text.toString())) {
yearage=year- Integer.parseInt(yearbirth.text.toString())
monthage= (Integer.parseInt(monthbirth.text.toString())- month)* -1
}else {
yearage=year- Integer.parseInt(yearbirth.text.toString())
monthage=0
}
if (day < Integer.parseInt(daybirth.text.toString())){
dayage= (Integer.parseInt(daybirth.text.toString())- day- 30)* -1
}else if (day > Integer.parseInt(daybirth.text.toString())){
dayage= day- Integer.parseInt(daybirth.text.toString())
}else {
dayage=0
}
val a= (yearage* 12)+ monthage
val b= (a * 30)+ dayage
val ageinyears= "$yearage years"
val ageinmonths= "$a months"
val ageindays= "$b days"
txtshow.text = "Your age is $yearage years, $monthage months and $dayage days"
txtshow2.text = "\nYOUR AGE:\nin years:\n\nin months:\n\nin days:"
txtshow3.text = "\n\n$ageinyears \n\n$ageinmonths \n\n $ageindays "
this.yearage=yearage
this.monthage=monthage
this.dayage=dayage
}
})
}
}
Verify that yearbirth.text.toString() is not empty before attempting to parse it into an Integer (and also if it's a valid integer.)
To achieve so, put the line you showed in your code:
var yearage = year - Integer.parseInt(yearbirth.text.toString()) -1
Inside an if verifying that the input is valid, like so:
if(yearbirth.text.toString().matches(Regex("\\d+")))
var yearage = year - Integer.parseInt(yearbirth.text.toString()) -1
You can check for empty Input like this:
newString = Integer.toString(yearbirth).trim();
if (newString.matches("")) {
Toast.makeText(this, "EditText is empty", Toast.LENGTH_SHORT).show();
return;
}