Drawer with caching.

This commit is contained in:
Amine 2017-06-04 16:09:42 +02:00
parent 9d40026ef7
commit fb84b31122
11 changed files with 282 additions and 39 deletions

View File

@ -1,3 +1,7 @@
**1.5.0.3**
- Added a drawer for filtering sources and tags.
**1.5.0.2** **1.5.0.2**
- If the content in the article viewer is empty, the article will open in a custom tab. - If the content in the article viewer is empty, the article will open in a custom tab.

View File

@ -113,6 +113,12 @@ dependencies {
// For the article reader // For the article reader
compile 'com.klinkerapps:drag-dismiss-activity:1.4.0' compile 'com.klinkerapps:drag-dismiss-activity:1.4.0'
// Drawer
compile('com.mikepenz:materialdrawer:5.9.2@aar') {
transitive = true
}
compile 'com.anupcowkur:reservoir:3.1.0'
} }
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'

View File

@ -31,7 +31,8 @@
<activity android:name=".LoginActivity" <activity android:name=".LoginActivity"
android:label="@string/title_activity_login"> android:label="@string/title_activity_login">
</activity> </activity>
<activity android:name=".HomeActivity"> <activity android:name=".HomeActivity"
android:theme="@style/NoBar">
</activity> </activity>
<activity <activity
android:name=".settings.SettingsActivity" android:name=".settings.SettingsActivity"

View File

