Drawer and bottom bar.
This commit is contained in:
parent
5e518ddc0e
commit
257d9fa401
@ -86,6 +86,10 @@ dependencies {
|
||||
// Dialog for adding a new location
|
||||
implementation 'com.afollestad.material-dialogs:core:3.1.0'
|
||||
implementation 'com.afollestad.material-dialogs:input:3.1.0'
|
||||
|
||||
// drawer
|
||||
implementation 'co.zsmb:materialdrawer-kt:2.0.1'
|
||||
implementation "androidx.annotation:annotation:1.1.0"
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,17 +7,29 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.location.LocationListener
|
||||
import android.location.LocationManager
|
||||
import android.util.Log
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.room.Room
|
||||
import bou.amine.apps.mteo.api.DarkSkyApi
|
||||
import bou.amine.apps.mteo.api.ForecastResponse
|
||||
import bou.amine.apps.mteo.persistence.MIGRATION_1_2
|
||||
import bou.amine.apps.mteo.persistence.database.AppDatabase
|
||||
import bou.amine.apps.mteo.persistence.entities.LocationView
|
||||
import co.zsmb.materialdrawerkt.builders.drawer
|
||||
import co.zsmb.materialdrawerkt.draweritems.badgeable.primaryItem
|
||||
import co.zsmb.materialdrawerkt.draweritems.badgeable.secondaryItem
|
||||
import co.zsmb.materialdrawerkt.draweritems.divider
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.input.input
|
||||
import com.mikepenz.materialdrawer.Drawer
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
@ -30,11 +42,15 @@ class MainActivity : AppCompatActivity() {
|
||||
private lateinit var api: DarkSkyApi
|
||||
|
||||
private lateinit var currentLocation: LocationView
|
||||
private lateinit var locations: List<LocationView>
|
||||
|
||||
private lateinit var drawer: Drawer
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
setSupportActionBar(bottom_app_bar)
|
||||
|
||||
api = DarkSkyApi(this@MainActivity)
|
||||
|
||||
@ -43,29 +59,83 @@ class MainActivity : AppCompatActivity() {
|
||||
AppDatabase::class.java, "mteo-database"
|
||||
).addMigrations(MIGRATION_1_2).build()
|
||||
|
||||
fab.setOnClickListener { checkPermission() }
|
||||
|
||||
handleRefresh()
|
||||
|
||||
thread {
|
||||
val locations = db.locationDao().locations()
|
||||
locations = db.locationDao().locations()
|
||||
runOnUiThread {
|
||||
if (locations.isEmpty()) {
|
||||
checkPermission()
|
||||
} else {
|
||||
currentLocation = locations[0]
|
||||
fetchForecastData()
|
||||
selectLocationAndFetch()
|
||||
loadDrawer()
|
||||
drawer.setSelection(locations[0].id.toLong(), false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleRefresh() {
|
||||
swipeRefreshLayout.setColorSchemeResources(
|
||||
R.color.colorPrimary,
|
||||
R.color.colorPrimaryDark,
|
||||
R.color.colorAccent
|
||||
)
|
||||
swipeRefreshLayout.setOnRefreshListener {
|
||||
fetchForecastData()
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadDrawer() {
|
||||
if (::drawer.isInitialized) {
|
||||
drawer.closeDrawer()
|
||||
}
|
||||
drawer = drawer {
|
||||
toolbar = toolBar
|
||||
primaryItem("Locations") {
|
||||
selectable = false
|
||||
}
|
||||
locations.map {
|
||||
secondaryItem(it.name) {
|
||||
identifier = it.id.toLong()
|
||||
onClick { _, position, _ ->
|
||||
selectLocationAndFetch(position - 1)
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
onItemLongClick {_, position, _ ->
|
||||
val toRemove = locations[position - 1]
|
||||
locations = locations.filterNot { it == toRemove }
|
||||
loadDrawer()
|
||||
thread {
|
||||
db.locationDao().deleteLocation(toRemove)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun selectLocationAndFetch(position: Int = 0) {
|
||||
swipeRefreshLayout.isRefreshing = true
|
||||
currentLocation = locations[position]
|
||||
fetchForecastData()
|
||||
}
|
||||
|
||||
private fun fetchForecastData() {
|
||||
thread {
|
||||
api.forecast(currentLocation.lat.toString(), currentLocation.lng.toString()).enqueue(object :
|
||||
Callback<ForecastResponse> {
|
||||
override fun onFailure(call: Call<ForecastResponse>, t: Throwable) {
|
||||
Toast.makeText(this@MainActivity, "Can't fetch forecast data !", Toast.LENGTH_LONG).show()
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call<ForecastResponse>, response: Response<ForecastResponse>) {
|
||||
Toast.makeText(this@MainActivity, "Ok", Toast.LENGTH_LONG).show()
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
}
|
||||
|
||||
})
|
||||
@ -114,10 +184,13 @@ class MainActivity : AppCompatActivity() {
|
||||
mLocationManager.removeUpdates(this)
|
||||
MaterialDialog(this@MainActivity).show {
|
||||
input { _, text ->
|
||||
currentLocation = LocationView(location.latitude, location.longitude, text.toString())
|
||||
fetchForecastData()
|
||||
locations += LocationView(location.latitude, location.longitude, text.toString())
|
||||
selectLocationAndFetch(locations.size - 1)
|
||||
thread {
|
||||
db.locationDao().insertLocation(currentLocation)
|
||||
runOnUiThread {
|
||||
loadDrawer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -147,4 +220,22 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
val inflater = menuInflater
|
||||
inflater.inflate(R.menu.bottom_app_bar, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
when (item!!.itemId) {
|
||||
R.id.alerts -> Toast.makeText(this@MainActivity, "alerts item is clicked!", Toast.LENGTH_SHORT).show()
|
||||
R.id.currently -> Toast.makeText(this@MainActivity, "currently item is clicked!", Toast.LENGTH_SHORT).show()
|
||||
R.id.daily -> Toast.makeText(this@MainActivity, "daily item is clicked!", Toast.LENGTH_SHORT).show()
|
||||
R.id.hourly -> Toast.makeText(this@MainActivity, "hourly item is clicked!", Toast.LENGTH_SHORT).show()
|
||||
R.id.minutely -> Toast.makeText(this@MainActivity, "minutely item is clicked!", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
package bou.amine.apps.mteo.persistence.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.*
|
||||
import bou.amine.apps.mteo.persistence.entities.LocationView
|
||||
|
||||
@Dao
|
||||
@ -13,4 +10,7 @@ interface LocationsDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertLocation(vararg location: LocationView)
|
||||
|
||||
@Delete
|
||||
fun deleteLocation(tag: LocationView)
|
||||
}
|
9
app/src/main/res/drawable-anydpi/ic_access_time.xml
Normal file
9
app/src/main/res/drawable-anydpi/ic_access_time.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM12.5,7H11v6l5.25,3.15 0.75,-1.23 -4.5,-2.67z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable-anydpi/ic_add_location.xml
Normal file
9
app/src/main/res/drawable-anydpi/ic_add_location.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,2C8.14,2 5,5.14 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.86 -3.14,-7 -7,-7zM16,10h-3v3h-2v-3L8,10L8,8h3L11,5h2v3h3v2z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable-anydpi/ic_cloud_circle.xml
Normal file
9
app/src/main/res/drawable-anydpi/ic_cloud_circle.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16.5,16L8,16c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3l0.14,0.01C8.58,8.28 10.13,7 12,7c2.21,0 4,1.79 4,4h0.5c1.38,0 2.5,1.12 2.5,2.5S17.88,16 16.5,16z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable-anydpi/ic_error_outline.xml
Normal file
9
app/src/main/res/drawable-anydpi/ic_error_outline.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable-anydpi/ic_hourglass_empty.xml
Normal file
9
app/src/main/res/drawable-anydpi/ic_hourglass_empty.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M6,2v6h0.01L6,8.01 10,12l-4,4 0.01,0.01L6,16.01L6,22h12v-5.99h-0.01L18,16l-4,-4 4,-3.99 -0.01,-0.01L18,8L18,2L6,2zM16,16.5L16,20L8,20v-3.5l4,-4 4,4zM12,11.5l-4,-4L8,4h8v3.5l-4,4z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable-anydpi/ic_view_day.xml
Normal file
9
app/src/main/res/drawable-anydpi/ic_view_day.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M2,21h19v-3H2v3zM20,8H3c-0.55,0 -1,0.45 -1,1v6c0,0.55 0.45,1 1,1h17c0.55,0 1,-0.45 1,-1V9c0,-0.55 -0.45,-1 -1,-1zM2,3v3h19V3H2z"/>
|
||||
</vector>
|
@ -1,19 +1,83 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
tools:context=".MainActivity"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/coordLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/intern_coordLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:theme="@style/ToolBarStyle"/>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipeRefreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="?android:attr/windowBackground">
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
<com.google.android.material.bottomappbar.BottomAppBar
|
||||
android:id="@+id/bottom_app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
app:backgroundTint="@color/colorPrimary"
|
||||
app:fabAlignmentMode="end"
|
||||
style="@style/Widget.MaterialComponents.BottomAppBar"/>
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_add_location"
|
||||
android:tint="#FFFFFF"
|
||||
app:layout_anchor="@id/bottom_app_bar" />
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
35
app/src/main/res/menu/bottom_app_bar.xml
Normal file
35
app/src/main/res/menu/bottom_app_bar.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/alerts"
|
||||
android:icon="@drawable/ic_error_outline"
|
||||
android:title="Alerts"
|
||||
android:iconTint="#FFFFFFFF"
|
||||
app:showAsAction="always"/>
|
||||
<item
|
||||
android:id="@+id/currently"
|
||||
android:icon="@drawable/ic_cloud_circle"
|
||||
android:title="Currently"
|
||||
android:iconTint="#FFFFFFFF"
|
||||
app:showAsAction="always"/>
|
||||
<item
|
||||
android:id="@+id/daily"
|
||||
android:icon="@drawable/ic_view_day"
|
||||
android:title="Daily"
|
||||
android:iconTint="#FFFFFFFF"
|
||||
app:showAsAction="always"/>
|
||||
<item
|
||||
android:id="@+id/hourly"
|
||||
android:icon="@drawable/ic_access_time"
|
||||
android:title="Hourly"
|
||||
android:iconTint="#FFFFFFFF"
|
||||
app:showAsAction="always"/>
|
||||
<item
|
||||
android:id="@+id/minutely"
|
||||
android:icon="@drawable/ic_hourglass_empty"
|
||||
android:title="Minutely"
|
||||
android:iconTint="#FFFFFFFF"
|
||||
app:showAsAction="always"/>
|
||||
</menu>
|
@ -1,11 +1,20 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<style name="AppTheme" parent="MaterialDrawerTheme.Light">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<!-- ToolBar -->
|
||||
<style name="ToolBarStyle" parent="Theme.AppCompat">
|
||||
<item name="android:textColorPrimary">#FFFFFFFF</item>
|
||||
<item name="android:textColorSecondary">#FFFFFFFF</item>
|
||||
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
|
||||
<item name="actionMenuTextColor">#FFFFFFFF</item>
|
||||
<!--<item name="actionOverflowButtonStyle">@style/ActionButtonOverflowStyle</item>
|
||||
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>-->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user