add possibility to move the main navigation to the bottom (#1808)
* add possibility to move the main navigation to the bottom * add top toolbar with drawer toggle, title and search button
This commit is contained in:
parent
70d426975f
commit
74bd493878
10 changed files with 188 additions and 61 deletions
|
@ -31,6 +31,7 @@ import android.view.View
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
import androidx.emoji.text.EmojiCompat
|
import androidx.emoji.text.EmojiCompat
|
||||||
|
@ -59,7 +60,10 @@ import com.keylesspalace.tusky.interfaces.ActionButtonActivity
|
||||||
import com.keylesspalace.tusky.interfaces.ReselectableFragment
|
import com.keylesspalace.tusky.interfaces.ReselectableFragment
|
||||||
import com.keylesspalace.tusky.pager.MainPagerAdapter
|
import com.keylesspalace.tusky.pager.MainPagerAdapter
|
||||||
import com.keylesspalace.tusky.util.*
|
import com.keylesspalace.tusky.util.*
|
||||||
|
import com.mikepenz.iconics.IconicsDrawable
|
||||||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||||
|
import com.mikepenz.iconics.utils.colorInt
|
||||||
|
import com.mikepenz.iconics.utils.sizeDp
|
||||||
import com.mikepenz.materialdrawer.iconics.iconicsIcon
|
import com.mikepenz.materialdrawer.iconics.iconicsIcon
|
||||||
import com.mikepenz.materialdrawer.model.*
|
import com.mikepenz.materialdrawer.model.*
|
||||||
import com.mikepenz.materialdrawer.model.interfaces.*
|
import com.mikepenz.materialdrawer.model.interfaces.*
|
||||||
|
@ -89,8 +93,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
||||||
private lateinit var drawerToggle: ActionBarDrawerToggle
|
private lateinit var drawerToggle: ActionBarDrawerToggle
|
||||||
|
|
||||||
private var notificationTabPosition = 0
|
private var notificationTabPosition = 0
|
||||||
|
private var onTabSelectedListener: OnTabSelectedListener? = null
|
||||||
private var adapter: MainPagerAdapter? = null
|
|
||||||
|
|
||||||
private val emojiInitCallback = object : InitCallback() {
|
private val emojiInitCallback = object : InitCallback() {
|
||||||
override fun onInitialized() {
|
override fun onInitialized() {
|
||||||
|
@ -159,6 +162,19 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
||||||
val composeIntent = Intent(applicationContext, ComposeActivity::class.java)
|
val composeIntent = Intent(applicationContext, ComposeActivity::class.java)
|
||||||
startActivity(composeIntent)
|
startActivity(composeIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mainToolbar.menu.add(R.string.action_search).apply {
|
||||||
|
setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
|
||||||
|
icon = IconicsDrawable(this@MainActivity, GoogleMaterial.Icon.gmd_search).apply {
|
||||||
|
sizeDp = 20
|
||||||
|
colorInt = ThemeUtils.getColor(this@MainActivity, android.R.attr.textColorPrimary)
|
||||||
|
}
|
||||||
|
setOnMenuItemClickListener {
|
||||||
|
startActivity(SearchActivity.getIntent(this@MainActivity))
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setupDrawer(savedInstanceState)
|
setupDrawer(savedInstanceState)
|
||||||
|
|
||||||
/* Fetch user info while we're doing other things. This has to be done after setting up the
|
/* Fetch user info while we're doing other things. This has to be done after setting up the
|
||||||
|
@ -167,30 +183,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
||||||
|
|
||||||
setupTabs(showNotificationTab)
|
setupTabs(showNotificationTab)
|
||||||
|
|
||||||
val pageMargin = resources.getDimensionPixelSize(R.dimen.tab_page_margin)
|
|
||||||
viewPager.setPageTransformer(MarginPageTransformer(pageMargin))
|
|
||||||
|
|
||||||
val uswSwipeForTabs = PreferenceManager.getDefaultSharedPreferences(this)
|
|
||||||
.getBoolean("enableSwipeForTabs", true)
|
|
||||||
viewPager.isUserInputEnabled = uswSwipeForTabs
|
|
||||||
|
|
||||||
tabLayout.addOnTabSelectedListener(object : OnTabSelectedListener {
|
|
||||||
override fun onTabSelected(tab: TabLayout.Tab) {
|
|
||||||
if (tab.position == notificationTabPosition) {
|
|
||||||
NotificationHelper.clearNotificationsForActiveAccount(this@MainActivity, accountManager)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onTabUnselected(tab: TabLayout.Tab) {}
|
|
||||||
|
|
||||||
override fun onTabReselected(tab: TabLayout.Tab) {
|
|
||||||
val fragment = adapter?.getFragment(tab.position)
|
|
||||||
if (fragment is ReselectableFragment) {
|
|
||||||
(fragment as ReselectableFragment).onReselect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Setup push notifications
|
// Setup push notifications
|
||||||
if (NotificationHelper.areNotificationsEnabled(this, accountManager)) {
|
if (NotificationHelper.areNotificationsEnabled(this, accountManager)) {
|
||||||
NotificationHelper.enablePullNotifications(this)
|
NotificationHelper.enablePullNotifications(this)
|
||||||
|
@ -376,13 +368,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
||||||
startActivityWithSlideInAnimation(ListsActivity.newIntent(context))
|
startActivityWithSlideInAnimation(ListsActivity.newIntent(context))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
primaryDrawerItem {
|
|
||||||
nameRes = R.string.action_search
|
|
||||||
iconicsIcon = GoogleMaterial.Icon.gmd_search
|
|
||||||
onClick = {
|
|
||||||
startActivityWithSlideInAnimation(SearchActivity.getIntent(context))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
primaryDrawerItem {
|
primaryDrawerItem {
|
||||||
nameRes = R.string.action_access_saved_toot
|
nameRes = R.string.action_access_saved_toot
|
||||||
iconRes = R.drawable.ic_notebook
|
iconRes = R.drawable.ic_notebook
|
||||||
|
@ -461,20 +446,37 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupTabs(selectNotificationTab: Boolean) {
|
private fun setupTabs(selectNotificationTab: Boolean) {
|
||||||
|
val preferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
|
||||||
|
val activeTabLayout = if(preferences.getString("mainNavPosition", "top") == "bottom") {
|
||||||
|
val actionBarSize = ThemeUtils.getDimension(this, R.attr.actionBarSize)
|
||||||
|
val fabMargin = resources.getDimensionPixelSize(R.dimen.fabMargin)
|
||||||
|
(composeButton.layoutParams as CoordinatorLayout.LayoutParams).bottomMargin = actionBarSize + fabMargin
|
||||||
|
tabLayout.hide()
|
||||||
|
bottomTabLayout
|
||||||
|
} else {
|
||||||
|
bottomNav.hide()
|
||||||
|
(viewPager.layoutParams as CoordinatorLayout.LayoutParams).bottomMargin = 0
|
||||||
|
(composeButton.layoutParams as CoordinatorLayout.LayoutParams).anchorId = R.id.viewPager
|
||||||
|
tabLayout
|
||||||
|
}
|
||||||
|
|
||||||
val tabs = accountManager.activeAccount!!.tabPreferences
|
val tabs = accountManager.activeAccount!!.tabPreferences
|
||||||
adapter = MainPagerAdapter(tabs, this)
|
|
||||||
|
val adapter = MainPagerAdapter(tabs, this)
|
||||||
viewPager.adapter = adapter
|
viewPager.adapter = adapter
|
||||||
TabLayoutMediator(tabLayout, viewPager, TabConfigurationStrategy { _: TabLayout.Tab?, _: Int -> }).attach()
|
TabLayoutMediator(activeTabLayout, viewPager, TabConfigurationStrategy { _: TabLayout.Tab?, _: Int -> }).attach()
|
||||||
tabLayout.removeAllTabs()
|
activeTabLayout.removeAllTabs()
|
||||||
for (i in tabs.indices) {
|
for (i in tabs.indices) {
|
||||||
val tab = tabLayout.newTab()
|
val tab = activeTabLayout.newTab()
|
||||||
.setIcon(tabs[i].icon)
|
.setIcon(tabs[i].icon)
|
||||||
if (tabs[i].id == LIST) {
|
if (tabs[i].id == LIST) {
|
||||||
tab.contentDescription = tabs[i].arguments[1]
|
tab.contentDescription = tabs[i].arguments[1]
|
||||||
} else {
|
} else {
|
||||||
tab.setContentDescription(tabs[i].text)
|
tab.setContentDescription(tabs[i].text)
|
||||||
}
|
}
|
||||||
tabLayout.addTab(tab)
|
activeTabLayout.addTab(tab)
|
||||||
|
|
||||||
if (tabs[i].id == NOTIFICATIONS) {
|
if (tabs[i].id == NOTIFICATIONS) {
|
||||||
notificationTabPosition = i
|
notificationTabPosition = i
|
||||||
if (selectNotificationTab) {
|
if (selectNotificationTab) {
|
||||||
|
@ -482,6 +484,40 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val pageMargin = resources.getDimensionPixelSize(R.dimen.tab_page_margin)
|
||||||
|
viewPager.setPageTransformer(MarginPageTransformer(pageMargin))
|
||||||
|
|
||||||
|
val uswSwipeForTabs = preferences.getBoolean("enableSwipeForTabs", true)
|
||||||
|
viewPager.isUserInputEnabled = uswSwipeForTabs
|
||||||
|
|
||||||
|
onTabSelectedListener?.let {
|
||||||
|
activeTabLayout.removeOnTabSelectedListener(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
onTabSelectedListener = object : OnTabSelectedListener {
|
||||||
|
override fun onTabSelected(tab: TabLayout.Tab) {
|
||||||
|
if (tab.position == notificationTabPosition) {
|
||||||
|
NotificationHelper.clearNotificationsForActiveAccount(this@MainActivity, accountManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
mainToolbar.title = tabs[tab.position].title(this@MainActivity)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabUnselected(tab: TabLayout.Tab) {}
|
||||||
|
|
||||||
|
override fun onTabReselected(tab: TabLayout.Tab) {
|
||||||
|
val fragment = adapter.getFragment(tab.position)
|
||||||
|
if (fragment is ReselectableFragment) {
|
||||||
|
(fragment as ReselectableFragment).onReselect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.also {
|
||||||
|
activeTabLayout.addOnTabSelectedListener(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
mainToolbar.title = tabs[0].title(this@MainActivity)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleProfileClick(profile: IProfile, current: Boolean): Boolean {
|
private fun handleProfileClick(profile: IProfile, current: Boolean): Boolean {
|
||||||
|
|
|
@ -129,7 +129,7 @@ class PreferencesActivity : BaseActivity(), SharedPreferences.OnSharedPreference
|
||||||
|
|
||||||
}
|
}
|
||||||
"statusTextSize", "absoluteTimeView", "showBotOverlay", "animateGifAvatars",
|
"statusTextSize", "absoluteTimeView", "showBotOverlay", "animateGifAvatars",
|
||||||
"useBlurhash", "showCardsInTimelines", "confirmReblogs", "enableSwipeForTabs" -> {
|
"useBlurhash", "showCardsInTimelines", "confirmReblogs", "enableSwipeForTabs", "mainNavPosition" -> {
|
||||||
restartActivitiesOnExit = true
|
restartActivitiesOnExit = true
|
||||||
}
|
}
|
||||||
"language" -> {
|
"language" -> {
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
package com.keylesspalace.tusky
|
package com.keylesspalace.tusky
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
@ -36,17 +37,58 @@ data class TabData(val id: String,
|
||||||
@StringRes val text: Int,
|
@StringRes val text: Int,
|
||||||
@DrawableRes val icon: Int,
|
@DrawableRes val icon: Int,
|
||||||
val fragment: (List<String>) -> Fragment,
|
val fragment: (List<String>) -> Fragment,
|
||||||
val arguments: List<String> = emptyList())
|
val arguments: List<String> = emptyList(),
|
||||||
|
val title: (Context) -> String = { context -> context.getString(text)}
|
||||||
|
)
|
||||||
|
|
||||||
fun createTabDataFromId(id: String, arguments: List<String> = emptyList()): TabData {
|
fun createTabDataFromId(id: String, arguments: List<String> = emptyList()): TabData {
|
||||||
return when (id) {
|
return when (id) {
|
||||||
HOME -> TabData(HOME, R.string.title_home, R.drawable.ic_home_24dp, { TimelineFragment.newInstance(TimelineFragment.Kind.HOME) })
|
HOME -> TabData(
|
||||||
NOTIFICATIONS -> TabData(NOTIFICATIONS, R.string.title_notifications, R.drawable.ic_notifications_24dp, { NotificationsFragment.newInstance() })
|
HOME,
|
||||||
LOCAL -> TabData(LOCAL, R.string.title_public_local, R.drawable.ic_local_24dp, { TimelineFragment.newInstance(TimelineFragment.Kind.PUBLIC_LOCAL) })
|
R.string.title_home,
|
||||||
FEDERATED -> TabData(FEDERATED, R.string.title_public_federated, R.drawable.ic_public_24dp, { TimelineFragment.newInstance(TimelineFragment.Kind.PUBLIC_FEDERATED) })
|
R.drawable.ic_home_24dp,
|
||||||
DIRECT -> TabData(DIRECT, R.string.title_direct_messages, R.drawable.ic_reblog_direct_24dp, { ConversationsFragment.newInstance() })
|
{ TimelineFragment.newInstance(TimelineFragment.Kind.HOME) }
|
||||||
HASHTAG -> TabData(HASHTAG, R.string.hashtags, R.drawable.ic_hashtag, { args -> TimelineFragment.newHashtagInstance(args) }, arguments)
|
)
|
||||||
LIST -> TabData(LIST, R.string.list, R.drawable.ic_list, { args -> TimelineFragment.newInstance(TimelineFragment.Kind.LIST, args.getOrNull(0).orEmpty()) }, arguments)
|
NOTIFICATIONS -> TabData(
|
||||||
|
NOTIFICATIONS,
|
||||||
|
R.string.title_notifications,
|
||||||
|
R.drawable.ic_notifications_24dp,
|
||||||
|
{ NotificationsFragment.newInstance() }
|
||||||
|
)
|
||||||
|
LOCAL -> TabData(
|
||||||
|
LOCAL,
|
||||||
|
R.string.title_public_local,
|
||||||
|
R.drawable.ic_local_24dp,
|
||||||
|
{ TimelineFragment.newInstance(TimelineFragment.Kind.PUBLIC_LOCAL) }
|
||||||
|
)
|
||||||
|
FEDERATED -> TabData(
|
||||||
|
FEDERATED,
|
||||||
|
R.string.title_public_federated,
|
||||||
|
R.drawable.ic_public_24dp,
|
||||||
|
{ TimelineFragment.newInstance(TimelineFragment.Kind.PUBLIC_FEDERATED) }
|
||||||
|
)
|
||||||
|
DIRECT -> TabData(
|
||||||
|
DIRECT,
|
||||||
|
R.string.title_direct_messages,
|
||||||
|
R.drawable.ic_reblog_direct_24dp,
|
||||||
|
{ ConversationsFragment.newInstance() }
|
||||||
|
)
|
||||||
|
HASHTAG -> TabData(
|
||||||
|
HASHTAG,
|
||||||
|
R.string.hashtags,
|
||||||
|
R.drawable.ic_hashtag,
|
||||||
|
{ args -> TimelineFragment.newHashtagInstance(args) },
|
||||||
|
arguments,
|
||||||
|
{ context -> arguments.joinToString(separator = " ") { context.getString(R.string.title_tag, it) }}
|
||||||
|
)
|
||||||
|
LIST -> TabData(
|
||||||
|
LIST,
|
||||||
|
R.string.list,
|
||||||
|
R.drawable.ic_list,
|
||||||
|
{ args -> TimelineFragment.newInstance(TimelineFragment.Kind.LIST, args.getOrNull(0).orEmpty()) },
|
||||||
|
arguments,
|
||||||
|
{ arguments.getOrNull(1).orEmpty() }
|
||||||
|
)
|
||||||
else -> throw IllegalArgumentException("unknown tab type")
|
else -> throw IllegalArgumentException("unknown tab type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,15 @@ class PreferencesFragment : PreferenceFragmentCompat() {
|
||||||
icon = makeIcon(GoogleMaterial.Icon.gmd_format_size)
|
icon = makeIcon(GoogleMaterial.Icon.gmd_format_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listPreference {
|
||||||
|
setDefaultValue("top")
|
||||||
|
setEntries(R.array.pref_main_nav_position_options)
|
||||||
|
setEntryValues(R.array.pref_main_nav_position_values)
|
||||||
|
key = PrefKeys.MAIN_NAV_POSITION
|
||||||
|
setSummaryProvider { entry }
|
||||||
|
setTitle(R.string.pref_main_nav_position)
|
||||||
|
}
|
||||||
|
|
||||||
switchPreference {
|
switchPreference {
|
||||||
setDefaultValue(false)
|
setDefaultValue(false)
|
||||||
key = PrefKeys.FAB_HIDE
|
key = PrefKeys.FAB_HIDE
|
||||||
|
|
|
@ -21,6 +21,7 @@ object PrefKeys {
|
||||||
const val FAB_HIDE = "fabHide"
|
const val FAB_HIDE = "fabHide"
|
||||||
const val LANGUAGE = "language"
|
const val LANGUAGE = "language"
|
||||||
const val STATUS_TEXT_SIZE = "statusTextSize"
|
const val STATUS_TEXT_SIZE = "statusTextSize"
|
||||||
|
const val MAIN_NAV_POSITION = "mainNavPosition"
|
||||||
const val ABSOLUTE_TIME_VIEW = "absoluteTimeView"
|
const val ABSOLUTE_TIME_VIEW = "absoluteTimeView"
|
||||||
const val SHOW_BOT_OVERLAY = "showBotOverlay"
|
const val SHOW_BOT_OVERLAY = "showBotOverlay"
|
||||||
const val ANIMATE_GIF_AVATARS = "animateGifAvatars"
|
const val ANIMATE_GIF_AVATARS = "animateGifAvatars"
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package com.keylesspalace.tusky.util;
|
package com.keylesspalace.tusky.util;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
@ -51,6 +52,13 @@ public class ThemeUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getDimension(@NonNull Context context, @AttrRes int attribute) {
|
||||||
|
TypedArray array = context.obtainStyledAttributes(new int[] { attribute });
|
||||||
|
int dimen = array.getDimensionPixelSize(0, -1);
|
||||||
|
array.recycle();
|
||||||
|
return dimen;
|
||||||
|
}
|
||||||
|
|
||||||
/** this can be replaced with drawableTint in xml once minSdkVersion >= 23 */
|
/** this can be replaced with drawableTint in xml once minSdkVersion >= 23 */
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Drawable getTintedDrawable(@NonNull Context context, @DrawableRes int drawableId, @AttrRes int colorAttr) {
|
public static Drawable getTintedDrawable(@NonNull Context context, @DrawableRes int drawableId, @AttrRes int colorAttr) {
|
||||||
|
|
|
@ -22,19 +22,17 @@
|
||||||
android:id="@+id/mainToolbar"
|
android:id="@+id/mainToolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:contentInsetStartWithNavigation="0dp">
|
app:contentInsetStartWithNavigation="0dp"
|
||||||
|
app:layout_scrollFlags="scroll|enterAlways" />
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
<com.google.android.material.tabs.TabLayout
|
||||||
android:id="@+id/tabLayout"
|
android:id="@+id/tabLayout"
|
||||||
style="@style/TuskyTabAppearance"
|
style="@style/TuskyTabAppearance"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="wrap_content"
|
||||||
app:tabGravity="fill"
|
app:tabGravity="fill"
|
||||||
app:tabMaxWidth="0dp"
|
app:tabMaxWidth="0dp"
|
||||||
app:tabMode="fixed"
|
app:tabMode="fixed" />
|
||||||
app:tabUnboundedRipple="false" />
|
|
||||||
|
|
||||||
</androidx.appcompat.widget.Toolbar>
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
@ -42,15 +40,32 @@
|
||||||
android:id="@+id/viewPager"
|
android:id="@+id/viewPager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_below="@id/tabLayout"
|
android:layout_marginBottom="?attr/actionBarSize"
|
||||||
android:background="?attr/windowBackgroundColor"
|
android:background="?attr/windowBackgroundColor"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||||
|
|
||||||
|
<com.google.android.material.bottomappbar.BottomAppBar
|
||||||
|
android:id="@+id/bottomNav"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
app:contentInsetStart="0dp"
|
||||||
|
app:fabAlignmentMode="end">
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/bottomTabLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:tabIndicator="@null"
|
||||||
|
app:tabMode="fixed" />
|
||||||
|
|
||||||
|
</com.google.android.material.bottomappbar.BottomAppBar>
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
android:id="@+id/composeButton"
|
android:id="@+id/composeButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="16dp"
|
android:layout_margin="@dimen/fabMargin"
|
||||||
android:contentDescription="@string/action_compose"
|
android:contentDescription="@string/action_compose"
|
||||||
app:layout_anchor="@id/viewPager"
|
app:layout_anchor="@id/viewPager"
|
||||||
app:layout_anchorGravity="bottom|end"
|
app:layout_anchorGravity="bottom|end"
|
||||||
|
|
|
@ -48,4 +48,6 @@
|
||||||
|
|
||||||
<dimen name="adaptive_bitmap_inner_size">72dp</dimen>
|
<dimen name="adaptive_bitmap_inner_size">72dp</dimen>
|
||||||
<dimen name="adaptive_bitmap_outer_size">108dp</dimen>
|
<dimen name="adaptive_bitmap_outer_size">108dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="fabMargin">16dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -110,6 +110,15 @@
|
||||||
<item>ja</item>
|
<item>ja</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="pref_main_nav_position_options">
|
||||||
|
<item>@string/pref_main_nav_position_option_top</item>
|
||||||
|
<item>@string/pref_main_nav_position_option_bottom</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="pref_main_nav_position_values">
|
||||||
|
<item>top</item>
|
||||||
|
<item>bottom</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string name="description_status" translatable="false">
|
<string name="description_status" translatable="false">
|
||||||
<!-- Display name, cw?, content?, poll? relative date, reposted by?, reposted?, favorited?, bookmarked?, username, media?; visibility, fav number?, reblog number?-->
|
<!-- Display name, cw?, content?, poll? relative date, reposted by?, reposted?, favorited?, bookmarked?, username, media?; visibility, fav number?, reblog number?-->
|
||||||
|
|
|
@ -252,6 +252,11 @@
|
||||||
<string name="pref_publishing">Publishing (synced with server)</string>
|
<string name="pref_publishing">Publishing (synced with server)</string>
|
||||||
<string name="pref_failed_to_sync">Failed to sync settings</string>
|
<string name="pref_failed_to_sync">Failed to sync settings</string>
|
||||||
|
|
||||||
|
<string name="pref_main_nav_position">Main navigation position</string>
|
||||||
|
<string name="pref_main_nav_position_option_top">Top</string>
|
||||||
|
<string name="pref_main_nav_position_option_bottom">Bottom</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="post_privacy_public">Public</string>
|
<string name="post_privacy_public">Public</string>
|
||||||
<string name="post_privacy_unlisted">Unlisted</string>
|
<string name="post_privacy_unlisted">Unlisted</string>
|
||||||
<string name="post_privacy_followers_only">Followers-only</string>
|
<string name="post_privacy_followers_only">Followers-only</string>
|
||||||
|
|
Loading…
Reference in a new issue