@ -4,6 +4,8 @@ import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager import android.preference.PreferenceManager
@ -13,21 +15,24 @@ import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.GridLayoutManager import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.support.v7.widget.StaggeredGridLayoutManager import android.support.v7.widget.StaggeredGridLayoutManager
import android.support.v7.widget.Toolbar
import android.support.v7.widget.helper.ItemTouchHelper import android.support.v7.widget.helper.ItemTouchHelper
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View
import android.widget.Toast import android.widget.Toast
import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter
import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter
import apps.amine.bou.readerforselfoss.api.selfoss.Item import apps.amine.bou.readerforselfoss.api.selfoss.*
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.Stats
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.settings.SettingsActivity import apps.amine.bou.readerforselfoss.settings.SettingsActivity
import apps.amine.bou.readerforselfoss.utils.Config import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.checkAndDisplayStoreApk import apps.amine.bou.readerforselfoss.utils.checkAndDisplayStoreApk
import apps.amine.bou.readerforselfoss.utils.checkApkVersion import apps.amine.bou.readerforselfoss.utils.checkApkVersion
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
import apps.amine.bou.readerforselfoss.utils.longHash
import com.anupcowkur.reservoir.Reservoir
import com.anupcowkur.reservoir.ReservoirGetCallback
import com.anupcowkur.reservoir.ReservoirPutCallback
import com.crashlytics.android.answers.Answers import com.crashlytics.android.answers.Answers
import com.crashlytics.android.answers.InviteEvent import com.crashlytics.android.answers.InviteEvent
import com.github.stkent.amplify.prompt.DefaultLayoutPromptView import com.github.stkent.amplify.prompt.DefaultLayoutPromptView
@ -36,13 +41,21 @@ import com.google.android.gms.appinvite.AppInviteInvitation
import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability import com.google.android.gms.common.GoogleApiAvailability
import com.google.firebase.remoteconfig.FirebaseRemoteConfig import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.gson.reflect.TypeToken
import com.mikepenz.aboutlibraries.Libs import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.aboutlibraries.LibsBuilder import com.mikepenz.aboutlibraries.LibsBuilder
import com.mikepenz.materialdrawer.Drawer
import com.mikepenz.materialdrawer.DrawerBuilder
import com.mikepenz.materialdrawer.model.DividerDrawerItem
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
import com.roughike.bottombar.BottomBar import com.roughike.bottombar.BottomBar
import com.roughike.bottombar.BottomBarTab import com.roughike.bottombar.BottomBarTab
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
import java.lang.Exception
class HomeActivity : AppCompatActivity() { class HomeActivity : AppCompatActivity() {
@ -51,6 +64,8 @@ class HomeActivity : AppCompatActivity() {
private val MENU_PREFERENCES = 12302 private val MENU_PREFERENCES = 12302
private val REQUEST_INVITE = 13231 private val REQUEST_INVITE = 13231
private val REQUEST_INVITE_BYMAIL = 13232 private val REQUEST_INVITE_BYMAIL = 13232
private val DRAWER_ID_TAGS = 100101L
private val DRAWER_ID_SOURCES = 100110L
private var mRecyclerView: RecyclerView? = null private var mRecyclerView: RecyclerView? = null
private var api: SelfossApi? = null private var api: SelfossApi? = null
private var items: ArrayList<Item> = ArrayList() private var items: ArrayList<Item> = ArrayList()
@ -77,6 +92,10 @@ class HomeActivity : AppCompatActivity() {
private var tabStarred: BottomBarTab? = null private var tabStarred: BottomBarTab? = null
private var mFirebaseRemoteConfig: FirebaseRemoteConfig? = null private var mFirebaseRemoteConfig: FirebaseRemoteConfig? = null
private var fullHeightCards: Boolean = false private var fullHeightCards: Boolean = false
private var toolbar: Toolbar? = null
private var drawer: Drawer? = null
data class DrawerData(val tags: List<Tag>?, val sources: List<Sources>?)
private fun handleSharedPrefs() { private fun handleSharedPrefs() {
clickBehavior = this.sharedPref!!.getBoolean("tab_on_tap", false) clickBehavior = this.sharedPref!!.getBoolean("tab_on_tap", false)
@ -91,6 +110,8 @@ class HomeActivity : AppCompatActivity() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
handleDrawerItems()
sharedPref = PreferenceManager.getDefaultSharedPreferences(this) sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
val settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) val settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
@ -110,13 +131,150 @@ class HomeActivity : AppCompatActivity() {
getElementsAccordingToTab() getElementsAccordingToTab()
} }
fun handleDrawer() {
drawer = DrawerBuilder()
.withActivity(this)
.withRootView(R.id.drawer_layout)
.withToolbar(toolbar!!)
.withActionBarDrawerToggle(true)
.withActionBarDrawerToggleAnimated(true)
.withShowDrawerOnFirstLaunch(true)
.build()
}
fun handleDrawerItems() {
fun handleDrawerData(maybeDrawerData: DrawerData?, loadedFromCache: Boolean = false) {
fun handleTags(maybeTags: List<Tag>?) {
if (maybeTags == null) {
if (loadedFromCache)
drawer!!.addItem(PrimaryDrawerItem().withName("Error loading tags..."))
}
else {
for (tag in maybeTags) {
val gd: GradientDrawable = GradientDrawable()
gd.setColor(Color.parseColor(tag.color))
gd.shape = GradientDrawable.RECTANGLE
gd.setSize(30, 30)
gd.cornerRadius = 30F
drawer!!.addItem(
PrimaryDrawerItem()
.withName(tag.tag)
.withIdentifier(longHash(tag.tag))
.withIcon(gd)
.withOnDrawerItemClickListener { _, _, _ ->
getElementsAccordingToTab(maybeTagFilter = tag)
true
}
)
}
}
}
fun handleSources(maybeSources: List<Sources>?) {
if (maybeSources == null) {
if (loadedFromCache)
drawer!!.addItem(PrimaryDrawerItem().withName("Error loading sources..."))
}
else
for (tag in maybeSources)
drawer!!.addItem(
PrimaryDrawerItem()
.withName(tag.title)
.withIdentifier(tag.id.toLong())
.withOnDrawerItemClickListener { _, _, _ ->
getElementsAccordingToTab(maybeSourceFilter = tag)
true
}
)
}
drawer!!.removeAllItems()
if (maybeDrawerData != null) {
drawer!!.addItem(SecondaryDrawerItem().withName("Tags").withIdentifier(DRAWER_ID_TAGS).withSelectable(false))
handleTags(maybeDrawerData.tags)
drawer!!.addItem(DividerDrawerItem())
drawer!!.addItem(SecondaryDrawerItem().withName("Sources").withIdentifier(DRAWER_ID_TAGS).withSelectable(false))
handleSources(maybeDrawerData.sources)
if (!loadedFromCache)
Reservoir.putAsync("drawerData", maybeDrawerData, object : ReservoirPutCallback {
override fun onSuccess() {}
override fun onFailure(p0: Exception?) {
Toast.makeText(this@HomeActivity, "Couldn't cache your drawer data", Toast.LENGTH_SHORT).show()
}
})
} else {
if (!loadedFromCache) {
drawer!!.addItem(SecondaryDrawerItem().withName("No tags loaded").withIdentifier(DRAWER_ID_TAGS).withSelectable(false))
drawer!!.addItem(SecondaryDrawerItem().withName("No sources loaded").withIdentifier(DRAWER_ID_SOURCES).withSelectable(false))
}
}
}
fun drawerApiCalls(maybeDrawerData: DrawerData?) {
var tags: List<Tag>? = null
var sources: List<Sources>? = null
fun sourcesApiCall() {
api!!.sources.enqueue(object: Callback<List<Sources>> {
override fun onResponse(call: Call<List<Sources>>?, response: Response<List<Sources>>) {
sources = response.body()
val apiDrawerData = DrawerData(tags, sources)
if (maybeDrawerData == null || (maybeDrawerData != null && maybeDrawerData != apiDrawerData))
handleDrawerData(apiDrawerData)
}
override fun onFailure(call: Call<List<Sources>>?, t: Throwable?) {
}
})
}
api!!.tags.enqueue(object: Callback<List<Tag>> {
override fun onResponse(call: Call<List<Tag>>, response: Response<List<Tag>>) {
tags = response.body()
sourcesApiCall()
}
override fun onFailure(call: Call<List<Tag>>?, t: Throwable?) {
sourcesApiCall()
}
})
}
drawer!!.addItem(SecondaryDrawerItem().withName("Loading ...").withSelectable(false))
val resultType = object : TypeToken<DrawerData>() {}.type
Reservoir.getAsync("drawerData", resultType, object: ReservoirGetCallback<DrawerData> {
override fun onSuccess(maybeDrawerData: DrawerData?) {
handleDrawerData(maybeDrawerData, loadedFromCache = true)
drawerApiCalls(maybeDrawerData)
}
override fun onFailure(p0: Exception?) {
drawerApiCalls(null)
}
})
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home) setContentView(R.layout.activity_home)
toolbar = findViewById(R.id.toolbar) as Toolbar?
setSupportActionBar(toolbar)
if (savedInstanceState == null) { if (savedInstanceState == null) {
val promptView = findViewById(R.id.prompt_view) as DefaultLayoutPromptView val promptView = findViewById(R.id.prompt_view) as DefaultLayoutPromptView
Amplify.getSharedInstance().promptIfReady(promptView) Amplify.getSharedInstance().promptIfReady(promptView)
} }
@ -130,6 +288,8 @@ class HomeActivity : AppCompatActivity() {
mBottomBar = findViewById(R.id.bottomBar) as BottomBar mBottomBar = findViewById(R.id.bottomBar) as BottomBar
handleDrawer()
// TODO: clean this hack // TODO: clean this hack
val listenerAlreadySet = booleanArrayOf(false) val listenerAlreadySet = booleanArrayOf(false)
mBottomBar!!.setOnTabSelectListener { tabId -> mBottomBar!!.setOnTabSelectListener { tabId ->
@ -228,20 +388,20 @@ class HomeActivity : AppCompatActivity() {
} }
} }
private fun getElementsAccordingToTab() { private fun getElementsAccordingToTab(maybeTagFilter: Tag? = null, maybeSourceFilter: Sources? = null) {
items = ArrayList() items = ArrayList()
when (elementsShown) { when (elementsShown) {
UNREAD_SHOWN -> getUnRead() UNREAD_SHOWN -> getUnRead(maybeTagFilter, maybeSourceFilter)
READ_SHOWN -> getRead() READ_SHOWN -> getRead(maybeTagFilter, maybeSourceFilter)
FAV_SHOWN -> getStarred() FAV_SHOWN -> getStarred(maybeTagFilter, maybeSourceFilter)
else -> getUnRead() else -> getUnRead(maybeTagFilter, maybeSourceFilter)
} }
} }
private fun getUnRead() { private fun getUnRead(maybeTagFilter: Tag? = null, maybeSourceFilter: Sources? = null) {
elementsShown = UNREAD_SHOWN elementsShown = UNREAD_SHOWN
api!!.unreadItems.enqueue(object : Callback<List<Item>> { api!!.unreadItems(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong()).enqueue(object : Callback<List<Item>> {
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) { override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
if (response.body() != null && response.body()!!.isNotEmpty()) { if (response.body() != null && response.body()!!.isNotEmpty()) {
items = response.body() as ArrayList<Item> items = response.body() as ArrayList<Item>
@ -259,9 +419,9 @@ class HomeActivity : AppCompatActivity() {
}) })
} }
private fun getRead() { private fun getRead(maybeTagFilter: Tag? = null, maybeSourceFilter: Sources? = null) {
elementsShown = READ_SHOWN elementsShown = READ_SHOWN
api!!.readItems.enqueue(object : Callback<List<Item>> { api!!.readItems(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong()).enqueue(object : Callback<List<Item>> {
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) { override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
if (response.body() != null && response.body()!!.isNotEmpty()) { if (response.body() != null && response.body()!!.isNotEmpty()) {
items = response.body() as ArrayList<Item> items = response.body() as ArrayList<Item>
@ -279,9 +439,9 @@ class HomeActivity : AppCompatActivity() {
}) })
} }
private fun getStarred() { private fun getStarred(maybeTagFilter: Tag? = null, maybeSourceFilter: Sources? = null) {
elementsShown = FAV_SHOWN elementsShown = FAV_SHOWN
api!!.starredItems.enqueue(object : Callback<List<Item>> { api!!.starredItems(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong()).enqueue(object : Callback<List<Item>> {
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) { override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
if (response.body() != null && response.body()!!.isNotEmpty()) { if (response.body() != null && response.body()!!.isNotEmpty()) {
items = response.body() as ArrayList<Item> items = response.body() as ArrayList<Item>

View File

@ -4,6 +4,8 @@ import android.support.multidex.MultiDexApplication
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
import com.github.stkent.amplify.tracking.Amplify import com.github.stkent.amplify.tracking.Amplify
import io.fabric.sdk.android.Fabric import io.fabric.sdk.android.Fabric
import com.anupcowkur.reservoir.Reservoir
import java.io.IOException
class MyApp : MultiDexApplication() { class MyApp : MultiDexApplication() {
@ -16,5 +18,11 @@ class MyApp : MultiDexApplication() {
.setFeedbackEmailAddress(getString(R.string.feedback_email)) .setFeedbackEmailAddress(getString(R.string.feedback_email))
.setAlwaysShow(BuildConfig.DEBUG) .setAlwaysShow(BuildConfig.DEBUG)
.applyAllDefaultRules() .applyAllDefaultRules()
try {
Reservoir.init(this, 4096) //in bytes
} catch (e: IOException) {
//failure
}
} }
} }

View File

@ -72,17 +72,17 @@ class SelfossApi(c: Context) {
return service.loginToSelfoss(config.userLogin, config.userPassword) return service.loginToSelfoss(config.userLogin, config.userPassword)
} }
val readItems: Call<List<Item>> fun readItems(tag: String?, sourceId: Long?): Call<List<Item>> =
get() = getItems("read") getItems("read", tag, sourceId)
val unreadItems: Call<List<Item>> fun unreadItems(tag: String?, sourceId: Long?): Call<List<Item>> =
get() = getItems("unread") getItems("unread", tag, sourceId)
val starredItems: Call<List<Item>> fun starredItems(tag: String?, sourceId: Long?): Call<List<Item>> =
get() = getItems("starred") getItems("starred", tag, sourceId)
private fun getItems(type: String): Call<List<Item>> { private fun getItems(type: String, tag: String?, sourceId: Long?): Call<List<Item>> {
return service.getItems(type, userName, password) return service.getItems(type, tag, sourceId, userName, password)
} }
fun markItem(itemId: String): Call<SuccessResponse> { fun markItem(itemId: String): Call<SuccessResponse> {

View File

@ -17,7 +17,7 @@ private fun constructUrl(config: Config?, path: String, file: String): String {
} }
data class Tag(val tag: String, val color: String, val unread: Int) data class Tag(val tag: String, val color: String)
class SuccessResponse(val success: Boolean) { class SuccessResponse(val success: Boolean) {
val isSuccess: Boolean val isSuccess: Boolean

View File

@ -16,7 +16,11 @@ internal interface SelfossService {
fun loginToSelfoss(@Query("username") username: String, @Query("password") password: String): Call<SuccessResponse> fun loginToSelfoss(@Query("username") username: String, @Query("password") password: String): Call<SuccessResponse>
@GET("items") @GET("items")
fun getItems(@Query("type") type: String, @Query("username") username: String, @Query("password") password: String): Call<List<Item>> fun getItems(@Query("type") type: String,
@Query("tag") tag: String?,
@Query("source") source: Long?,
@Query("username") username: String,
@Query("password") password: String): Call<List<Item>>
@POST("mark/{id}") @POST("mark/{id}")
fun markAsRead(@Path("id") id: String, @Query("username") username: String, @Query("password") password: String): Call<SuccessResponse> fun markAsRead(@Path("id") id: String, @Query("username") username: String, @Query("password") password: String): Call<SuccessResponse>

View File

@ -86,3 +86,14 @@ private fun isThereAnUpdate(settings: SharedPreferences, editor: SharedPreferenc
} }
} }
fun longHash(string: String): Long {
var h = 98764321261L
val l = string.length
val chars = string.toCharArray()
for (i in 0..l - 1) {
h = 31 * h + chars[i].toLong()
}
return h
}

View File

@ -5,6 +5,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="apps.amine.bou.readerforselfoss.HomeActivity" tools:context="apps.amine.bou.readerforselfoss.HomeActivity"
android:fitsSystemWindows="true"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<com.github.stkent.amplify.prompt.DefaultLayoutPromptView <com.github.stkent.amplify.prompt.DefaultLayoutPromptView
@ -34,6 +35,35 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@id/prompt_view"> android:layout_below="@id/prompt_view">
<android.support.design.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">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:theme="@style/ToolBarStyle"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout <android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout" android:id="@+id/swipeRefreshLayout"
@ -50,6 +80,10 @@
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.v4.widget.SwipeRefreshLayout> </android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
<com.roughike.bottombar.BottomBar <com.roughike.bottombar.BottomBar
android:id="@+id/bottomBar" android:id="@+id/bottomBar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -62,6 +96,5 @@
app:bb_badgeBackgroundColor="@color/colorPrimary" app:bb_badgeBackgroundColor="@color/colorPrimary"
app:bb_inActiveTabColor="@color/black" app:bb_inActiveTabColor="@color/black"
app:bb_badgesHideWhenActive="false" /> app:bb_badgesHideWhenActive="false" />
</android.support.design.widget.CoordinatorLayout> </android.support.design.widget.CoordinatorLayout>
</RelativeLayout> </RelativeLayout>

View File

@ -13,4 +13,20 @@
<item name="android:windowBackground">@drawable/background_splash</item> <item name="android:windowBackground">@drawable/background_splash</item>
</style> </style>
<style name="NoBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textColor">#000000</item>
</style>
<!-- ToolBar -->
<style name="ToolBarStyle" parent="Theme.AppCompat">
<item name="android:textColorPrimary">@color/white</item>
<item name="android:textColorSecondary">@color/white</item>
<item name="actionMenuTextColor">@color/white</item>
<!--<item name="actionOverflowButtonStyle">@style/ActionButtonOverflowStyle</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>-->
</style>
</resources> </resources>