Skip to content

Commit 43b4e58

Browse files
Merge pull request #16601 from nextcloud/change-file-list-action-style
style(file-list-actions): use m3 buttons instead of linear layout
2 parents 49e85d0 + 703b42d commit 43b4e58

15 files changed

Lines changed: 462 additions & 559 deletions

app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingMenuBottomSheetDialog.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import android.os.Bundle;
1414
import android.view.View;
1515
import android.view.ViewGroup;
16+
import androidx.core.content.ContextCompat;
17+
import com.owncloud.android.R;
1618

1719
import com.google.android.material.bottomsheet.BottomSheetBehavior;
1820
import com.google.android.material.bottomsheet.BottomSheetDialog;
@@ -59,10 +61,15 @@ protected void onCreate(Bundle savedInstanceState) {
5961

6062
viewThemeUtils.platform.themeDialog(binding.getRoot());
6163

62-
viewThemeUtils.platform.colorImageView(binding.menuIconAdvancedPermissions, ColorRole.PRIMARY);
63-
viewThemeUtils.platform.colorImageView(binding.menuIconSendLink, ColorRole.PRIMARY);
64-
viewThemeUtils.platform.colorImageView(binding.menuIconUnshare, ColorRole.PRIMARY);
65-
viewThemeUtils.platform.colorImageView(binding.menuIconSendNewEmail, ColorRole.PRIMARY);
64+
int textColor = ContextCompat.getColor(getContext(), R.color.text_color);
65+
viewThemeUtils.material.colorMaterialButtonContent(binding.menuShareAdvancedPermissions, ColorRole.PRIMARY);
66+
viewThemeUtils.material.colorMaterialButtonContent(binding.menuShareSendNewEmail, ColorRole.PRIMARY);
67+
viewThemeUtils.material.colorMaterialButtonContent(binding.menuShareSendLink, ColorRole.PRIMARY);
68+
viewThemeUtils.material.colorMaterialButtonContent(binding.menuShareUnshare, ColorRole.PRIMARY);
69+
binding.menuShareAdvancedPermissions.setTextColor(textColor);
70+
binding.menuShareSendNewEmail.setTextColor(textColor);
71+
binding.menuShareSendLink.setTextColor(textColor);
72+
binding.menuShareUnshare.setTextColor(textColor);
6673

6774
updateUI();
6875

app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.kt

Lines changed: 72 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@ package com.owncloud.android.ui.fragment
99

1010
import android.os.Build
1111
import android.os.Bundle
12+
import android.view.ContextThemeWrapper
13+
import android.view.Gravity
1214
import android.view.View
15+
import android.widget.LinearLayout
16+
import androidx.core.content.ContextCompat
1317
import com.google.android.material.bottomsheet.BottomSheetDialog
18+
import com.google.android.material.button.MaterialButton
1419
import com.google.gson.Gson
1520
import com.nextcloud.android.common.ui.theme.utils.ColorRole
1621
import com.nextcloud.client.account.User
@@ -21,7 +26,6 @@ import com.nextcloud.utils.BuildHelper.isFlavourGPlay
2126
import com.nextcloud.utils.EditorUtils
2227
import com.owncloud.android.MainApp
2328
import com.owncloud.android.R
24-
import com.owncloud.android.databinding.FileListActionsBottomSheetCreatorBinding
2529
import com.owncloud.android.databinding.FileListActionsBottomSheetFragmentBinding
2630
import com.owncloud.android.datamodel.ArbitraryDataProvider
2731
import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
@@ -81,24 +85,35 @@ class OCFileListBottomSheetDialog(
8185

8286
if (!hasPermission) {
8387
binding.menuUploadFiles.visibility = View.GONE
84-
binding.uploadContentFromOtherApps.text = context.getString(R.string.upload_files)
88+
binding.menuUploadFromApp.text = context.getString(R.string.upload_files)
8589
}
8690
}
8791
}
8892

