Change message list layout for density setting
This commit is contained in:
parent
d2ed96550e
commit
296d331921
7 changed files with 147 additions and 45 deletions
|
@ -2,6 +2,7 @@ package com.fsck.k9.activity
|
|||
|
||||
import com.fsck.k9.K9
|
||||
import com.fsck.k9.SwipeAction
|
||||
import com.fsck.k9.UiDensity
|
||||
import com.fsck.k9.preferences.AppTheme
|
||||
import com.fsck.k9.preferences.GeneralSettingsManager
|
||||
import com.fsck.k9.preferences.SubTheme
|
||||
|
@ -21,6 +22,7 @@ data class MessageListActivityConfig(
|
|||
val contactNameColor: Int,
|
||||
val messageViewTheme: SubTheme,
|
||||
val messageListPreviewLines: Int,
|
||||
val messageListDensity: UiDensity,
|
||||
val splitViewMode: K9.SplitViewMode,
|
||||
val fontSizeMessageListSubject: Int,
|
||||
val fontSizeMessageListSender: Int,
|
||||
|
@ -53,6 +55,7 @@ data class MessageListActivityConfig(
|
|||
contactNameColor = K9.contactNameColor,
|
||||
messageViewTheme = settings.messageViewTheme,
|
||||
messageListPreviewLines = K9.messageListPreviewLines,
|
||||
messageListDensity = K9.messageListDensity,
|
||||
splitViewMode = K9.splitViewMode,
|
||||
fontSizeMessageListSubject = K9.fontSizes.messageListSubject,
|
||||
fontSizeMessageListSender = K9.fontSizes.messageListSender,
|
||||
|
|
|
@ -17,12 +17,16 @@ import android.view.View.OnLongClickListener
|
|||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.DimenRes
|
||||
import androidx.constraintlayout.widget.Guideline
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.NO_POSITION
|
||||
import com.fsck.k9.FontSizes
|
||||
import com.fsck.k9.UiDensity
|
||||
import com.fsck.k9.contacts.ContactPictureLoader
|
||||
import com.fsck.k9.controller.MessageReference
|
||||
import com.fsck.k9.mail.Address
|
||||
|
@ -69,6 +73,16 @@ class MessageListAdapter internal constructor(
|
|||
private val unreadItemBackgroundColor: Int =
|
||||
theme.resolveColorAttribute(R.attr.messageListUnreadItemBackgroundColor)
|
||||
|
||||
private val compactVerticalPadding = res.getDimensionPixelSize(R.dimen.messageListCompactVerticalPadding)
|
||||
private val compactTextViewMarginTop = res.getDimensionPixelSize(R.dimen.messageListCompactTextViewMargin)
|
||||
private val compactLineSpacingMultiplier = res.getFloatCompat(R.dimen.messageListCompactLineSpacingMultiplier)
|
||||
private val defaultVerticalPadding = res.getDimensionPixelSize(R.dimen.messageListDefaultVerticalPadding)
|
||||
private val defaultTextViewMarginTop = res.getDimensionPixelSize(R.dimen.messageListDefaultTextViewMargin)
|
||||
private val defaultLineSpacingMultiplier = res.getFloatCompat(R.dimen.messageListDefaultLineSpacingMultiplier)
|
||||
private val relaxedVerticalPadding = res.getDimensionPixelSize(R.dimen.messageListRelaxedVerticalPadding)
|
||||
private val relaxedTextViewMarginTop = res.getDimensionPixelSize(R.dimen.messageListRelaxedTextViewMargin)
|
||||
private val relaxedLineSpacingMultiplier = res.getFloatCompat(R.dimen.messageListRelaxedLineSpacingMultiplier)
|
||||
|
||||
var messages: List<MessageListItem> = emptyList()
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
set(value) {
|
||||
|
@ -260,9 +274,14 @@ class MessageListAdapter internal constructor(
|
|||
|
||||
val holder = MessageViewHolder(view)
|
||||
|
||||
val contactPictureContainer = view.findViewById<View>(R.id.contact_picture_container)
|
||||
contactPictureContainer.isVisible = appearance.showContactPicture
|
||||
contactPictureContainer.setOnClickListener(contactPictureContainerClickListener)
|
||||
val contactPictureClickArea = view.findViewById<View>(R.id.contact_picture_click_area)
|
||||
if (appearance.showContactPicture) {
|
||||
contactPictureClickArea.setOnClickListener(contactPictureContainerClickListener)
|
||||
} else {
|
||||
contactPictureClickArea.isVisible = false
|
||||
holder.selected.isVisible = false
|
||||
holder.contactPicture.isVisible = false
|
||||
}
|
||||
|
||||
holder.chip.isVisible = appearance.showAccountChip
|
||||
|
||||
|
@ -281,11 +300,43 @@ class MessageListAdapter internal constructor(
|
|||
holder.starClickArea.isVisible = appearance.stars
|
||||
holder.starClickArea.setOnClickListener(starClickListener)
|
||||
|
||||
applyDensityValue(holder, appearance.density)
|
||||
|
||||
view.tag = holder
|
||||
|
||||
return holder
|
||||
}
|
||||
|
||||
private fun applyDensityValue(holder: MessageViewHolder, density: UiDensity) {
|
||||
val verticalPadding: Int
|
||||
val textViewMarginTop: Int
|
||||
val lineSpacingMultiplier: Float
|
||||
when (density) {
|
||||
UiDensity.Compact -> {
|
||||
verticalPadding = compactVerticalPadding
|
||||
textViewMarginTop = compactTextViewMarginTop
|
||||
lineSpacingMultiplier = compactLineSpacingMultiplier
|
||||
}
|
||||
UiDensity.Default -> {
|
||||
verticalPadding = defaultVerticalPadding
|
||||
textViewMarginTop = defaultTextViewMarginTop
|
||||
lineSpacingMultiplier = defaultLineSpacingMultiplier
|
||||
}
|
||||
UiDensity.Relaxed -> {
|
||||
verticalPadding = relaxedVerticalPadding
|
||||
textViewMarginTop = relaxedTextViewMarginTop
|
||||
lineSpacingMultiplier = relaxedLineSpacingMultiplier
|
||||
}
|
||||
}
|
||||
|
||||
holder.itemView.findViewById<Guideline>(R.id.top_guideline).setGuidelineBegin(verticalPadding)
|
||||
holder.itemView.findViewById<Guideline>(R.id.bottom_guideline).setGuidelineEnd(verticalPadding)
|
||||
holder.preview.apply {
|
||||
setMarginTop(textViewMarginTop)
|
||||
setLineSpacing(lineSpacingExtra, lineSpacingMultiplier)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFooterViewHolder(parent: ViewGroup): MessageListViewHolder {
|
||||
val view = layoutInflater.inflate(R.layout.message_list_item_footer, parent, false)
|
||||
view.setOnClickListener(footerClickListener)
|
||||
|
@ -537,6 +588,12 @@ class MessageListAdapter internal constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun Resources.getFloatCompat(@DimenRes resId: Int) = ResourcesCompat.getFloat(this, resId)
|
||||
|
||||
private fun View.setMarginTop(margin: Int) {
|
||||
(layoutParams as? ViewGroup.MarginLayoutParams)?.topMargin = margin
|
||||
}
|
||||
|
||||
private class MessageListDiffCallback(
|
||||
private val oldMessageList: List<MessageListItem>,
|
||||
private val newMessageList: List<MessageListItem>,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.fsck.k9.ui.messagelist
|
||||
|
||||
import com.fsck.k9.FontSizes
|
||||
import com.fsck.k9.UiDensity
|
||||
|
||||
data class MessageListAppearance(
|
||||
val fontSizes: FontSizes,
|
||||
|
@ -11,4 +12,5 @@ data class MessageListAppearance(
|
|||
val showingThreadedList: Boolean,
|
||||
val backGroundAsReadIndicator: Boolean,
|
||||
val showAccountChip: Boolean,
|
||||
val density: UiDensity,
|
||||
)
|
||||
|
|
|
@ -573,6 +573,7 @@ class MessageListFragment :
|
|||
showingThreadedList = showingThreadedList,
|
||||
backGroundAsReadIndicator = K9.isUseBackgroundAsUnreadIndicator,
|
||||
showAccountChip = isShowAccountChip,
|
||||
density = K9.messageListDensity,
|
||||
)
|
||||
|
||||
private fun getFolderInfoHolder(folderId: Long, account: Account): FolderInfoHolder {
|
||||
|
|
|
@ -8,54 +8,55 @@
|
|||
|
||||
<Space
|
||||
android:id="@+id/margin_start"
|
||||
android:layout_width="16dp"
|
||||
android:layout_width="@dimen/messageListHorizontalPadding"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/contact_picture_container"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="0dp"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
<ImageView
|
||||
android:id="@+id/selected"
|
||||
android:layout_width="@dimen/messageListContactPictureSize"
|
||||
android:layout_height="@dimen/messageListContactPictureSize"
|
||||
android:layout_marginStart="@dimen/messageListHorizontalPadding"
|
||||
android:layout_marginTop="@dimen/fakeAlignImageTopToTextTopPadding"
|
||||
android:contentDescription="@null"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toTopOf="@+id/bottom_guideline"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
app:layout_constraintTop_toTopOf="@+id/top_guideline"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
app:srcCompat="@drawable/ic_check_circle_large" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/selected"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="top"
|
||||
android:contentDescription="@null"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@drawable/ic_check_circle_large" />
|
||||
|
||||
<de.hdodenhof.circleimageview.CircleImageView
|
||||
android:id="@+id/contact_picture"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="top"
|
||||
android:background="@android:color/transparent"
|
||||
tools:src="@drawable/ic_contact_picture" />
|
||||
|
||||
</FrameLayout>
|
||||
<de.hdodenhof.circleimageview.CircleImageView
|
||||
android:id="@+id/contact_picture"
|
||||
android:layout_width="@dimen/messageListContactPictureSize"
|
||||
android:layout_height="@dimen/messageListContactPictureSize"
|
||||
android:layout_marginStart="@dimen/messageListHorizontalPadding"
|
||||
android:layout_marginTop="@dimen/fakeAlignImageTopToTextTopPadding"
|
||||
android:background="@android:color/transparent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/bottom_guideline"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/top_guideline"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
tools:src="@drawable/ic_contact_picture" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/preview"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:layout_marginTop="@dimen/messageListDefaultTextViewMargin"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:bufferType="spannable"
|
||||
android:lineSpacingMultiplier="@dimen/messageListDefaultLineSpacingMultiplier"
|
||||
android:singleLine="false"
|
||||
android:textAppearance="@style/TextAppearance.K9.Small"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/divider"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/bottom_guideline"
|
||||
app:layout_constraintEnd_toStartOf="@+id/star"
|
||||
app:layout_constraintStart_toEndOf="@+id/barrier_start"
|
||||
app:layout_constraintTop_toTopOf="@+id/barrier_first_line_bottom"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
app:layout_goneMarginEnd="16dp"
|
||||
tools:text="Message preview"
|
||||
app:layout_goneMarginEnd="@dimen/messageListHorizontalPadding"
|
||||
tools:maxLines="2"
|
||||
tools:text="Sender – Message preview text that can span multiple lines. Users can specify in settings how much of that is displayed."
|
||||
tools:textColor="?attr/messageListPreviewTextColor" />
|
||||
|
||||
<ImageView
|
||||
|
@ -76,8 +77,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toEndOf="@+id/barrier_start"
|
||||
app:layout_constraintTop_toTopOf="@+id/top_guideline"
|
||||
app:srcCompat="?attr/messageListAnswered"
|
||||
tools:src="@drawable/ic_messagelist_answered" />
|
||||
app:srcCompat="?attr/messageListAnswered" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subject"
|
||||
|
@ -124,7 +124,7 @@
|
|||
android:id="@+id/date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginEnd="@dimen/messageListHorizontalPadding"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.K9.Small"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
|
@ -136,27 +136,34 @@
|
|||
android:id="@+id/star"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginEnd="14dp"
|
||||
android:layout_marginTop="@dimen/fakeAlignImageTopToTextTopPadding"
|
||||
android:layout_marginEnd="@dimen/messageListHorizontalPadding"
|
||||
android:src="@drawable/btn_select_star"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/bottom_guideline"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/preview"
|
||||
app:layout_constraintVertical_bias="0.0" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/start_keyline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_begin="72dp" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/top_guideline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintGuide_begin="12dp" />
|
||||
app:layout_constraintGuide_begin="@dimen/messageListDefaultVerticalPadding" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/bottom_guideline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintGuide_end="12dp" />
|
||||
app:layout_constraintGuide_end="@dimen/messageListDefaultVerticalPadding" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/barrier_first_line_bottom"
|
||||
|
@ -170,7 +177,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="end"
|
||||
app:constraint_referenced_ids="margin_start,contact_picture_container" />
|
||||
app:constraint_referenced_ids="margin_start,contact_picture_click_area" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
|
@ -179,14 +186,22 @@
|
|||
android:background="?android:attr/listDivider"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/contact_picture_container" />
|
||||
app:layout_constraintStart_toEndOf="@+id/contact_picture_click_area" />
|
||||
|
||||
<View
|
||||
android:id="@+id/star_click_area"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/contact_picture_click_area"
|
||||
android:layout_width="@dimen/messageListStartKeyline"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
@ -13,6 +13,27 @@
|
|||
<dimen name="messageListSwipeIconPadding">24dp</dimen>
|
||||
<dimen name="messageListSwipeTextPadding">12dp</dimen>
|
||||
|
||||
<dimen name="messageListStartKeyline">72dp</dimen>
|
||||
<dimen name="messageListContactPictureSize">40dp</dimen>
|
||||
<dimen name="messageListHorizontalPadding">16dp</dimen>
|
||||
|
||||
<!-- Message list density: compact -->
|
||||
<dimen name="messageListCompactVerticalPadding">4dp</dimen>
|
||||
<dimen name="messageListCompactTextViewMargin">0dp</dimen>
|
||||
<item name="messageListCompactLineSpacingMultiplier" format="float" type="dimen">1.0</item>
|
||||
|
||||
<!-- Message list density: default -->
|
||||
<dimen name="messageListDefaultVerticalPadding">12dp</dimen>
|
||||
<dimen name="messageListDefaultTextViewMargin">2dp</dimen>
|
||||
<item name="messageListDefaultLineSpacingMultiplier" format="float" type="dimen">1.1</item>
|
||||
|
||||
<!-- Message list density: relaxed -->
|
||||
<dimen name="messageListRelaxedTextViewMargin">4dp</dimen>
|
||||
<dimen name="messageListRelaxedVerticalPadding">16dp</dimen>
|
||||
<item name="messageListRelaxedLineSpacingMultiplier" format="float" type="dimen">1.2</item>
|
||||
|
||||
<dimen name="fakeAlignImageTopToTextTopPadding">4dp</dimen>
|
||||
|
||||
<dimen name="floatingActionButtonMargin">16dp</dimen>
|
||||
<!-- Height of ExtendedFloatingActionButton (48dp) plus two times floatingActionButtonMargin -->
|
||||
<dimen name="floatingActionButtonSpacing">80dp</dimen>
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.fsck.k9.FontSizes.FONT_DEFAULT
|
|||
import com.fsck.k9.FontSizes.LARGE
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.TestClock
|
||||
import com.fsck.k9.UiDensity
|
||||
import com.fsck.k9.contacts.ContactPictureLoader
|
||||
import com.fsck.k9.mail.Address
|
||||
import com.fsck.k9.textString
|
||||
|
@ -398,6 +399,7 @@ class MessageListAdapterTest : RobolectricTest() {
|
|||
showingThreadedList: Boolean = true,
|
||||
backGroundAsReadIndicator: Boolean = false,
|
||||
showAccountChip: Boolean = false,
|
||||
density: UiDensity = UiDensity.Default,
|
||||
): MessageListAdapter {
|
||||
val appearance = MessageListAppearance(
|
||||
fontSizes,
|
||||
|
@ -408,6 +410,7 @@ class MessageListAdapterTest : RobolectricTest() {
|
|||
showingThreadedList,
|
||||
backGroundAsReadIndicator,
|
||||
showAccountChip,
|
||||
density,
|
||||
)
|
||||
|
||||
return MessageListAdapter(
|
||||
|
@ -476,7 +479,7 @@ class MessageListAdapterTest : RobolectricTest() {
|
|||
|
||||
val View.accountChipView: View get() = findViewById(R.id.account_color_chip)
|
||||
val View.starView: View get() = findViewById(R.id.star)
|
||||
val View.contactPictureContainerView: View get() = findViewById(R.id.contact_picture_container)
|
||||
val View.contactPictureContainerView: View get() = findViewById(R.id.contact_picture_click_area)
|
||||
val View.threadCountView: TextView get() = findViewById(R.id.thread_count)
|
||||
val View.firstLineView: TextView get() = findViewById(R.id.subject)
|
||||
val View.secondLineView: TextView get() = findViewById(R.id.preview)
|
||||
|
|
Loading…
Reference in a new issue