chinwag-android/app/src/main/res/layout/activity_account.xml
Konrad Pozniak 78152f0449
Full support for Android 15, edge-to-edge mode on Android 15 (#4897)
- Update to Api 35
- Update all dependencies that were blocked because they require Api 35
- fix some deprecation warnings
- implement the now required edge-to-edge mode

Edge-to-edge mode means that we now draw under the status bar and the
navigation bar and need to make sure we don't overlap with them.
Previously the system would do that for us, and we would only provide
the color we want the bars in.

For the edge-to-edge mode there are two Apis that are important:
- `fitsSystemWindows` - some Widgets, mostly from the Material library,
automatically handle system insets if you set this attribute on them to
true
- `ViewCompat.setOnApplyWindowInsetsListener` - this allows you to
manually handle the various insets. By returning new insets from the
callback it is possible to tell the system which ones are handled and
which ones should be taken care of by another view.

In most places edge-to-edge was straightforward to implement, except in
`ComposeActivity`, `AccountActivity` and `MainActivity` which required a
more custom approach, and a hacky solution to make landscape mode work
in `BaseActivity`.

There is also the `ViewCompat.setWindowInsetsAnimationCallback` Api
which allows animating with moving insets. I used that in
`LoginActivity` and `ComposeActivity` to animate the Views together with
the keyboard.

On Android Versions below 15 (Api <= 34) Tusky will look almost the same
as before. I think the only exception is the main bottom bar, which is
now slighty larger. We customized it to be smaller than the default, but
in edge-to-edge mode the height needs to be `wrap_content` or it won't
handle insets correctly.

Screenshots: 

<img
src="https://github.com/user-attachments/assets/2a1bf5d9-79fb-48eb-affc-1cbb1164d5f0"
width="280"/>
<img
src="https://github.com/user-attachments/assets/9edccdf2-c0e9-4881-a6df-bd0872934f28"
width="280"/>
<img
src="https://github.com/user-attachments/assets/2916a271-f53e-4d38-a83a-69083eb3053f"
width="280"/>
2025-02-06 11:37:54 +01:00

495 lines
27 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<com.keylesspalace.tusky.view.TuskySwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/swipeToRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/accountCoordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:textDirection="anyRtl">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/accountAppBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="false">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentScrim="?attr/colorSurface"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:statusBarScrim="?attr/colorSurface"
app:titleEnabled="false">
<ImageView
android:id="@+id/accountHeaderImageView"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_alignTop="@+id/account_header_info"
android:background="?attr/colorPrimaryDark"
android:contentDescription="@string/label_header"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:background="#000" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/accountHeaderInfoContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="180dp"
android:background="?attr/colorSurface"
android:paddingStart="16dp"
android:paddingEnd="16dp">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideAvatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="@dimen/account_activity_avatar_size" />
<Button
android:id="@+id/accountFollowButton"
style="@style/TuskyButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:ellipsize="end"
android:maxLines="1"
android:textSize="?attr/status_text_medium"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/accountMuteButton"
app:layout_constraintTop_toTopOf="parent"
tools:text="Follow Requested" />
<com.google.android.material.button.MaterialButton
android:id="@+id/accountSubscribeButton"
style="@style/TuskyButton.Outlined"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="6dp"
android:minWidth="36dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
app:icon="@drawable/ic_notifications_24dp"
app:iconPadding="0dp"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="@+id/accountFollowButton"
app:layout_constraintEnd_toStartOf="@id/accountFollowButton"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="@id/accountMuteButton"
app:layout_constraintTop_toTopOf="@+id/accountFollowButton" />
<com.google.android.material.button.MaterialButton
android:id="@+id/accountMuteButton"
style="@style/TuskyButton.Outlined"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="6dp"
android:minWidth="36dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
app:icon="@drawable/ic_unmute_24dp"
app:iconPadding="0dp"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="@+id/accountFollowButton"
app:layout_constraintEnd_toStartOf="@id/accountSubscribeButton"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="@id/guideAvatar"
app:layout_constraintTop_toTopOf="@+id/accountFollowButton" />
<TextView
android:id="@+id/accountDisplayNameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="62dp"
android:textColor="?android:textColorPrimary"
android:textSize="?attr/status_text_large"
android:textStyle="normal|bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Tusky Mastodon Client " />
<TextView
android:id="@+id/accountUsernameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textColor="?android:textColorSecondary"
android:textSize="?attr/status_text_medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/accountDisplayNameTextView"
tools:text="\@Tusky" />
<ImageView
android:id="@+id/accountLockedImageView"
android:layout_width="16sp"
android:layout_height="16sp"
android:layout_marginStart="4dp"
android:contentDescription="@string/description_account_locked"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/accountUsernameTextView"
app:layout_constraintStart_toEndOf="@+id/accountUsernameTextView"
app:layout_constraintTop_toTopOf="@+id/accountUsernameTextView"
app:srcCompat="@drawable/ic_reblog_private_24dp"
app:tint="?android:textColorSecondary"
tools:visibility="visible" />
<com.google.android.material.chip.Chip
android:id="@+id/accountFollowsYouTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:clickable="false"
android:focusable="false"
android:minHeight="@dimen/profile_badge_min_height"
android:text="@string/follows_you"
android:textSize="?attr/status_text_small"
android:visibility="gone"
app:chipBackgroundColor="#0000"
app:chipMinHeight="@dimen/profile_badge_min_height"
app:chipStrokeColor="?android:attr/textColorTertiary"
app:chipStrokeWidth="@dimen/profile_badge_stroke_width"
app:closeIconEnabled="false"
app:ensureMinTouchTargetSize="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/accountUsernameTextView"
tools:visibility="visible" />
<com.google.android.material.chip.ChipGroup
android:id="@+id/accountBadgeContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
app:chipSpacingVertical="4dp"
app:layout_constraintStart_toEndOf="@id/accountUsernameTextView"
app:layout_constraintTop_toBottomOf="@id/accountFollowsYouTextView"
app:layout_goneMarginStart="0dp" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/labelBarrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="accountFollowsYouTextView,accountBadgeContainer" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/accountNoteTextInputLayout"
style="@style/TuskyTextInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/labelBarrier"
tools:visibility="visible">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/account_note_hint"
android:textDirection="firstStrong" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/saveNoteInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/account_note_saved"
android:textColor="?attr/colorPrimary"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/accountNoteTextInputLayout" />
<com.keylesspalace.tusky.view.ClickableSpanTextView
android:id="@+id/accountNoteTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hyphenationFrequency="full"
android:lineSpacingMultiplier="1.1"
android:paddingTop="2dp"
android:textColor="?android:textColorTertiary"
android:textDirection="firstStrong"
android:textIsSelectable="true"
android:textSize="?attr/status_text_medium"
app:layout_constraintTop_toBottomOf="@id/saveNoteInfo"
app:layout_goneMarginTop="8dp"
tools:text="This is a test description. Descriptions can be quite looooong." />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/accountFieldList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/accountNoteTextView"
tools:itemCount="2"
tools:listitem="@layout/item_account_field" />
<TextView
android:id="@+id/accountDateJoined"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:textColor="@color/textColorSecondary"
app:layout_constraintBottom_toTopOf="@id/accountRemoveView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/accountFieldList"
tools:text="April, 1971" />
<TextView
android:id="@+id/accountRemoveView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:hyphenationFrequency="full"
android:lineSpacingMultiplier="1.1"
android:text="@string/label_remote_account"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/accountDateJoined"
tools:visibility="visible" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/accountMovedView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/accountRemoveView"
tools:visibility="visible">
<TextView
android:id="@+id/accountMovedText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:drawablePadding="6dp"
android:textSize="?attr/status_text_medium"
app:drawableStartCompat="@drawable/ic_briefcase"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Account has moved" />
<ImageView
android:id="@+id/accountMovedAvatar"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_centerVertical="true"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="8dp"
android:importantForAccessibility="no"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/accountMovedText"
tools:src="@drawable/avatar_default" />
<TextView
android:id="@+id/accountMovedDisplayName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorPrimary"
android:textSize="?attr/status_text_large"
android:textStyle="normal|bold"
app:layout_constraintBottom_toTopOf="@id/accountMovedUsername"
app:layout_constraintStart_toEndOf="@id/accountMovedAvatar"
app:layout_constraintTop_toTopOf="@id/accountMovedAvatar"
tools:text="Display name" />
<TextView
android:id="@+id/accountMovedUsername"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="?attr/status_text_medium"
app:layout_constraintBottom_toBottomOf="@id/accountMovedAvatar"
app:layout_constraintStart_toEndOf="@id/accountMovedAvatar"
app:layout_constraintTop_toBottomOf="@id/accountMovedDisplayName"
tools:text="\@username" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:id="@+id/accountStatuses"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintEnd_toStartOf="@id/accountFollowing"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/accountMovedView">
<TextView
android:id="@+id/accountStatusesTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="sans-serif-medium"
android:textColor="@color/account_tab_font_color"
android:textSize="?attr/status_text_medium"
tools:text="3000" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="6dp"
android:text="@string/title_posts"
android:textColor="@color/account_tab_font_color"
android:textSize="?attr/status_text_medium" />
</LinearLayout>
<LinearLayout
android:id="@+id/accountFollowing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintEnd_toStartOf="@id/accountFollowers"
app:layout_constraintStart_toEndOf="@id/accountStatuses"
app:layout_constraintTop_toBottomOf="@id/accountMovedView">
<TextView
android:id="@+id/accountFollowingTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="sans-serif-medium"
android:textColor="@color/account_tab_font_color"
android:textSize="?attr/status_text_medium"
tools:text="500" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="6dp"
android:text="@string/title_follows"
android:textColor="@color/account_tab_font_color"
android:textSize="?attr/status_text_medium" />
</LinearLayout>
<LinearLayout
android:id="@+id/accountFollowers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/accountFollowing"
app:layout_constraintTop_toBottomOf="@id/accountMovedView">
<TextView
android:id="@+id/accountFollowersTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="sans-serif-medium"
android:textColor="@color/account_tab_font_color"
android:textSize="?attr/status_text_medium"
tools:text="1234" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="6dp"
android:text="@string/title_followers"
android:textColor="@color/account_tab_font_color"
android:textSize="?attr/status_text_medium" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- correct size and color will be set programmatically -->
<View
android:id="@+id/accountStatusBarScrim"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@android:color/transparent"
app:layout_collapseMode="pin" />
<!-- top margin equal to statusbar size will be set programmatically -->
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/accountToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="@android:color/transparent"
app:contentInsetStartWithNavigation="0dp"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/accountTabLayout"
style="@style/TuskyTabAppearance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="center"
app:tabIndicator="@drawable/tab_indicator_top"
app:tabIndicatorFullWidth="true"
app:tabIndicatorHeight="4dp"
app:tabMode="scrollable" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/accountFragmentViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:windowBackground"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/accountFloatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:contentDescription="@string/action_mention"
app:srcCompat="@drawable/ic_create_24dp"
app:tint="?attr/colorOnPrimary" />
<include layout="@layout/item_status_bottom_sheet" />
<ImageView
android:id="@+id/accountAvatarImageView"
android:layout_width="@dimen/account_activity_avatar_size"
android:layout_height="@dimen/account_activity_avatar_size"
android:layout_marginStart="16dp"
android:contentDescription="@string/label_avatar"
android:padding="3dp"
app:layout_anchor="@+id/accountHeaderInfoContainer"
app:layout_anchorGravity="top"
app:layout_scrollFlags="scroll"
app:srcCompat="@drawable/avatar_default" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</com.keylesspalace.tusky.view.TuskySwipeRefreshLayout>