mirror of
https://github.com/hmalik144/Weather-apps.git
synced 2026-03-18 15:36:04 +00:00
Refactor flavours (#17)
- Fastlane completed - Circleci config completed - Flavours build completed
This commit is contained in:
@@ -2,9 +2,6 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
|
||||
<application
|
||||
android:name="com.appttude.h_mal.atlas_weather.application.AppClass"
|
||||
android:allowBackup="true"
|
||||
@@ -15,7 +12,7 @@
|
||||
android:theme="@style/AppTheme"
|
||||
tools:node="merge">
|
||||
<activity
|
||||
android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.MainActivity"
|
||||
android:name="com.appttude.h_mal.atlas_weather.ui.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
@@ -27,18 +24,15 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.settings.UnitSettingsActivity"
|
||||
android:label="Settings" />
|
||||
|
||||
<activity android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.widget.WidgetLocationPermissionActivity"
|
||||
<activity android:name="com.appttude.h_mal.monoWeather.ui.widget.WidgetLocationPermissionActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<receiver android:name="com.appttude.h_mal.atlas_weather.monoWeather.widget.NewAppWidget"
|
||||
<receiver android:name="com.appttude.h_mal.atlas_weather.widget.NewAppWidget"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
@@ -52,7 +46,7 @@
|
||||
</receiver>
|
||||
|
||||
<service
|
||||
android:name="com.appttude.h_mal.atlas_weather.monoWeather.widget.WidgetJobServiceIntent"
|
||||
android:name="com.appttude.h_mal.atlas_weather.widget.WidgetJobServiceIntent"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE" />
|
||||
</application>
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.appttude.h_mal.atlas_weather.application.LOCATION_PERMISSION_REQUEST
|
||||
import com.appttude.h_mal.atlas_weather.utils.Event
|
||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||
import com.appttude.h_mal.atlas_weather.utils.hide
|
||||
import com.appttude.h_mal.atlas_weather.utils.show
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.ApplicationViewModelFactory
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.android.x.kodein
|
||||
import org.kodein.di.generic.instance
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
abstract class BaseFragment(@LayoutRes contentLayoutId: Int) : Fragment(contentLayoutId), KodeinAware {
|
||||
|
||||
override val kodein by kodein()
|
||||
val factory by instance<ApplicationViewModelFactory>()
|
||||
|
||||
inline fun <reified VM : ViewModel> getFragmentViewModel(): Lazy<VM> = viewModels { factory }
|
||||
|
||||
private var shortAnimationDuration by Delegates.notNull<Int>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
shortAnimationDuration = resources.getInteger(android.R.integer.config_shortAnimTime)
|
||||
}
|
||||
|
||||
// toggle visibility of progress spinner while async operations are taking place
|
||||
fun progressBarStateObserver(progressBar: View) = Observer<Event<Boolean>> {
|
||||
when (it.getContentIfNotHandled()) {
|
||||
true -> progressBar.fadeIn()
|
||||
false -> progressBar.fadeOut()
|
||||
}
|
||||
}
|
||||
|
||||
// display a toast when operation fails
|
||||
fun errorObserver() = Observer<Event<String>> {
|
||||
it.getContentIfNotHandled()?.let { message ->
|
||||
displayToast(message)
|
||||
}
|
||||
}
|
||||
|
||||
fun refreshObserver(refresher: SwipeRefreshLayout) = Observer<Event<Boolean>> {
|
||||
refresher.isRefreshing = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a permission for
|
||||
* @param permission with
|
||||
* @param permissionCode
|
||||
* Callback if is already permission granted
|
||||
* @param permissionGranted
|
||||
*/
|
||||
fun getPermissionResult(
|
||||
permission: String,
|
||||
permissionCode: Int,
|
||||
permissionGranted: () -> Unit
|
||||
) {
|
||||
if (ActivityCompat.checkSelfPermission(requireContext(), permission) != PackageManager.PERMISSION_GRANTED) {
|
||||
requestPermissions(arrayOf(permission), permissionCode)
|
||||
return
|
||||
} else {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
permissionGranted.invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun View.fadeIn() {
|
||||
apply {
|
||||
// Set the content view to 0% opacity but visible, so that it is visible
|
||||
// (but fully transparent) during the animation.
|
||||
alpha = 0f
|
||||
hide()
|
||||
|
||||
// Animate the content view to 100% opacity, and clear any animation
|
||||
// listener set on the view.
|
||||
animate()
|
||||
.alpha(1f)
|
||||
.setDuration(shortAnimationDuration.toLong())
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
show()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun View.fadeOut() {
|
||||
apply {
|
||||
// Set the content view to 0% opacity but visible, so that it is visible
|
||||
// (but fully transparent) during the animation.
|
||||
alpha = 1f
|
||||
show()
|
||||
|
||||
// Animate the content view to 100% opacity, and clear any animation
|
||||
// listener set on the view.
|
||||
animate()
|
||||
.alpha(0f)
|
||||
.setDuration(shortAnimationDuration.toLong())
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
hide()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String?>, grantResults: IntArray) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
if (requestCode == LOCATION_PERMISSION_REQUEST) {
|
||||
if (grantResults.isNotEmpty() &&
|
||||
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
permissionsGranted()
|
||||
displayToast("Permission granted")
|
||||
} else {
|
||||
permissionsRefused()
|
||||
displayToast("Permission denied")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open fun permissionsGranted() {}
|
||||
open fun permissionsRefused() {}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
import androidx.navigation.ui.setupActionBarWithNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.settings.UnitSettingsActivity
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import kotlinx.android.synthetic.main.activity_main_navigation.*
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
lateinit var navHost: NavHostFragment
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main_navigation)
|
||||
|
||||
val navView: BottomNavigationView = findViewById(R.id.nav_view)
|
||||
setSupportActionBar(toolbar)
|
||||
|
||||
navHost = supportFragmentManager
|
||||
.findFragmentById(R.id.container) as NavHostFragment
|
||||
val navController = navHost.navController
|
||||
navController.setGraph(R.navigation.main_navigation)
|
||||
|
||||
setupBottomBar(navView, navController)
|
||||
}
|
||||
|
||||
private fun setupBottomBar(navView: BottomNavigationView, navController: NavController) {
|
||||
val tabs = setOf(R.id.nav_home, R.id.nav_world)
|
||||
val appBarConfiguration = AppBarConfiguration(tabs)
|
||||
|
||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||
navView.setupWithNavController(navController)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
menuInflater.inflate(R.menu.menu_main, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
when (item.itemId) {
|
||||
R.id.action_settings -> {
|
||||
val i = Intent(this, UnitSettingsActivity::class.java)
|
||||
startActivity(i)
|
||||
return true
|
||||
}
|
||||
android.R.id.home -> onBackPressed()
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.settings
|
||||
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceActivity
|
||||
import android.preference.PreferenceFragment
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.widget.NewAppWidget
|
||||
|
||||
|
||||
class UnitSettingsActivity : PreferenceActivity() {
|
||||
private var prefListener: OnSharedPreferenceChangeListener? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
PreferenceManager.setDefaultValues(this, R.xml.prefs_screen, false)
|
||||
fragmentManager.beginTransaction().replace(android.R.id.content, MyPreferenceFragment()).commit()
|
||||
|
||||
//listener on changed sort order preference:
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext)
|
||||
prefListener = OnSharedPreferenceChangeListener { _, key ->
|
||||
if (key == "temp_units") {
|
||||
val intent = Intent(baseContext, NewAppWidget::class.java)
|
||||
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
val ids = AppWidgetManager.getInstance(application).getAppWidgetIds(ComponentName(application, NewAppWidget::class.java))
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
|
||||
if (key == "widget_black_background"){
|
||||
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE)
|
||||
val widgetManager = AppWidgetManager.getInstance(this)
|
||||
val ids = widgetManager.getAppWidgetIds(ComponentName(this, NewAppWidget::class.java))
|
||||
AppWidgetManager.getInstance(this).notifyAppWidgetViewDataChanged(ids, R.id.whole_widget_view)
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
}
|
||||
prefs.registerOnSharedPreferenceChangeListener(prefListener)
|
||||
}
|
||||
|
||||
|
||||
class MyPreferenceFragment : PreferenceFragment() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
addPreferencesFromResource(R.xml.prefs_screen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.widget
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.app.PendingIntent.FLAG_IMMUTABLE
|
||||
import android.app.TaskStackBuilder
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.widget.RemoteViews
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.core.app.JobIntentService
|
||||
import com.squareup.picasso.Picasso
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
abstract class BaseWidgetServiceIntentClass<T : AppWidgetProvider> : JobIntentService() {
|
||||
|
||||
lateinit var appWidgetManager: AppWidgetManager
|
||||
lateinit var appWidgetIds: IntArray
|
||||
|
||||
fun initBaseWidget(componentName: ComponentName) {
|
||||
appWidgetManager = AppWidgetManager.getInstance(baseContext)
|
||||
appWidgetIds = appWidgetManager.getAppWidgetIds(componentName)
|
||||
}
|
||||
|
||||
fun createRemoteView(@LayoutRes id: Int): RemoteViews {
|
||||
return RemoteViews(packageName, id)
|
||||
}
|
||||
|
||||
// Create pending intent commonly used for 'click to update' features
|
||||
fun createUpdatePendingIntent(
|
||||
appWidgetProvider: Class<T>,
|
||||
appWidgetId: Int
|
||||
): PendingIntent? {
|
||||
val seconds = (System.currentTimeMillis() / 1000L).toInt()
|
||||
val intentUpdate = Intent(applicationContext, appWidgetProvider)
|
||||
intentUpdate.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
val idArray = intArrayOf(appWidgetId)
|
||||
intentUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, idArray)
|
||||
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
PendingIntent.getBroadcast(this, seconds, intentUpdate, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||
} else {
|
||||
PendingIntent.getBroadcast(this, seconds, intentUpdate, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create a pending intent used to navigate to activity:
|
||||
* @param activityClass
|
||||
*/
|
||||
fun <T : Activity> createClickingPendingIntent(activityClass: Class<T>): PendingIntent {
|
||||
val clickIntentTemplate = Intent(this, activityClass)
|
||||
|
||||
return TaskStackBuilder.create(this)
|
||||
.addNextIntentWithParentStack(clickIntentTemplate)
|
||||
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE)
|
||||
}
|
||||
|
||||
fun setImageView(
|
||||
path: String?,
|
||||
views: RemoteViews,
|
||||
@IdRes viewId: Int,
|
||||
appWidgetId: Int
|
||||
) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
Picasso.get().load(path).into(views, viewId, intArrayOf(appWidgetId))
|
||||
}
|
||||
}
|
||||
|
||||
open fun bindView(widgetId: Int, views: RemoteViews, data: Any?) {}
|
||||
open fun bindEmptyView(widgetId: Int, views: RemoteViews, data: Any?) {}
|
||||
open fun bindErrorView(widgetId: Int, views: RemoteViews, data: Any?) {}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.widget
|
||||
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.widget.WidgetJobServiceIntent.Companion.enqueueWork
|
||||
|
||||
/**
|
||||
* Implementation of App Widget functionality.
|
||||
*/
|
||||
class NewAppWidget : AppWidgetProvider() {
|
||||
|
||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||
super.onUpdate(context, appWidgetManager, appWidgetIds)
|
||||
|
||||
loadWidget(context)
|
||||
}
|
||||
|
||||
override fun onEnabled(context: Context) {
|
||||
super.onEnabled(context)
|
||||
|
||||
loadWidget(context)
|
||||
}
|
||||
|
||||
override fun onDisabled(context: Context) { }
|
||||
|
||||
private fun loadWidget(context: Context){
|
||||
val mIntent = Intent(context, WidgetJobServiceIntent::class.java)
|
||||
enqueueWork(context, mIntent)
|
||||
}
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.widget
|
||||
|
||||
import android.Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.PendingIntent
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
||||
import android.icu.text.SimpleDateFormat
|
||||
import android.os.PowerManager
|
||||
import android.widget.RemoteViews
|
||||
import android.os.Build
|
||||
import androidx.core.app.ActivityCompat.checkSelfPermission
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.helper.ServicesHelper
|
||||
import com.appttude.h_mal.atlas_weather.model.widget.InnerWidgetCellData
|
||||
import com.appttude.h_mal.atlas_weather.model.widget.WidgetWeatherCollection
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.MainActivity
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.widget.WidgetState.*
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.widget.WidgetState.Companion.getWidgetState
|
||||
import com.appttude.h_mal.atlas_weather.utils.isInternetAvailable
|
||||
import com.appttude.h_mal.atlas_weather.utils.tryOrNullSuspended
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.LateInitKodein
|
||||
import org.kodein.di.generic.instance
|
||||
import java.util.*
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of a JobIntentService used for home screen widget
|
||||
*/
|
||||
const val HALF_DAY = 43200000L
|
||||
class WidgetJobServiceIntent : BaseWidgetServiceIntentClass<NewAppWidget>() {
|
||||
|
||||
private val kodein = LateInitKodein()
|
||||
private val helper: ServicesHelper by kodein.instance()
|
||||
|
||||
override fun onHandleWork(intent: Intent) {
|
||||
// We have received work to do. The system or framework is already
|
||||
// holding a wake lock for us at this point, so we can just go.
|
||||
kodein.baseKodein = (applicationContext as KodeinAware).kodein
|
||||
executeWidgetUpdate()
|
||||
}
|
||||
|
||||
private fun executeWidgetUpdate() {
|
||||
val componentName = ComponentName(this, NewAppWidget::class.java)
|
||||
initBaseWidget(componentName)
|
||||
|
||||
initiateWidgetUpdate(getCurrentWidgetState())
|
||||
}
|
||||
|
||||
private fun initiateWidgetUpdate(state: WidgetState) {
|
||||
when (state) {
|
||||
NO_LOCATION, SCREEN_ON_CONNECTION_UNAVAILABLE -> updateErrorWidget(state)
|
||||
SCREEN_ON_CONNECTION_AVAILABLE -> updateWidget(false)
|
||||
SCREEN_OFF_CONNECTION_AVAILABLE -> updateWidget(true)
|
||||
SCREEN_OFF_CONNECTION_UNAVAILABLE -> return
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateWidget(fromStorage: Boolean) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val result = getWidgetWeather(fromStorage)
|
||||
appWidgetIds.forEach { id -> setupView(id, result) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateErrorWidget(state: WidgetState) {
|
||||
appWidgetIds.forEach { id -> setEmptyView(id, state) }
|
||||
}
|
||||
|
||||
private fun getCurrentWidgetState(): WidgetState {
|
||||
val pm = getSystemService(POWER_SERVICE) as PowerManager
|
||||
val isScreenOn = pm.isInteractive
|
||||
val locationGranted =
|
||||
checkSelfPermission(this, ACCESS_COARSE_LOCATION) == PERMISSION_GRANTED
|
||||
val internetAvailable = isInternetAvailable(this.applicationContext)
|
||||
|
||||
return getWidgetState(locationGranted, isScreenOn, internetAvailable)
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
suspend fun getWidgetWeather(storageOnly: Boolean): WidgetWeatherCollection? {
|
||||
return tryOrNullSuspended {
|
||||
if (!storageOnly) helper.fetchData()
|
||||
helper.getWidgetWeatherCollection()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setEmptyView(appWidgetId: Int, state: WidgetState) {
|
||||
val error = when (state) {
|
||||
NO_LOCATION -> "No Location Permission"
|
||||
SCREEN_ON_CONNECTION_UNAVAILABLE -> "No network available"
|
||||
else -> "No data"
|
||||
}
|
||||
|
||||
val views = createRemoteView(R.layout.weather_app_widget)
|
||||
bindErrorView(appWidgetId, views, error)
|
||||
}
|
||||
|
||||
private fun setupView(
|
||||
appWidgetId: Int,
|
||||
collection: WidgetWeatherCollection?
|
||||
) {
|
||||
val views = createRemoteView(R.layout.weather_app_widget)
|
||||
setLastUpdated(views, collection?.widgetData?.timeStamp)
|
||||
views.setInt(R.id.whole_widget_view, "setBackgroundColor", helper.getWidgetBackground())
|
||||
|
||||
if (collection != null) {
|
||||
bindView(appWidgetId, views, collection)
|
||||
} else {
|
||||
bindEmptyView(appWidgetId, views, "No weather available")
|
||||
}
|
||||
}
|
||||
|
||||
override fun bindErrorView(
|
||||
widgetId: Int,
|
||||
views: RemoteViews,
|
||||
data: Any?
|
||||
) {
|
||||
bindEmptyView(widgetId, views, data)
|
||||
}
|
||||
|
||||
override fun bindEmptyView(
|
||||
widgetId: Int,
|
||||
views: RemoteViews,
|
||||
data: Any?
|
||||
) {
|
||||
val clickUpdate = createUpdatePendingIntent(NewAppWidget::class.java, widgetId)
|
||||
|
||||
views.apply {
|
||||
setTextViewText(R.id.widget_current_location, data as String)
|
||||
setImageViewResource(R.id.widget_current_icon, R.drawable.ic_baseline_cloud_off_24)
|
||||
setImageViewResource(R.id.location_icon, 0)
|
||||
|
||||
setTextViewText(R.id.widget_main_temp, "")
|
||||
setTextViewText(R.id.widget_feel_temp, "")
|
||||
|
||||
setOnClickPendingIntent(R.id.widget_current_icon, clickUpdate)
|
||||
setOnClickPendingIntent(R.id.widget_current_location, clickUpdate)
|
||||
appWidgetManager.updateAppWidget(widgetId, this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun bindView(widgetId: Int, views: RemoteViews, data: Any?) {
|
||||
val clickUpdate = createUpdatePendingIntent(NewAppWidget::class.java, widgetId)
|
||||
val clickToMain = createClickingPendingIntent(MainActivity::class.java)
|
||||
|
||||
val collection = data as WidgetWeatherCollection
|
||||
val weather = collection.widgetData
|
||||
views.apply {
|
||||
setTextViewText(R.id.widget_main_temp, weather.currentTemp)
|
||||
setTextViewText(R.id.widget_feel_temp, "°C")
|
||||
setTextViewText(R.id.widget_current_location, weather.location)
|
||||
setImageViewResource(R.id.location_icon, R.drawable.location_flag)
|
||||
setImageView(weather.icon, this, R.id.widget_current_icon, widgetId)
|
||||
setOnClickPendingIntent(R.id.widget_current_icon, clickUpdate)
|
||||
setOnClickPendingIntent(R.id.widget_current_location, clickUpdate)
|
||||
|
||||
loadCells(widgetId, this, collection.forecast, clickToMain)
|
||||
// Instruct the widget manager to update the widget
|
||||
appWidgetManager.updateAppWidget(widgetId, views)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadCells(
|
||||
appWidgetId: Int,
|
||||
remoteViews: RemoteViews,
|
||||
weather: List<InnerWidgetCellData>,
|
||||
clickIntent: PendingIntent
|
||||
) {
|
||||
(0..4).forEach { i ->
|
||||
val containerId: Int = resources.getIdentifier("widget_item_$i", "id", packageName)
|
||||
val dayId: Int = resources.getIdentifier("widget_item_day_$i", "id", packageName)
|
||||
val imageId: Int = resources.getIdentifier("widget_item_image_$i", "id", packageName)
|
||||
val tempId: Int = resources.getIdentifier("widget_item_temp_high_$i", "id", packageName)
|
||||
|
||||
val it = weather[i]
|
||||
|
||||
remoteViews.setTextViewText(dayId, it.date)
|
||||
remoteViews.setTextViewText(tempId, it.highTemp)
|
||||
setImageView(it.icon, remoteViews, imageId, appWidgetId)
|
||||
remoteViews.setOnClickPendingIntent(containerId, clickIntent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setLastUpdated(views: RemoteViews, timeStamp: Long?) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && timeStamp != null) {
|
||||
val difference = System.currentTimeMillis().minus(timeStamp)
|
||||
|
||||
val status = if (difference > HALF_DAY) {
|
||||
"12hrs ago"
|
||||
} else {
|
||||
val date = Date(timeStamp)
|
||||
val sdf = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
sdf.format(date)
|
||||
}
|
||||
|
||||
views.setTextViewText(R.id.widget_current_status, "last updated: $status")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Unique job ID for this service.
|
||||
*/
|
||||
private const val JOB_ID = 1000
|
||||
|
||||
/**
|
||||
* Convenience method for enqueuing work in to this service.
|
||||
*/
|
||||
fun enqueueWork(context: Context, work: Intent) {
|
||||
enqueueWork(context, WidgetJobServiceIntent::class.java, JOB_ID, work)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.widget
|
||||
|
||||
enum class WidgetState {
|
||||
NO_LOCATION,
|
||||
SCREEN_ON_CONNECTION_AVAILABLE,
|
||||
SCREEN_ON_CONNECTION_UNAVAILABLE,
|
||||
SCREEN_OFF_CONNECTION_AVAILABLE,
|
||||
SCREEN_OFF_CONNECTION_UNAVAILABLE;
|
||||
|
||||
companion object {
|
||||
fun getWidgetState(
|
||||
locationAvailable: Boolean,
|
||||
screenOn: Boolean,
|
||||
connectionAvailable: Boolean
|
||||
): WidgetState {
|
||||
return if (!locationAvailable)
|
||||
NO_LOCATION
|
||||
else if (screenOn && connectionAvailable)
|
||||
SCREEN_ON_CONNECTION_AVAILABLE
|
||||
else if (screenOn && !connectionAvailable)
|
||||
SCREEN_ON_CONNECTION_UNAVAILABLE
|
||||
else if (!screenOn && connectionAvailable)
|
||||
SCREEN_OFF_CONNECTION_AVAILABLE
|
||||
else
|
||||
SCREEN_OFF_CONNECTION_UNAVAILABLE
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.appttude.h_mal.atlas_weather.ui
|
||||
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
|
||||
val tabs = setOf(R.id.nav_home, R.id.nav_world)
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.dialog
|
||||
package com.appttude.h_mal.monoWeather.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
@@ -14,7 +14,6 @@ interface DeclarationBuilder{
|
||||
|
||||
fun Context.readFromResources(@StringRes id: Int) = resources.getString(id)
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
fun buildMessage(): CharSequence? {
|
||||
val link1 = "<font color='blue'><a href=\"$link\">here</a></font>"
|
||||
val message = "$message See my privacy policy: $link1"
|
||||
@@ -1,13 +1,10 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.dialog
|
||||
package com.appttude.h_mal.monoWeather.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
|
||||
|
||||
class PermissionsDeclarationDialog(context: Context) : BaseDeclarationDialog(context) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui
|
||||
package com.appttude.h_mal.monoWeather.ui
|
||||
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
@@ -1,14 +1,12 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui
|
||||
package com.appttude.h_mal.monoWeather.ui
|
||||
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.WeatherRecyclerAdapter
|
||||
import com.appttude.h_mal.monoWeather.ui.home.adapter.WeatherRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
||||
import kotlinx.android.synthetic.main.fragment_home.*
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.details
|
||||
package com.appttude.h_mal.monoWeather.ui.details
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
@@ -1,22 +1,21 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.home
|
||||
package com.appttude.h_mal.monoWeather.ui.home
|
||||
|
||||
import android.Manifest
|
||||
import android.Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.observe
|
||||
import androidx.navigation.Navigation.findNavController
|
||||
import androidx.navigation.ui.onNavDestinationSelected
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.application.LOCATION_PERMISSION_REQUEST
|
||||
import com.appttude.h_mal.atlas_weather.model.forecast.Forecast
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.dialog.PermissionsDeclarationDialog
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.BaseFragment
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.WeatherRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||
import com.appttude.h_mal.monoWeather.dialog.PermissionsDeclarationDialog
|
||||
import com.appttude.h_mal.monoWeather.ui.BaseFragment
|
||||
import com.appttude.h_mal.monoWeather.ui.home.adapter.WeatherRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.MainViewModel
|
||||
import kotlinx.android.synthetic.main.fragment_home.*
|
||||
@@ -35,6 +34,7 @@ class HomeFragment : BaseFragment(R.layout.fragment_home) {
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
|
||||
val recyclerAdapter = WeatherRecyclerAdapter(itemClick = {
|
||||
navigateToFurtherDetails(it)
|
||||
@@ -86,4 +86,14 @@ class HomeFragment : BaseFragment(R.layout.fragment_home) {
|
||||
.actionHomeFragmentToFurtherDetailsFragment(forecast)
|
||||
navigateTo(directions)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
inflater.inflate(R.menu.menu_main, menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
val navController = findNavController(requireActivity(), R.id.container)
|
||||
return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter
|
||||
package com.appttude.h_mal.monoWeather.ui.home.adapter
|
||||
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
@@ -1,14 +1,14 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter
|
||||
package com.appttude.h_mal.monoWeather.ui.home.adapter
|
||||
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.model.forecast.Forecast
|
||||
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.EmptyViewHolder
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.forecast.ViewHolderForecast
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.forecastDaily.ViewHolderForecastDaily
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.further.ViewHolderFurtherDetails
|
||||
import com.appttude.h_mal.monoWeather.ui.EmptyViewHolder
|
||||
import com.appttude.h_mal.monoWeather.ui.home.adapter.forecast.ViewHolderForecast
|
||||
import com.appttude.h_mal.monoWeather.ui.home.adapter.forecastDaily.ViewHolderForecastDaily
|
||||
import com.appttude.h_mal.monoWeather.ui.home.adapter.further.ViewHolderFurtherDetails
|
||||
import com.appttude.h_mal.atlas_weather.utils.generateView
|
||||
|
||||
class WeatherRecyclerAdapter(
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.forecast
|
||||
package com.appttude.h_mal.monoWeather.ui.home.adapter.forecast
|
||||
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.forecast
|
||||
package com.appttude.h_mal.monoWeather.ui.home.adapter.forecast
|
||||
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.forecast
|
||||
package com.appttude.h_mal.monoWeather.ui.home.adapter.forecast
|
||||
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.forecastDaily
|
||||
package com.appttude.h_mal.monoWeather.ui.home.adapter.forecastDaily
|
||||
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.further
|
||||
package com.appttude.h_mal.monoWeather.ui.home.adapter.further
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.further
|
||||
package com.appttude.h_mal.monoWeather.ui.home.adapter.further
|
||||
|
||||
import android.view.View
|
||||
import android.widget.GridView
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.appttude.h_mal.monoWeather.ui.settings
|
||||
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.widget.NewAppWidget
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat() {
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.prefs_screen, rootKey)
|
||||
|
||||
//listener on changed sort order preference:
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
prefs.registerOnSharedPreferenceChangeListener { _, key ->
|
||||
if (key == "temp_units") {
|
||||
val intent = Intent(requireContext(), NewAppWidget::class.java)
|
||||
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
val ids = AppWidgetManager.getInstance(requireContext())
|
||||
.getAppWidgetIds(ComponentName(requireContext(), NewAppWidget::class.java))
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
|
||||
requireContext().sendBroadcast(intent)
|
||||
}
|
||||
|
||||
if (key == "widget_black_background") {
|
||||
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE)
|
||||
val widgetManager = AppWidgetManager.getInstance(requireContext())
|
||||
val ids =
|
||||
widgetManager.getAppWidgetIds(ComponentName(requireContext(), NewAppWidget::class.java))
|
||||
AppWidgetManager.getInstance(requireContext())
|
||||
.notifyAppWidgetViewDataChanged(ids, R.id.whole_widget_view)
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
|
||||
requireContext().sendBroadcast(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.widget
|
||||
package com.appttude.h_mal.monoWeather.ui.widget
|
||||
|
||||
import android.Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
import android.app.Activity
|
||||
@@ -11,7 +11,7 @@ import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat.checkSelfPermission
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.dialog.DeclarationBuilder
|
||||
import com.appttude.h_mal.monoWeather.dialog.DeclarationBuilder
|
||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||
import kotlinx.android.synthetic.monoWeather.permissions_declaration_dialog.*
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.world
|
||||
package com.appttude.h_mal.monoWeather.ui.world
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.observe
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.BaseFragment
|
||||
import com.appttude.h_mal.monoWeather.ui.BaseFragment
|
||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||
import com.appttude.h_mal.atlas_weather.utils.goBack
|
||||
import com.appttude.h_mal.atlas_weather.utils.hideKeyboard
|
||||
@@ -1,15 +1,13 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.world
|
||||
package com.appttude.h_mal.monoWeather.ui.world
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.observe
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.BaseFragment
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.world.WorldFragmentDirections.actionWorldFragmentToWorldItemFragment
|
||||
import com.appttude.h_mal.monoWeather.ui.BaseFragment
|
||||
import com.appttude.h_mal.monoWeather.ui.world.WorldFragmentDirections.actionWorldFragmentToWorldItemFragment
|
||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.world
|
||||
package com.appttude.h_mal.monoWeather.ui.world
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -7,7 +7,7 @@ import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.EmptyViewHolder
|
||||
import com.appttude.h_mal.monoWeather.ui.EmptyViewHolder
|
||||
import com.appttude.h_mal.atlas_weather.utils.generateView
|
||||
import com.appttude.h_mal.atlas_weather.utils.loadImage
|
||||
|
||||
@@ -93,13 +93,9 @@ class WorldRecyclerAdapter(
|
||||
avgTempTV.text = data?.forecast?.get(0)?.mainTemp
|
||||
tempUnit.text = itemView.context.getString(R.string.degrees)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract class BaseViewHolder<T : Any>(cellView: View) : RecyclerView.ViewHolder(cellView) {
|
||||
|
||||
abstract fun bindData(data : T?)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -7,68 +7,57 @@
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_home"
|
||||
android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.home.HomeFragment"
|
||||
android:name="com.appttude.h_mal.monoWeather.ui.home.HomeFragment"
|
||||
android:label="Home"
|
||||
tools:layout="@layout/fragment_home">
|
||||
<action
|
||||
android:id="@+id/action_homeFragment_to_furtherDetailsFragment"
|
||||
app:destination="@id/furtherDetailsFragment"
|
||||
app:enterAnim="@anim/fragment_open_enter"
|
||||
app:exitAnim="@anim/fragment_open_exit"
|
||||
app:popEnterAnim="@anim/fragment_open_enter"
|
||||
app:popExitAnim="@anim/fragment_open_exit" />
|
||||
app:destination="@id/furtherDetailsFragment"/>
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/furtherDetailsFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.details.FurtherInfoFragment"
|
||||
android:name="com.appttude.h_mal.monoWeather.ui.details.FurtherInfoFragment"
|
||||
android:label="Further Details">
|
||||
<argument
|
||||
android:name="forecast"
|
||||
app:argType="com.appttude.h_mal.atlas_weather.model.forecast.Forecast" />
|
||||
app:argType="com.appttude.h_mal.atlas_weather.model.forecast.Forecast"
|
||||
app:nullable="true"/>
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_world"
|
||||
android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.world.WorldFragment"
|
||||
android:name="com.appttude.h_mal.monoWeather.ui.world.WorldFragment"
|
||||
android:label="World"
|
||||
tools:layout="@layout/fragment__two">
|
||||
<action
|
||||
android:id="@+id/action_worldFragment_to_addLocationFragment"
|
||||
app:destination="@id/addLocationFragment"
|
||||
app:enterAnim="@anim/fragment_open_enter"
|
||||
app:exitAnim="@anim/fragment_open_exit"
|
||||
app:popEnterAnim="@anim/fragment_open_enter"
|
||||
app:popExitAnim="@anim/fragment_open_exit" />
|
||||
app:destination="@id/addLocationFragment"/>
|
||||
<action
|
||||
android:id="@+id/action_worldFragment_to_worldItemFragment"
|
||||
app:destination="@id/worldItemFragment"
|
||||
app:enterAnim="@anim/fragment_open_enter"
|
||||
app:exitAnim="@anim/fragment_open_exit"
|
||||
app:popEnterAnim="@anim/fragment_open_enter"
|
||||
app:popExitAnim="@anim/fragment_open_exit" />
|
||||
app:destination="@id/worldItemFragment"/>
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/addLocationFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.world.AddLocationFragment"
|
||||
android:name="com.appttude.h_mal.monoWeather.ui.world.AddLocationFragment"
|
||||
android:label="Add Weather Location"
|
||||
tools:layout="@layout/activity_add_forecast" />
|
||||
<fragment
|
||||
android:id="@+id/worldItemFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.WorldItemFragment"
|
||||
android:name="com.appttude.h_mal.monoWeather.ui.WorldItemFragment"
|
||||
android:label="Overview"
|
||||
tools:layout="@layout/fragment_home">
|
||||
<action
|
||||
android:id="@+id/action_worldItemFragment_to_furtherDetailsFragment"
|
||||
app:destination="@id/furtherDetailsFragment"
|
||||
app:enterAnim="@anim/fragment_open_enter"
|
||||
app:exitAnim="@anim/fragment_open_exit"
|
||||
app:popEnterAnim="@anim/fragment_open_enter"
|
||||
app:popExitAnim="@anim/fragment_open_exit" />
|
||||
app:destination="@id/furtherDetailsFragment" />
|
||||
<argument
|
||||
android:name="locationName"
|
||||
app:argType="string"
|
||||
app:nullable="true" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/settings_fragment"
|
||||
android:name="com.appttude.h_mal.monoWeather.ui.settings.SettingsFragment"
|
||||
android:label="SettingsFragment" />
|
||||
|
||||
</navigation>
|
||||
12
app/src/monoWeather/res/values/arrays.xml
Normal file
12
app/src/monoWeather/res/values/arrays.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<resources>
|
||||
<!-- Reply Preference -->
|
||||
<string-array name="reply_entries">
|
||||
<item>Reply</item>
|
||||
<item>Reply to all</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="reply_values">
|
||||
<item>reply</item>
|
||||
<item>reply_all</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -10,4 +10,18 @@
|
||||
<string name="title_world">World</string>
|
||||
|
||||
<string name="widget_declaration">When using the app widget with app will require the use of background location services. Just to confirm the location data is used just to provide the end user with widget data. The use of background location permission is to update the widget at 30 minute intervals. </string>
|
||||
<!-- Preference Titles -->
|
||||
<string name="messages_header">Messages</string>
|
||||
<string name="sync_header">Sync</string>
|
||||
|
||||
<!-- Messages Preferences -->
|
||||
<string name="signature_title">Your signature</string>
|
||||
<string name="reply_title">Default reply action</string>
|
||||
|
||||
<!-- Sync Preferences -->
|
||||
<string name="sync_title">Sync email periodically</string>
|
||||
<string name="attachment_title">Download incoming attachments</string>
|
||||
<string name="attachment_summary_on">Automatically download attachments for incoming emails
|
||||
</string>
|
||||
<string name="attachment_summary_off">Only download attachments when manually requested</string>
|
||||
</resources>
|
||||
|
||||
@@ -66,12 +66,4 @@
|
||||
<item name="android:textSize">32sp</item>
|
||||
</style>
|
||||
|
||||
<style name="icon_style__further_deatils">
|
||||
<item name="android:layout_width">48dp</item>
|
||||
<item name="android:layout_height">48dp</item>
|
||||
<item name="android:adjustViewBounds">true</item>
|
||||
<item name="android:layout_gravity">center</item>
|
||||
<item name="android:tint">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
15
app/src/monoWeather/res/xml/new_app_widget_info.xml
Normal file
15
app/src/monoWeather/res/xml/new_app_widget_info.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:configure="com.appttude.h_mal.monoWeather.ui.widget.WidgetLocationPermissionActivity"
|
||||
android:initialKeyguardLayout="@layout/weather_app_widget"
|
||||
android:initialLayout="@layout/weather_app_widget"
|
||||
android:minHeight="110.0dp"
|
||||
android:minWidth="320.0dp"
|
||||
android:minResizeWidth="320.0dp"
|
||||
android:minResizeHeight="110.0dp"
|
||||
android:previewImage="@drawable/widget_screenshot"
|
||||
android:updatePeriodMillis="1800000"
|
||||
android:resizeMode="vertical"
|
||||
android:widgetCategory="home_screen">
|
||||
|
||||
</appwidget-provider>
|
||||
35
app/src/monoWeather/res/xml/root_preferences.xml
Normal file
35
app/src/monoWeather/res/xml/root_preferences.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<PreferenceCategory app:title="@string/messages_header">
|
||||
|
||||
<EditTextPreference
|
||||
app:key="signature"
|
||||
app:title="@string/signature_title"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
|
||||
<ListPreference
|
||||
app:defaultValue="reply"
|
||||
app:entries="@array/reply_entries"
|
||||
app:entryValues="@array/reply_values"
|
||||
app:key="reply"
|
||||
app:title="@string/reply_title"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory app:title="@string/sync_header">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:key="sync"
|
||||
app:title="@string/sync_title" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:dependency="sync"
|
||||
app:key="attachment"
|
||||
app:summaryOff="@string/attachment_summary_off"
|
||||
app:summaryOn="@string/attachment_summary_on"
|
||||
app:title="@string/attachment_title" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
Reference in New Issue
Block a user