8993
private fun applyBranding() {
90-
viewThemeUtils.platform.run {
94+
viewThemeUtils.material.run {
9195
binding.run {
92-
colorImageView(menuIconUploadFiles, ColorRole.PRIMARY)
93-
colorImageView(menuIconUploadFromApp, ColorRole.PRIMARY)
94-
colorImageView(menuIconDirectCameraUpload, ColorRole.PRIMARY)
95-
colorImageView(menuIconScanDocUpload, ColorRole.PRIMARY)
96-
colorImageView(menuIconMkdir, ColorRole.PRIMARY)
97-
colorImageView(menuIconAddFolderInfo, ColorRole.PRIMARY)
98-
99-
colorViewBackground(binding.bottomSheet, ColorRole.SURFACE)
96+
colorMaterialButtonContent(menuUploadFiles, ColorRole.PRIMARY)
97+
colorMaterialButtonContent(menuUploadFromApp, ColorRole.PRIMARY)
98+
colorMaterialButtonContent(menuDirectCameraUpload, ColorRole.PRIMARY)
99+
colorMaterialButtonContent(menuScanDocUpload, ColorRole.PRIMARY)
100+
colorMaterialButtonContent(menuMkdir, ColorRole.PRIMARY)
101+
colorMaterialButtonContent(menuCreateRichWorkspace, ColorRole.PRIMARY)
100102
}
101103
}
104+
105+
viewThemeUtils.platform.colorViewBackground(binding.bottomSheet, ColorRole.SURFACE)
106+
107+
val textColor = ContextCompat.getColor(context, R.color.text_color)
108+
109+
binding.run {
110+
menuUploadFiles.setTextColor(textColor)
111+
menuUploadFromApp.setTextColor(textColor)
112+
menuDirectCameraUpload.setTextColor(textColor)
113+
menuScanDocUpload.setTextColor(textColor)
114+
menuMkdir.setTextColor(textColor)
115+
menuCreateRichWorkspace.setTextColor(textColor)
116+
}
102117
}
103118

104119
@Suppress("ComplexCondition")
@@ -110,50 +125,76 @@ class OCFileListBottomSheetDialog(
110125
capability.richDocumentsTemplatesAvailable.isTrue &&
111126
!file.isEncrypted
112127
) {
113-
binding.templates.visibility = View.VISIBLE
128+
binding.menuNewDocument.visibility = View.VISIBLE
129+
binding.menuNewSpreadsheet.visibility = View.VISIBLE
130+
binding.menuNewPresentation.visibility = View.VISIBLE
114131
}
115132
}
116133

