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:
@@ -1,8 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.appttude.h_mal.atlas_weather"
|
||||
tools:node="merge">
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<application
|
||||
android:name="com.appttude.h_mal.atlas_weather.application.AppClass"
|
||||
@@ -14,7 +12,7 @@
|
||||
android:theme="@style/AppTheme"
|
||||
tools:node="merge">
|
||||
|
||||
<activity android:name=".atlasWeather.ui.MainActivity"
|
||||
<activity android:name=".ui.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
@@ -26,18 +24,12 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".atlasWeather.ui.settings.UnitSettingsActivity"
|
||||
android:label="Settings"
|
||||
android:exported="true"/>
|
||||
|
||||
<receiver
|
||||
android:name=".atlasWeather.notification.NotificationReceiver"
|
||||
android:name=".notification.NotificationReceiver"
|
||||
android:parentActivityName=".MainActivity"
|
||||
android:exported="true"/>
|
||||
|
||||
<receiver android:name=".atlasWeather.widget.NewAppWidget"
|
||||
<receiver android:name=".widget.NewAppWidget"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
@@ -49,11 +41,6 @@
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/new_app_widget_info" />
|
||||
</receiver>
|
||||
|
||||
|
||||
<service
|
||||
android:name=".atlasWeather.widget.WidgetRemoteViewsService"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.pm.PackageManager
|
||||
import android.view.View
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
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 kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
abstract class BaseFragment: Fragment(){
|
||||
|
||||
// toggle visibility of progress spinner while async operations are taking place
|
||||
fun progressBarStateObserver(progressBar: View) = Observer<Event<Boolean>> {
|
||||
when(it.getContentIfNotHandled()){
|
||||
true -> {
|
||||
progressBar.show()
|
||||
}
|
||||
false -> {
|
||||
progressBar.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// display a toast when operation fails
|
||||
fun errorObserver() = Observer<Event<String>> {
|
||||
it.getContentIfNotHandled()?.let { message ->
|
||||
displayToast(message)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
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.atlasWeather.ui.settings.UnitSettingsActivity
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import kotlinx.android.synthetic.atlasWeather.activity_main.*
|
||||
|
||||
|
||||
class MainActivity : BaseActivity(){
|
||||
|
||||
lateinit var navHost: NavHostFragment
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.home
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.observe
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
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.atlasWeather.ui.BaseFragment
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.adapter.WeatherRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.ApplicationViewModelFactory
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.MainViewModel
|
||||
import kotlinx.android.synthetic.main.fragment_home.*
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.android.x.kodein
|
||||
|
||||
import org.kodein.di.generic.instance
|
||||
|
||||
|
||||
/**
|
||||
* A simple [Fragment] subclass.
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
class HomeFragment : BaseFragment(), KodeinAware {
|
||||
override val kodein by kodein()
|
||||
private val factory by instance<ApplicationViewModelFactory>()
|
||||
|
||||
private val viewModel by activityViewModels<MainViewModel> { factory }
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.fragment_home, container, false)
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val recyclerAdapter = WeatherRecyclerAdapter {
|
||||
val directions =
|
||||
HomeFragmentDirections.actionHomeFragmentToFurtherDetailsFragment(it)
|
||||
navigateTo(directions)
|
||||
}
|
||||
|
||||
forecast_listview.apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
adapter = recyclerAdapter
|
||||
}
|
||||
|
||||
getPermissionResult(Manifest.permission.ACCESS_FINE_LOCATION, LOCATION_PERMISSION_REQUEST){
|
||||
viewModel.fetchData()
|
||||
}
|
||||
|
||||
swipe_refresh.apply {
|
||||
setOnRefreshListener {
|
||||
getPermissionResult(Manifest.permission.ACCESS_FINE_LOCATION, LOCATION_PERMISSION_REQUEST){
|
||||
viewModel.fetchData()
|
||||
}
|
||||
isRefreshing = true
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.weatherLiveData.observe(viewLifecycleOwner) {
|
||||
recyclerAdapter.addCurrent(it)
|
||||
}
|
||||
|
||||
viewModel.operationState.observe(viewLifecycleOwner, progressBarStateObserver(progressBar))
|
||||
viewModel.operationError.observe(viewLifecycleOwner, errorObserver())
|
||||
|
||||
viewModel.operationState.observe(viewLifecycleOwner){
|
||||
swipe_refresh.isRefreshing = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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) {
|
||||
viewModel.fetchData()
|
||||
displayToast("Permission granted")
|
||||
} else {
|
||||
displayToast("Permission denied")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.settings
|
||||
|
||||
import android.app.AlarmManager
|
||||
import android.app.PendingIntent
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
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.atlasWeather.notification.NotificationReceiver
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.widget.NewAppWidget
|
||||
import java.util.*
|
||||
|
||||
|
||||
class UnitSettingsActivity : PreferenceActivity() {
|
||||
private var prefListener: OnSharedPreferenceChangeListener? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
PreferenceManager.setDefaultValues(this, R.xml.prefs, 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 == "notif_boolean") {
|
||||
setupNotificationBroadcaster(baseContext)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
fun setupNotificationBroadcaster(context: Context) {
|
||||
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
val notificationIntent = Intent(context, NotificationReceiver::class.java)
|
||||
val broadcast = PendingIntent.getBroadcast(context, 100, notificationIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
val cal: Calendar = Calendar.getInstance()
|
||||
cal.set(Calendar.HOUR_OF_DAY, 6)
|
||||
cal.set(Calendar.MINUTE, 8)
|
||||
cal.set(Calendar.SECOND, 5)
|
||||
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.timeInMillis, AlarmManager.INTERVAL_DAY, broadcast)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
super.onBackPressed()
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
|
||||
// Log.i(TAG, "onSharedPreferenceChanged: " + s);
|
||||
// if (s == "temp_units"){
|
||||
// Intent intent = new Intent(getBaseContext(), NewAppWidget.class);
|
||||
// intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
|
||||
//
|
||||
// int[] ids = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), NewAppWidget.class));
|
||||
// intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
|
||||
// sendBroadcast(intent);
|
||||
// }
|
||||
// }
|
||||
class MyPreferenceFragment : PreferenceFragment() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
addPreferencesFromResource(R.xml.prefs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.widget
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.app.TaskStackBuilder
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.widget.RemoteViews
|
||||
import androidx.annotation.LayoutRes
|
||||
|
||||
abstract class BaseWidgetClass : AppWidgetProvider(){
|
||||
|
||||
fun createRemoteView(context: Context, @LayoutRes id: Int): RemoteViews {
|
||||
return RemoteViews(context.packageName, id)
|
||||
}
|
||||
|
||||
fun AppWidgetProvider.createUpdatePendingIntent(context: Context, appWidgetId: Int): PendingIntent? {
|
||||
val seconds = (System.currentTimeMillis() / 1000L).toInt()
|
||||
val intentUpdate = Intent(context, this::class.java)
|
||||
intentUpdate.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
val idArray = intArrayOf(appWidgetId)
|
||||
intentUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, idArray)
|
||||
|
||||
return PendingIntent.getBroadcast(
|
||||
context, seconds, intentUpdate,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
|
||||
fun <T: Activity> createClickingPendingIntent(context: Context, activityClass: Class<T>): PendingIntent {
|
||||
val clickIntentTemplate = Intent(context, activityClass)
|
||||
|
||||
return TaskStackBuilder.create(context)
|
||||
.addNextIntentWithParentStack(clickIntentTemplate)
|
||||
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.widget
|
||||
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.widget.RemoteViews
|
||||
import android.widget.RemoteViewsService.RemoteViewsFactory
|
||||
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.InnerWidgetData
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.LateInitKodein
|
||||
import org.kodein.di.generic.instance
|
||||
|
||||
|
||||
class MyWidgetRemoteViewsFactory(
|
||||
private val context: Context,
|
||||
val intent: Intent
|
||||
) : RemoteViewsFactory{
|
||||
private val TAG = "MyWidgetRemoteViewsFactory"
|
||||
|
||||
private val kodein = LateInitKodein()
|
||||
private val helper : ServicesHelper by kodein.instance()
|
||||
|
||||
private var appWidgetId: Int? = 0
|
||||
private var list: List<InnerWidgetData>? = null
|
||||
|
||||
init {
|
||||
appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
AppWidgetManager.INVALID_APPWIDGET_ID)
|
||||
kodein.baseKodein = (context.applicationContext as KodeinAware).kodein
|
||||
|
||||
}
|
||||
|
||||
override fun onCreate() {}
|
||||
override fun onDataSetChanged() {
|
||||
runBlocking {
|
||||
list = helper.getWidgetInnerWeather()
|
||||
}
|
||||
}
|
||||
override fun onDestroy() {}
|
||||
|
||||
override fun getCount(): Int = list?.size ?: 5
|
||||
|
||||
override fun getViewAt(i: Int): RemoteViews {
|
||||
val rv = RemoteViews(context.packageName, R.layout.widget_item)
|
||||
|
||||
if (list.isNullOrEmpty()) return rv
|
||||
|
||||
|
||||
list?.get(i)?.let {
|
||||
rv.setTextViewText(R.id.widget_item_day, it.date)
|
||||
rv.setImageViewBitmap(R.id.widget_item_image, it.icon)
|
||||
rv.setTextViewText(R.id.widget_item_temp_high, it.highTemp)
|
||||
rv.setOnClickFillInIntent(R.id.widget_item_layout, intent)
|
||||
}
|
||||
|
||||
return rv
|
||||
}
|
||||
|
||||
override fun getLoadingView(): RemoteViews {
|
||||
return RemoteViews(context.packageName, R.layout.widget_item_loading)
|
||||
}
|
||||
|
||||
override fun getViewTypeCount(): Int = 1
|
||||
|
||||
|
||||
override fun getItemId(i: Int): Long = i.toLong()
|
||||
|
||||
|
||||
override fun hasStableIds(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.widget
|
||||
|
||||
import android.Manifest
|
||||
import android.app.PendingIntent
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.app.ActivityCompat
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.MainActivity
|
||||
import com.appttude.h_mal.atlas_weather.helper.ServicesHelper
|
||||
import com.appttude.h_mal.atlas_weather.model.widget.WidgetData
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.LateInitKodein
|
||||
import org.kodein.di.generic.instance
|
||||
|
||||
/**
|
||||
* Implementation of App Widget functionality.
|
||||
*/
|
||||
private val TAG = NewAppWidget::class.java.simpleName
|
||||
class NewAppWidget : BaseWidgetClass() {
|
||||
|
||||
private val kodein = LateInitKodein()
|
||||
private val helper : ServicesHelper by kodein.instance()
|
||||
|
||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||
kodein.baseKodein = (context.applicationContext as KodeinAware).kodein
|
||||
// There may be multiple widgets active, so update all of them
|
||||
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
return
|
||||
}
|
||||
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val results = helper.fetchData()
|
||||
if (results) return@launch
|
||||
val weatherWidgetCurrent = helper.getWidgetWeather()
|
||||
|
||||
withContext(Dispatchers.Main){
|
||||
for (appWidgetId in appWidgetIds) {
|
||||
val updatePendingIntent = createUpdatePendingIntent(context, appWidgetId)
|
||||
val views = createRemoteView(context, R.layout.new_app_widget)
|
||||
bindView(context, appWidgetId, views, updatePendingIntent, weatherWidgetCurrent)
|
||||
}
|
||||
super.onUpdate(context, appWidgetManager, appWidgetIds)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEnabled(context: Context) {
|
||||
try {
|
||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
val thisAppWidget = ComponentName(context.packageName, NewAppWidget::class.java.name)
|
||||
val appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget)
|
||||
onUpdate(context, appWidgetManager, appWidgetIds)
|
||||
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_listview)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "onEnabled: ", e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDisabled(context: Context) {
|
||||
// Enter relevant functionality for when the last widget is disabled
|
||||
}
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action ==
|
||||
AppWidgetManager.ACTION_APPWIDGET_UPDATE) {
|
||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
val thisAppWidget = ComponentName(context.packageName, NewAppWidget::class.java.name)
|
||||
val appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget)
|
||||
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_listview)
|
||||
}
|
||||
super.onReceive(context, intent)
|
||||
}
|
||||
|
||||
private fun createForecastListIntent(
|
||||
context: Context,
|
||||
appWidgetId: Int
|
||||
): Intent {
|
||||
return Intent(context, WidgetRemoteViewsService::class.java).apply {
|
||||
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
|
||||
data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME))
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindView(
|
||||
context: Context,
|
||||
appWidgetId: Int,
|
||||
views: RemoteViews,
|
||||
updatePendingIntent: PendingIntent?,
|
||||
weather: WidgetData?){
|
||||
|
||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
|
||||
views.setInt(R.id.whole_widget_view, "setBackgroundColor", helper.getWidgetBackground())
|
||||
|
||||
weather?.let {
|
||||
|
||||
val intent = createForecastListIntent(
|
||||
context,
|
||||
appWidgetId
|
||||
)
|
||||
|
||||
views.setRemoteAdapter(R.id.widget_listview, intent)
|
||||
views.setTextViewText(R.id.widget_main_temp, it.currentTemp)
|
||||
views.setTextViewText(R.id.widget_feel_temp, "°C")
|
||||
views.setTextViewText(R.id.widget_current_location, it.location)
|
||||
views.setImageViewResource(R.id.location_icon, R.drawable.location_flag)
|
||||
// views.setImageViewBitmap(R.id.widget_current_icon, it.icon)
|
||||
|
||||
val clickPendingIntentTemplate = createClickingPendingIntent(context, MainActivity::class.java)
|
||||
views.setPendingIntentTemplate(R.id.widget_listview, clickPendingIntentTemplate)
|
||||
|
||||
views.setOnClickPendingIntent(R.id.widget_current_icon, updatePendingIntent)
|
||||
views.setOnClickPendingIntent(R.id.widget_current_location, updatePendingIntent)
|
||||
|
||||
// Instruct the widget manager to update the widget
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview)
|
||||
return
|
||||
}
|
||||
|
||||
Log.i(TAG, "onPostExecute: weather is empty")
|
||||
views.setTextViewText(R.id.widget_current_location, "Refresh")
|
||||
views.setImageViewResource(R.id.widget_current_icon, R.drawable.widget_error_icon)
|
||||
views.setImageViewResource(R.id.location_icon, R.drawable.refreshing)
|
||||
views.setOnClickPendingIntent(R.id.widget_current_icon, updatePendingIntent)
|
||||
views.setOnClickPendingIntent(R.id.widget_current_location, updatePendingIntent)
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.widget
|
||||
|
||||
import android.content.Intent
|
||||
import android.widget.RemoteViewsService
|
||||
|
||||
class WidgetRemoteViewsService : RemoteViewsService() {
|
||||
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
|
||||
return MyWidgetRemoteViewsFactory(applicationContext, intent)
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.widget
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.app.TaskStackBuilder
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
|
||||
fun <T: Activity> createClickingPendingIntent(context: Context, activityClass: Class<T>): PendingIntent {
|
||||
val clickIntentTemplate = Intent(context, activityClass)
|
||||
|
||||
return TaskStackBuilder.create(context)
|
||||
.addNextIntentWithParentStack(clickIntentTemplate)
|
||||
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.notification
|
||||
package com.appttude.h_mal.atlas_weather.notification
|
||||
|
||||
import android.graphics.Bitmap
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.notification
|
||||
package com.appttude.h_mal.atlas_weather.notification
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Notification
|
||||
@@ -12,13 +12,10 @@ import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import androidx.core.app.ActivityCompat
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.MainActivity
|
||||
import com.appttude.h_mal.atlas_weather.ui.MainActivity
|
||||
import com.appttude.h_mal.atlas_weather.helper.ServicesHelper
|
||||
import com.appttude.h_mal.atlas_weather.model.weather.FullWeather
|
||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||
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
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui
|
||||
package com.appttude.h_mal.atlas_weather.ui
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
||||
@@ -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.atlasWeather.ui
|
||||
package com.appttude.h_mal.atlas_weather.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
@@ -8,7 +8,7 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
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.atlasWeather.ui.home.adapter.WeatherRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.ui.home.adapter.WeatherRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||
import kotlinx.android.synthetic.main.fragment_home.*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.details
|
||||
package com.appttude.h_mal.atlas_weather.ui.details
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.appttude.h_mal.atlas_weather.ui.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.os.Build
|
||||
import android.text.Html
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.content.ContextCompat
|
||||
|
||||
interface DeclarationBuilder{
|
||||
val link: String
|
||||
val message: String
|
||||
|
||||
fun Context.readFromResources(@StringRes id: Int) = resources.getString(id)
|
||||
|
||||
fun buildMessage(): CharSequence? {
|
||||
val link1 = "<font color='blue'><a href=\"$link\">here</a></font>"
|
||||
val message = "$message See my privacy policy: $link1"
|
||||
return Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.appttude.h_mal.atlas_weather.ui.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
|
||||
|
||||
class PermissionsDeclarationDialog(context: Context) : BaseDeclarationDialog(context) {
|
||||
|
||||
override val link: String = "https://sites.google.com/view/hmaldev/home/monochrome"
|
||||
override val message: String = "Hi, thank you for downloading my app. Google play isn't letting me upload my app to the Playstore until I have a privacy declaration :(. My app is basically used to demonstrate my code=ing to potential employers and others. I do NOT store or process any information. The location permission in the app is there just to provide the end user with weather data."
|
||||
}
|
||||
|
||||
abstract class BaseDeclarationDialog(val context: Context): DeclarationBuilder {
|
||||
abstract override val link: String
|
||||
abstract override val message: String
|
||||
|
||||
lateinit var dialog: AlertDialog
|
||||
|
||||
fun showDialog(agreeCallback: () -> Unit = { }, disagreeCallback: () -> Unit = { }) {
|
||||
val myMessage = buildMessage()
|
||||
|
||||
val builder = AlertDialog.Builder(context)
|
||||
.setPositiveButton("agree") { _, _ ->
|
||||
agreeCallback()
|
||||
}
|
||||
.setNegativeButton("disagree") { _, _ ->
|
||||
disagreeCallback()
|
||||
}
|
||||
.setMessage(myMessage)
|
||||
.setCancelable(false)
|
||||
|
||||
dialog = builder.create()
|
||||
dialog.show()
|
||||
|
||||
// Make the textview clickable. Must be called after show()
|
||||
val msgTxt = dialog.findViewById<View>(android.R.id.message) as TextView?
|
||||
msgTxt?.movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
|
||||
fun dismiss() = dialog.dismiss()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.appttude.h_mal.atlas_weather.ui.home
|
||||
|
||||
import android.Manifest
|
||||
import android.Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.Navigation.findNavController
|
||||
import androidx.navigation.ui.onNavDestinationSelected
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
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.ui.dialog.PermissionsDeclarationDialog
|
||||
import com.appttude.h_mal.atlas_weather.ui.home.adapter.WeatherRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.ApplicationViewModelFactory
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.MainViewModel
|
||||
import com.appttude.h_mal.monoWeather.ui.BaseFragment
|
||||
import kotlinx.android.synthetic.main.fragment_home.*
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.android.x.kodein
|
||||
|
||||
import org.kodein.di.generic.instance
|
||||
|
||||
|
||||
/**
|
||||
* A simple [Fragment] subclass.
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
class HomeFragment : BaseFragment(R.layout.fragment_home) {
|
||||
private val viewModel by getFragmentViewModel<MainViewModel>()
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
|
||||
val recyclerAdapter = WeatherRecyclerAdapter(itemClick = {
|
||||
navigateToFurtherDetails(it)
|
||||
})
|
||||
|
||||
forecast_listview.apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
adapter = recyclerAdapter
|
||||
}
|
||||
|
||||
swipe_refresh.apply {
|
||||
setOnRefreshListener {
|
||||
getPermissionResult(ACCESS_COARSE_LOCATION, LOCATION_PERMISSION_REQUEST) {
|
||||
viewModel.fetchData()
|
||||
isRefreshing = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.weatherLiveData.observe(viewLifecycleOwner) {
|
||||
recyclerAdapter.addCurrent(it)
|
||||
}
|
||||
|
||||
viewModel.operationState.observe(viewLifecycleOwner, progressBarStateObserver(progressBar))
|
||||
viewModel.operationError.observe(viewLifecycleOwner, errorObserver())
|
||||
viewModel.operationRefresh.observe(viewLifecycleOwner) { it ->
|
||||
it.getContentIfNotHandled()?.let {
|
||||
swipe_refresh.isRefreshing = false
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.operationState.observe(viewLifecycleOwner) {
|
||||
swipe_refresh.isRefreshing = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
getPermissionResult(ACCESS_COARSE_LOCATION, LOCATION_PERMISSION_REQUEST) {
|
||||
viewModel.fetchData()
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun permissionsGranted() {
|
||||
viewModel.fetchData()
|
||||
}
|
||||
|
||||
private fun navigateToFurtherDetails(forecast: Forecast) {
|
||||
val directions = HomeFragmentDirections
|
||||
.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.atlasWeather.ui.home.adapter
|
||||
package com.appttude.h_mal.atlas_weather.ui.home.adapter
|
||||
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.adapter
|
||||
package com.appttude.h_mal.atlas_weather.ui.home.adapter
|
||||
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
@@ -17,7 +17,7 @@ class ViewHolderCurrent(listItemView: View) : RecyclerView.ViewHolder(listItemVi
|
||||
var tempUnit: TextView = listItemView.findViewById(R.id.temp_unit_4)
|
||||
|
||||
fun bindData(weather: WeatherDisplay?){
|
||||
locationTV.text = weather?.location
|
||||
locationTV.text = weather?.displayName
|
||||
conditionTV.text = weather?.description
|
||||
weatherIV.loadImage(weather?.iconURL)
|
||||
avgTempTV.text = weather?.averageTemp?.toInt().toString()
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.adapter
|
||||
package com.appttude.h_mal.atlas_weather.ui.home.adapter
|
||||
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.adapter
|
||||
package com.appttude.h_mal.atlas_weather.ui.home.adapter
|
||||
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.adapter
|
||||
package com.appttude.h_mal.atlas_weather.ui.home.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.View
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.appttude.h_mal.atlas_weather.ui.settings
|
||||
|
||||
import android.app.AlarmManager
|
||||
import android.app.PendingIntent
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
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.notification.NotificationReceiver
|
||||
import com.appttude.h_mal.atlas_weather.widget.NewAppWidget
|
||||
import java.util.Calendar
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat() {
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.prefs, 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 == "notif_boolean") {
|
||||
setupNotificationBroadcaster(requireContext())
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setupNotificationBroadcaster(context: Context) {
|
||||
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
val notificationIntent = Intent(context, NotificationReceiver::class.java)
|
||||
val broadcast = PendingIntent.getBroadcast(context, 100, notificationIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
val cal: Calendar = Calendar.getInstance()
|
||||
cal.set(Calendar.HOUR_OF_DAY, 6)
|
||||
cal.set(Calendar.MINUTE, 8)
|
||||
cal.set(Calendar.SECOND, 5)
|
||||
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.timeInMillis, AlarmManager.INTERVAL_DAY, broadcast)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.world
|
||||
package com.appttude.h_mal.atlas_weather.ui.world
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
@@ -7,28 +7,20 @@ import android.view.ViewGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.observe
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.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.viewmodel.ApplicationViewModelFactory
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
||||
import com.appttude.h_mal.monoWeather.ui.BaseFragment
|
||||
import kotlinx.android.synthetic.main.activity_add_forecast.*
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.android.x.kodein
|
||||
import org.kodein.di.generic.instance
|
||||
|
||||
|
||||
class AddLocationFragment : BaseFragment(), KodeinAware {
|
||||
override val kodein by kodein()
|
||||
private val factory by instance<ApplicationViewModelFactory>()
|
||||
class AddLocationFragment : BaseFragment(R.layout.activity_add_forecast) {
|
||||
|
||||
private val viewModel by viewModels<WorldViewModel> { factory }
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.activity_add_forecast, container, false)
|
||||
}
|
||||
private val viewModel by getFragmentViewModel<WorldViewModel>()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.world
|
||||
package com.appttude.h_mal.atlas_weather.ui.world
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
@@ -9,12 +9,10 @@ import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.observe
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.world.WorldRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.BaseFragment
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.world.WorldFragmentDirections
|
||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.ApplicationViewModelFactory
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
||||
import com.appttude.h_mal.monoWeather.ui.BaseFragment
|
||||
import kotlinx.android.synthetic.main.fragment_add_location.*
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.android.x.kodein
|
||||
@@ -25,17 +23,8 @@ import org.kodein.di.generic.instance
|
||||
* A simple [Fragment] subclass.
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
class WorldFragment : BaseFragment(), KodeinAware {
|
||||
override val kodein by kodein()
|
||||
private val factory by instance<ApplicationViewModelFactory>()
|
||||
|
||||
val viewModel by viewModels<WorldViewModel> { factory }
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.fragment_add_location, container, false)
|
||||
}
|
||||
class WorldFragment : BaseFragment(R.layout.fragment_add_location) {
|
||||
val viewModel by getFragmentViewModel<WorldViewModel>()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.world
|
||||
package com.appttude.h_mal.atlas_weather.ui.world
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
10
app/src/atlasWeather/res/drawable/gradient.xml
Normal file
10
app/src/atlasWeather/res/drawable/gradient.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<gradient
|
||||
android:startColor="@color/colour_two"
|
||||
android:centerColor="@color/colour_three"
|
||||
android:endColor="@color/colour_four"
|
||||
android:type="linear"
|
||||
android:angle="45"/>
|
||||
</shape>
|
||||
BIN
app/src/atlasWeather/res/font/archeologicaps.ttf
Normal file
BIN
app/src/atlasWeather/res/font/archeologicaps.ttf
Normal file
Binary file not shown.
@@ -76,7 +76,7 @@
|
||||
android:id="@+id/icon_main_4"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
tools:src="@drawable/day_305" />
|
||||
tools:srcCompat="@drawable/water_drop" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
|
||||
@@ -48,7 +48,9 @@
|
||||
android:id="@+id/list_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
tools:src="@drawable/day_305" />
|
||||
android:adjustViewBounds="true"
|
||||
tools:layout_width="32dp"
|
||||
tools:srcCompat="@drawable/water_drop" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
|
||||
@@ -8,21 +8,17 @@
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_home"
|
||||
android:name="com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.HomeFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.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.atlasWeather.ui.details.FurtherInfoFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.ui.details.FurtherInfoFragment"
|
||||
android:label="Further Details">
|
||||
<argument
|
||||
android:name="forecast"
|
||||
@@ -31,44 +27,36 @@
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_world"
|
||||
android:name="com.appttude.h_mal.atlas_weather.atlasWeather.ui.world.WorldFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.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.atlasWeather.ui.world.AddLocationFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.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.atlasWeather.ui.WorldItemFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.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="weatherDisplay"
|
||||
app:argType="com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/settings_fragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.ui.settings.SettingsFragment"
|
||||
android:label="SettingsFragment" />
|
||||
</navigation>
|
||||
12
app/src/atlasWeather/res/values/colors.xml
Normal file
12
app/src/atlasWeather/res/values/colors.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
|
||||
<color name="colour_one">#E8D0DD</color>
|
||||
<color name="colour_two">#5F8E7B</color>
|
||||
<color name="colour_three">#B3C0CA</color>
|
||||
<color name="colour_four">#8C98AD</color>
|
||||
<color name="colour_five">#2E3532</color>
|
||||
</resources>
|
||||
@@ -3,24 +3,27 @@
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@android:color/black</item>
|
||||
<item name="colorPrimary">@android:color/transparent</item>
|
||||
<item name="colorPrimaryDark">@color/colour_four</item>
|
||||
<item name="colorAccent">@color/colour_one</item>
|
||||
<item name="android:windowBackground">@drawable/gradient</item>
|
||||
<item name="fontFamily">sans-serif-light</item>
|
||||
<item name="android:textColor">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="android:windowBackground">@drawable/gradient</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="TextAppearance.AppCompat.Widget.ActionBar.Title" parent="@android:style/TextAppearance">
|
||||
<item name="android:fontFamily">@font/archeologicaps</item>
|
||||
<!--<item name="android:textColor">@color/colour_five</item>-->
|
||||
</style>
|
||||
|
||||
<style name="titlebar" parent="@android:style/TextAppearance">
|
||||
<item name="android:fontFamily">@font/archeologicaps</item>
|
||||
<!--<item name="android:textColor">@color/colour_five</item>-->
|
||||
</style>
|
||||
|
||||
@@ -42,12 +45,4 @@
|
||||
<item name="android:textSize">32sp</item>
|
||||
</style>
|
||||
|
||||
<style name="icon_style__further_deatils">
|
||||
<item name="android:layout_width">64dp</item>
|
||||
<item name="android:layout_height">64dp</item>
|
||||
<item name="android:adjustViewBounds">true</item>
|
||||
<item name="android:layout_gravity">center</item>
|
||||
<item name="android:tint">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
</resources>
|
||||
15
app/src/atlasWeather/res/xml/new_app_widget_info.xml
Normal file
15
app/src/atlasWeather/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.atlas_weather.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>
|
||||
Reference in New Issue
Block a user