117-
@Suppress("DEPRECATION")
134+
@Suppress("DEPRECATION", "LongMethod", "MagicNumber")
118135
private fun initCreatorContainer() {
119136
val json = ArbitraryDataProviderImpl(context)
120137
.getValue(user, ArbitraryDataProvider.DIRECT_EDITING)
121138

122-
if (!json.isEmpty() && !file.isEncrypted) {
139+
if (json.isNotEmpty() && !file.isEncrypted) {
123140
val directEditing = Gson().fromJson(json, DirectEditing::class.java)
124141
if (directEditing.creators.isEmpty()) {
125142
return
126143
}
127144

128145
binding.creatorsContainer.visibility = View.VISIBLE
146+
binding.creators.removeAllViews()
147+
148+
val itemHeight = context.resources.getDimensionPixelSize(R.dimen.bottom_sheet_item_height)
149+
val standardPadding = context.resources.getDimensionPixelSize(R.dimen.standard_padding)
150+
val iconSize = context.resources.getDimensionPixelSize(R.dimen.iconized_single_line_item_icon_size)
129151

130152
for (creator in directEditing.creators.values) {
131-
val creatorViewBinding =
132-
FileListActionsBottomSheetCreatorBinding.inflate(layoutInflater)
153+
val creatorButton = MaterialButton(
154+
ContextThemeWrapper(
155+
context,
156+
R.style.ThemeOverlay_App_Button_BottomSheetItem
157+
),
158+
null,
159+
com.google.android.material.R.attr.materialButtonStyle
160+
).apply {
161+
id = View.generateViewId()
162+
layoutParams = LinearLayout.LayoutParams(
163+
LinearLayout.LayoutParams.MATCH_PARENT,
164+
itemHeight
165+
)
133166

134-
val creatorView: View = creatorViewBinding.getRoot()
167+
gravity = Gravity.START or Gravity.CENTER_VERTICAL
168+
setPaddingRelative(standardPadding, 0, standardPadding, 0)
135169

136-
creatorViewBinding.creatorName.text = String.format(
137-
fileActivity.getString(R.string.editor_placeholder),
138-
fileActivity.getString(R.string.create_new),
139-
creator.name
140-
)
170+
val buttonText = String.format(
171+
fileActivity.getString(R.string.editor_placeholder),
172+
fileActivity.getString(R.string.create_new),
173+
creator.name
174+
)
175+
text = buttonText
176+
setTextColor(ContextCompat.getColor(context, R.color.text_color))
177+
textSize = 16f
178+
isAllCaps = false
141179

142-
creatorViewBinding.creatorThumbnail.setImageDrawable(
143-
MimeTypeUtil.getFileTypeIcon(
180+
icon = MimeTypeUtil.getFileTypeIcon(
144181
creator.mimetype,
145182
creator.extension,
146-
creatorViewBinding.creatorThumbnail.context,
183+
context,
147184
viewThemeUtils
148185
)
149-
)
150-
151-
creatorView.setOnClickListener {
152-
actions.showTemplate(creator, creatorViewBinding.creatorName.text.toString())
153-
dismiss()
186+
this.iconSize = iconSize
187+
this.iconPadding = standardPadding
188+
iconGravity = MaterialButton.ICON_GRAVITY_START
189+
iconTint = null
190+
191+
setOnClickListener {
192+
actions.showTemplate(creator, buttonText)
193+
dismiss()
194+
}
154195
}
155196

156-
binding.creators.addView(creatorView)
197+
binding.creators.addView(creatorButton)
157198
}
158199
}
159200
}

app/src/main/java/com/owncloud/android/ui/fragment/ProfileBottomSheetDialog.kt

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,33 @@ package com.owncloud.android.ui.fragment
99
import android.content.ActivityNotFoundException
1010
import android.content.DialogInterface
1111
import android.content.Intent
12+
import android.content.res.ColorStateList
1213
import android.graphics.drawable.Drawable
1314
import android.os.Bundle
15+
import android.view.ContextThemeWrapper
16+
import android.view.Gravity
1417
import android.view.View
1518
import android.view.ViewGroup
1619
import android.widget.ImageView
20+
import android.widget.LinearLayout
21+
import androidx.compose.ui.graphics.toArgb
22+
import androidx.core.content.ContextCompat
1723
import androidx.core.content.res.ResourcesCompat
1824
import androidx.core.net.toUri
1925
import androidx.fragment.app.FragmentActivity
2026
import com.google.android.material.bottomsheet.BottomSheetBehavior
2127
import com.google.android.material.bottomsheet.BottomSheetDialog
28+
import com.google.android.material.button.MaterialButton
2229
import com.nextcloud.android.lib.resources.profile.Action
2330
import com.nextcloud.android.lib.resources.profile.HoverCard
2431
import com.nextcloud.client.account.User
2532
import com.owncloud.android.R
26-
import com.owncloud.android.databinding.ProfileBottomSheetActionBinding
2733
import com.owncloud.android.databinding.ProfileBottomSheetFragmentBinding
2834
import com.owncloud.android.utils.DisplayUtils
2935
import com.owncloud.android.utils.theme.ViewThemeUtils
3036

37+
private const val TEXT_SIZE = 16f
38+
3139
/**
3240
* Show actions of an user
3341
*/
@@ -67,39 +75,34 @@ class ProfileBottomSheetDialog(
6775

6876
binding.displayName.text = hoverCard.displayName
6977

70-
for (action in hoverCard.actions) {
71-
val actionBinding = ProfileBottomSheetActionBinding.inflate(
72-
layoutInflater
73-
)
74-
val creatorView: View = actionBinding.root
78+
val itemHeight = context.resources.getDimensionPixelSize(R.dimen.bottom_sheet_item_height)
79+
val standardPadding = context.resources.getDimensionPixelSize(R.dimen.standard_padding)
80+
val iconSize = context.resources.getDimensionPixelSize(R.dimen.iconized_single_line_item_icon_size)
81+
val primaryColor = viewThemeUtils.getColorScheme(context).primary.toArgb()
82+
val textColor = ContextCompat.getColor(context, R.color.text_color)
7583

84+
for (action in hoverCard.actions) {
7685
if (action.appId == "email") {
7786
action.hyperlink = action.title
7887
action.title = context.resources.getString(R.string.write_email)
7988
}
8089

81-
actionBinding.name.text = action.title
82-
83-
val icon = when (action.appId) {
90+
val iconRes = when (action.appId) {
8491
"profile" -> R.drawable.ic_user_outline
8592
"email" -> R.drawable.ic_email
8693
"spreed" -> R.drawable.ic_talk
8794
else -> R.drawable.ic_edit
8895
}
89-
actionBinding.icon.setImageDrawable(
90-
ResourcesCompat.getDrawable(
91-
context.resources,
92-
icon,
93-
null
94-
)
95-
)
96-
viewThemeUtils.platform.tintPrimaryDrawable(context, actionBinding.icon.drawable)
9796

98-
creatorView.setOnClickListener { v: View? ->
99-
send(hoverCard.userId, action)
100-
dismiss()
101-
}
102-
binding.creators.addView(creatorView)
97+
val config = ProfileButtonConfig(
98+
itemHeight = itemHeight,
99+
standardPadding = standardPadding,
100+
textColor = textColor,
101+
iconRes = iconRes,
102+
iconSize = iconSize,
103+
primaryColor = primaryColor
104+
)
105+
binding.creators.addView(createProfileButton(config, action))
103106
}
104107

105108
setOnShowListener { d: DialogInterface? ->
@@ -108,6 +111,32 @@ class ProfileBottomSheetDialog(
108111
}
109112
}
110113

114+
private fun createProfileButton(config: ProfileButtonConfig, action: Action): MaterialButton = MaterialButton(
115+
ContextThemeWrapper(context, R.style.ThemeOverlay_App_Button_BottomSheetItem),
116+
null,
117+
com.google.android.material.R.attr.materialButtonStyle
118+
).apply {
119+
layoutParams = LinearLayout.LayoutParams(
120+
LinearLayout.LayoutParams.MATCH_PARENT,
121+
config.itemHeight
122+
)
123+
gravity = Gravity.START or Gravity.CENTER_VERTICAL
124+
setPaddingRelative(config.standardPadding, 0, config.standardPadding, 0)
125+
text = action.title
126+
setTextColor(config.textColor)
127+
textSize = TEXT_SIZE
128+
isAllCaps = false
129+
icon = ResourcesCompat.getDrawable(context.resources, config.iconRes, null)
130+
this.iconSize = config.iconSize
131+
this.iconPadding = config.standardPadding
132+
iconGravity = MaterialButton.ICON_GRAVITY_START
133+
iconTint = ColorStateList.valueOf(config.primaryColor)
134+
setOnClickListener {
135+
send(hoverCard.userId, action)
136+
dismiss()
137+
}
138+
}
139+
111140
private fun send(userId: String, action: Action) {
112141
when (action.appId) {
113142
"profile" -> openWebsite(action.hyperlink)
@@ -162,4 +191,13 @@ class ProfileBottomSheetDialog(
162191
}
163192
return false
164193
}
194+
195+
private data class ProfileButtonConfig(
196+
val itemHeight: Int,
197+
val standardPadding: Int,
198+
val textColor: Int,
199+
val iconRes: Int,
200+
val iconSize: Int,
201+
val primaryColor: Int
202+
)
165203
}

0 commit comments

Comments
 (0)