mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Profile room: continue working on it (try to get a nice animation) [WIP]
This commit is contained in:
parent
0edc953a23
commit
8aab46804b
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.riotx.core.animations.behavior
|
||||
|
||||
import android.animation.ArgbEvaluator
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
|
||||
import im.vector.riotx.R
|
||||
import kotlin.math.abs
|
||||
|
||||
private const val UNSPECIFIED_INT = Integer.MAX_VALUE
|
||||
private val UNSPECIFIED_FLOAT = Float.MAX_VALUE
|
||||
private const val DEPEND_TYPE_HEIGHT = 0
|
||||
private const val DEPEND_TYPE_WIDTH = 1
|
||||
private const val DEPEND_TYPE_X = 2
|
||||
private const val DEPEND_TYPE_Y = 3
|
||||
|
||||
class PercentViewBehavior<V : View>(context: Context, attrs: AttributeSet) : CoordinatorLayout.Behavior<V>(context, attrs) {
|
||||
|
||||
private var dependType: Int = 0
|
||||
private var dependViewId: Int = 0
|
||||
private var dependTarget: Int = 0
|
||||
private var dependStartX: Int = 0
|
||||
private var dependStartY: Int = 0
|
||||
private var dependStartWidth: Int = 0
|
||||
private var dependStartHeight: Int = 0
|
||||
|
||||
private var startX: Int = 0
|
||||
private var startY: Int = 0
|
||||
private var startWidth: Int = 0
|
||||
private var startHeight: Int = 0
|
||||
private var startBackgroundColor: Int = 0
|
||||
private var startAlpha: Float = 0f
|
||||
private var startRotateX: Float = 0f
|
||||
private var startRotateY: Float = 0f
|
||||
|
||||
private var targetX: Int = 0
|
||||
private var targetY: Int = 0
|
||||
private var targetWidth: Int = 0
|
||||
private var targetHeight: Int = 0
|
||||
private var targetBackgroundColor: Int = 0
|
||||
private var targetAlpha: Float = 0f
|
||||
private var targetRotateX: Float = 0f
|
||||
private var targetRotateY: Float = 0f
|
||||
|
||||
/**
|
||||
* Is the values prepared to be use
|
||||
*/
|
||||
private var isPrepared: Boolean = false
|
||||
|
||||
init {
|
||||
val a = context.obtainStyledAttributes(attrs, R.styleable.PercentViewBehavior)
|
||||
dependViewId = a.getResourceId(R.styleable.PercentViewBehavior_behavior_dependsOn, 0)
|
||||
dependType = a.getInt(R.styleable.PercentViewBehavior_behavior_dependType, DEPEND_TYPE_WIDTH)
|
||||
dependTarget = a.getDimensionPixelOffset(R.styleable.PercentViewBehavior_behavior_dependTarget, UNSPECIFIED_INT)
|
||||
targetX = a.getDimensionPixelOffset(R.styleable.PercentViewBehavior_behavior_targetX, UNSPECIFIED_INT)
|
||||
targetY = a.getDimensionPixelOffset(R.styleable.PercentViewBehavior_behavior_targetY, UNSPECIFIED_INT)
|
||||
targetWidth = a.getDimensionPixelOffset(R.styleable.PercentViewBehavior_behavior_targetWidth, UNSPECIFIED_INT)
|
||||
targetHeight = a.getDimensionPixelOffset(R.styleable.PercentViewBehavior_behavior_targetHeight, UNSPECIFIED_INT)
|
||||
targetBackgroundColor = a.getColor(R.styleable.PercentViewBehavior_behavior_targetBackgroundColor, UNSPECIFIED_INT)
|
||||
targetAlpha = a.getFloat(R.styleable.PercentViewBehavior_behavior_targetAlpha, UNSPECIFIED_FLOAT)
|
||||
targetRotateX = a.getFloat(R.styleable.PercentViewBehavior_behavior_targetRotateX, UNSPECIFIED_FLOAT)
|
||||
targetRotateY = a.getFloat(R.styleable.PercentViewBehavior_behavior_targetRotateY, UNSPECIFIED_FLOAT)
|
||||
a.recycle()
|
||||
}
|
||||
|
||||
private fun prepare(parent: CoordinatorLayout, child: View, dependency: View) {
|
||||
dependStartX = dependency.x.toInt()
|
||||
dependStartY = dependency.y.toInt()
|
||||
dependStartWidth = dependency.width
|
||||
dependStartHeight = dependency.height
|
||||
startX = child.x.toInt()
|
||||
startY = child.y.toInt()
|
||||
startWidth = child.width
|
||||
startHeight = child.height
|
||||
startAlpha = child.alpha
|
||||
startRotateX = child.rotationX
|
||||
startRotateY = child.rotationY
|
||||
|
||||
// only set the start background color when the background is color drawable
|
||||
val background = child.background
|
||||
if (background is ColorDrawable) {
|
||||
startBackgroundColor = background.color
|
||||
}
|
||||
|
||||
// if parent fitsSystemWindows is true, add status bar height to target y if specified
|
||||
if (parent.fitsSystemWindows && targetY != UNSPECIFIED_INT) {
|
||||
var result = 0
|
||||
val resources = parent.context.resources
|
||||
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
|
||||
if (resourceId > 0) {
|
||||
result = resources.getDimensionPixelSize(resourceId)
|
||||
}
|
||||
targetY += result
|
||||
}
|
||||
isPrepared = true
|
||||
}
|
||||
|
||||
override fun layoutDependsOn(parent: CoordinatorLayout, child: V, dependency: View): Boolean {
|
||||
return dependency.id == dependViewId
|
||||
}
|
||||
|
||||
override fun onDependentViewChanged(parent: CoordinatorLayout, child: V, dependency: View): Boolean {
|
||||
// first time, prepare values before continue
|
||||
if (!isPrepared) {
|
||||
prepare(parent, child, dependency)
|
||||
}
|
||||
updateView(child, dependency)
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onLayoutChild(parent: CoordinatorLayout, child: V, layoutDirection: Int): Boolean {
|
||||
val bool = super.onLayoutChild(parent, child, layoutDirection)
|
||||
if (isPrepared) {
|
||||
updateView(child, parent.getDependencies(child)[0])
|
||||
}
|
||||
return bool
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the child view from the dependency states
|
||||
*
|
||||
* @param child child view
|
||||
* @param dependency dependency view
|
||||
*/
|
||||
private fun updateView(child: V, dependency: View) {
|
||||
var percent = 0f
|
||||
var start = 0f
|
||||
var current = 0f
|
||||
var end = UNSPECIFIED_INT.toFloat()
|
||||
when (dependType) {
|
||||
DEPEND_TYPE_WIDTH -> {
|
||||
start = dependStartWidth.toFloat()
|
||||
current = dependency.width.toFloat()
|
||||
end = dependTarget.toFloat()
|
||||
}
|
||||
DEPEND_TYPE_HEIGHT -> {
|
||||
start = dependStartHeight.toFloat()
|
||||
current = dependency.height.toFloat()
|
||||
end = dependTarget.toFloat()
|
||||
}
|
||||
DEPEND_TYPE_X -> {
|
||||
start = dependStartX.toFloat()
|
||||
current = dependency.x
|
||||
end = dependTarget.toFloat()
|
||||
}
|
||||
DEPEND_TYPE_Y -> {
|
||||
start = dependStartY.toFloat()
|
||||
current = dependency.y
|
||||
end = dependTarget.toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
// need to define target value according to the depend type, if not then skip
|
||||
if (end != UNSPECIFIED_INT.toFloat()) {
|
||||
percent = abs(current - start) / abs(end - start)
|
||||
}
|
||||
updateViewWithPercent(child, if (percent > 1f) 1f else percent)
|
||||
}
|
||||
|
||||
private fun updateViewWithPercent(child: View, percent: Float) {
|
||||
var newX = if (targetX == UNSPECIFIED_INT) 0f else (targetX - startX) * percent
|
||||
var newY = if (targetY == UNSPECIFIED_INT) 0f else (targetY - startY) * percent
|
||||
|
||||
// set scale
|
||||
if (targetWidth != UNSPECIFIED_INT) {
|
||||
val newWidth = startWidth + (targetWidth - startWidth) * percent
|
||||
child.scaleX = newWidth / startWidth
|
||||
newX -= (startWidth - newWidth) / 2
|
||||
}
|
||||
if (targetHeight != UNSPECIFIED_INT) {
|
||||
val newHeight = startHeight + (targetHeight - startHeight) * percent
|
||||
child.scaleY = newHeight / startHeight
|
||||
newY -= (startHeight - newHeight) / 2
|
||||
}
|
||||
|
||||
// set new position
|
||||
child.translationX = newX
|
||||
child.translationY = newY
|
||||
|
||||
// set alpha
|
||||
if (targetAlpha != UNSPECIFIED_FLOAT) {
|
||||
child.alpha = startAlpha + (targetAlpha - startAlpha) * percent
|
||||
}
|
||||
|
||||
// set background color
|
||||
if (targetBackgroundColor != UNSPECIFIED_INT && startBackgroundColor != 0) {
|
||||
val evaluator = ArgbEvaluator()
|
||||
val color = evaluator.evaluate(percent, startBackgroundColor, targetBackgroundColor) as Int
|
||||
child.setBackgroundColor(color)
|
||||
}
|
||||
|
||||
// set rotation
|
||||
if (targetRotateX != UNSPECIFIED_FLOAT) {
|
||||
child.rotationX = startRotateX + (targetRotateX - startRotateX) * percent
|
||||
}
|
||||
if (targetRotateY != UNSPECIFIED_FLOAT) {
|
||||
child.rotationY = startRotateY + (targetRotateY - startRotateY) * percent
|
||||
}
|
||||
|
||||
child.requestLayout()
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
|
||||
package im.vector.riotx.core.epoxy.profiles
|
||||
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.isVisible
|
||||
@ -37,9 +38,12 @@ abstract class ProfileItemAction : VectorEpoxyModel<ProfileItemAction.Holder>()
|
||||
var iconRes: Int = 0
|
||||
@EpoxyAttribute
|
||||
var editable: Boolean = true
|
||||
@EpoxyAttribute
|
||||
lateinit var listener: View.OnClickListener
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.view.setOnClickListener(listener)
|
||||
holder.editable.isVisible = editable
|
||||
holder.title.text = title
|
||||
holder.subtitle.setTextOrHide(subtitle)
|
||||
|
@ -332,12 +332,10 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
|
||||
*/
|
||||
protected fun configureToolbar(toolbar: Toolbar, displayBack: Boolean = true) {
|
||||
setSupportActionBar(toolbar)
|
||||
|
||||
if (displayBack) {
|
||||
supportActionBar?.let {
|
||||
it.setDisplayShowHomeEnabled(true)
|
||||
it.setDisplayHomeAsUpEnabled(true)
|
||||
}
|
||||
supportActionBar?.let {
|
||||
it.setDisplayShowHomeEnabled(displayBack)
|
||||
it.setDisplayHomeAsUpEnabled(displayBack)
|
||||
it.title = null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,29 +22,49 @@ import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.dividerItem
|
||||
import im.vector.riotx.core.epoxy.profiles.profileItemAction
|
||||
import im.vector.riotx.core.epoxy.profiles.profileItemSection
|
||||
import im.vector.riotx.core.resources.StringProvider
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomProfileController @Inject constructor()
|
||||
class RoomProfileController @Inject constructor(private val stringProvider: StringProvider)
|
||||
: TypedEpoxyController<RoomProfileViewState>() {
|
||||
|
||||
var callback: Callback? = null
|
||||
|
||||
interface Callback {
|
||||
fun onLearnMoreClicked()
|
||||
fun onMemberListClicked()
|
||||
fun onSettingsClicked()
|
||||
}
|
||||
|
||||
override fun buildModels(data: RoomProfileViewState?) {
|
||||
if (data == null) {
|
||||
return
|
||||
}
|
||||
|
||||
val roomSummary = data.roomSummary()
|
||||
|
||||
profileItemSection {
|
||||
id("section_security")
|
||||
title("Security")
|
||||
}
|
||||
|
||||
|
||||
val learnMoreSubtitle = if (data.isEncrypted) {
|
||||
R.string.room_profile_encrypted_subtitle
|
||||
} else {
|
||||
R.string.room_profile_not_encrypted_subtitle
|
||||
}
|
||||
profileItemAction {
|
||||
id("action_learn_more")
|
||||
title("Learn more")
|
||||
editable(true)
|
||||
subtitle("Messages in this room are not end-to-end encrypted.")
|
||||
subtitle(stringProvider.getString(learnMoreSubtitle))
|
||||
listener { _ ->
|
||||
callback?.onLearnMoreClicked()
|
||||
}
|
||||
}
|
||||
|
||||
dividerItem{
|
||||
dividerItem {
|
||||
id("action_learn_more_divider")
|
||||
}
|
||||
|
||||
@ -53,33 +73,29 @@ class RoomProfileController @Inject constructor()
|
||||
title("Options")
|
||||
}
|
||||
|
||||
val numberOfMembers = (roomSummary?.otherMemberIds?.size ?: 0) + 1
|
||||
profileItemAction {
|
||||
iconRes(R.drawable.ic_person_outline_black)
|
||||
id("action_member_list")
|
||||
title("88 people")
|
||||
title(stringProvider.getString(R.string.room_profile_member_list_title, numberOfMembers))
|
||||
editable(true)
|
||||
listener { _ ->
|
||||
callback?.onMemberListClicked()
|
||||
}
|
||||
}
|
||||
|
||||
dividerItem{
|
||||
dividerItem {
|
||||
id("action_member_list_divider")
|
||||
}
|
||||
|
||||
profileItemAction {
|
||||
iconRes(R.drawable.ic_attachment)
|
||||
id("action_files")
|
||||
title("12 files")
|
||||
editable(true)
|
||||
}
|
||||
|
||||
dividerItem{
|
||||
id("action_files_divider")
|
||||
}
|
||||
|
||||
profileItemAction {
|
||||
iconRes(R.drawable.ic_settings_x)
|
||||
iconRes(R.drawable.ic_room_actions_settings)
|
||||
id("action_settings")
|
||||
title("Room settings")
|
||||
editable(true)
|
||||
listener { _ ->
|
||||
callback?.onSettingsClicked()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class RoomProfileFragment @Inject constructor(
|
||||
private val roomProfileController: RoomProfileController,
|
||||
private val avatarRenderer: AvatarRenderer,
|
||||
val roomProfileViewModelFactory: RoomProfileViewModel.Factory
|
||||
) : VectorBaseFragment() {
|
||||
) : VectorBaseFragment(), RoomProfileController.Callback {
|
||||
|
||||
private val roomProfileArgs: RoomProfileArgs by args()
|
||||
private val roomProfileViewModel: RoomProfileViewModel by fragmentViewModel()
|
||||
@ -57,9 +57,11 @@ class RoomProfileFragment @Inject constructor(
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
roomProfileController.callback = this
|
||||
roomProfileRecyclerView.setHasFixedSize(true)
|
||||
roomProfileRecyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false)
|
||||
roomProfileRecyclerView.adapter = roomProfileController.adapter
|
||||
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
@ -74,6 +76,7 @@ class RoomProfileFragment @Inject constructor(
|
||||
activity?.finish()
|
||||
} else {
|
||||
roomProfileNameView.text = it.displayName
|
||||
roomProfileNameView2.text = it.displayName
|
||||
roomProfileIdView.text = it.roomId
|
||||
roomProfileTopicView.setTextOrHide(it.topic)
|
||||
avatarRenderer.render(it, roomProfileAvatarView)
|
||||
@ -82,5 +85,19 @@ class RoomProfileFragment @Inject constructor(
|
||||
roomProfileController.setData(state)
|
||||
}
|
||||
|
||||
// RoomProfileController.Callback
|
||||
|
||||
override fun onLearnMoreClicked() {
|
||||
vectorBaseActivity.notImplemented()
|
||||
}
|
||||
|
||||
override fun onMemberListClicked() {
|
||||
vectorBaseActivity.notImplemented("Room member list")
|
||||
}
|
||||
|
||||
override fun onSettingsClicked() {
|
||||
vectorBaseActivity.notImplemented("Room settings")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -55,7 +55,10 @@ class RoomProfileViewModel @AssistedInject constructor(@Assisted initialState: R
|
||||
room.rx().liveRoomSummary()
|
||||
.unwrap()
|
||||
.execute {
|
||||
copy(roomSummary = it)
|
||||
copy(
|
||||
roomSummary = it,
|
||||
isEncrypted = room.isEncrypted()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,8 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
|
||||
data class RoomProfileViewState(
|
||||
val roomId: String,
|
||||
val roomSummary: Async<RoomSummary> = Uninitialized
|
||||
val roomSummary: Async<RoomSummary> = Uninitialized,
|
||||
val isEncrypted: Boolean = false
|
||||
) : MvRxState {
|
||||
|
||||
constructor(args: RoomProfileArgs) : this(roomId = args.roomId)
|
||||
|
@ -7,49 +7,40 @@
|
||||
android:background="?riotx_header_panel_background">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
style="@style/VectorAppBarLayoutStyle"
|
||||
android:id="@+id/roomProfileAppBarLayout"
|
||||
style="@style/VectorAppBarLayoutStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
style="@style/VectorAppBarLayoutStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed"
|
||||
app:titleEnabled="false">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/roomProfileToolbar"
|
||||
style="@style/VectorToolbarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:layout_collapseMode="pin" />
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
|
||||
app:titleEnabled="false"
|
||||
app:toolbarId="@+id/roomProfileToolbar">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/roomProfileHeaderView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?riotx_background"
|
||||
android:orientation="vertical"
|
||||
app:layout_collapseMode="parallax">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomProfileAvatarView"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp"
|
||||
android:src="@drawable/ic_person_outline_black" />
|
||||
android:paddingTop="160dp"
|
||||
android:minHeight="280dp"
|
||||
app:layout_collapseMode="parallax"
|
||||
app:layout_collapseParallaxMultiplier="0.9">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomProfileNameView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center_vertical"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/Vector.Toolbar.Title"
|
||||
android:textStyle="bold"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="Random" />
|
||||
|
||||
<TextView
|
||||
@ -77,12 +68,14 @@
|
||||
android:textStyle="normal"
|
||||
tools:text="Here is a room topic, it can be multi-line but should always be displayed in full 🍱" />
|
||||
|
||||
<Space
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="24dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/roomProfileToolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:layout_collapseMode="pin" />
|
||||
|
||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||
|
||||
|
||||
@ -92,7 +85,42 @@
|
||||
android:id="@+id/roomProfileRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:listitem="@layout/item_profile_action" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomProfileAvatarView"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp"
|
||||
android:elevation="10dp"
|
||||
app:behavior_dependTarget="-176dp"
|
||||
app:behavior_dependType="y"
|
||||
app:behavior_dependsOn="@id/roomProfileAppBarLayout"
|
||||
app:behavior_targetHeight="40dp"
|
||||
app:behavior_targetWidth="40dp"
|
||||
app:behavior_targetX="56dp"
|
||||
app:behavior_targetY="8dp"
|
||||
app:layout_behavior="im.vector.riotx.core.animations.behavior.PercentViewBehavior"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomProfileNameView2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:layout_marginStart="104dp"
|
||||
android:layout_marginTop="-100dp"
|
||||
android:alpha="0"
|
||||
android:elevation="10dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textAppearance="@style/Vector.Toolbar.Title"
|
||||
android:textSize="18dp"
|
||||
app:behavior_dependTarget="-208dp"
|
||||
app:behavior_dependType="y"
|
||||
app:behavior_dependsOn="@id/roomProfileAppBarLayout"
|
||||
app:behavior_targetAlpha="1"
|
||||
app:behavior_targetY="0dp"
|
||||
app:layout_behavior="im.vector.riotx.core.animations.behavior.PercentViewBehavior" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
@ -25,8 +25,8 @@
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="16dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@drawable/ic_room_actions_notifications_all" />
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/actionTitle"
|
||||
@ -45,7 +45,7 @@
|
||||
app:layout_constraintBottom_toTopOf="@+id/actionSubtitle"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_default="wrap"
|
||||
tools:text="zbla azjazj" />
|
||||
tools:text="Learn more" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/actionSubtitle"
|
||||
@ -64,7 +64,7 @@
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintTop_toBottomOf="@id/actionTitle"
|
||||
app:layout_constraintWidth_default="wrap"
|
||||
tools:text="zbla azjazj sdqkqsdkqsd sdqkqsdkqsdk kqdkqsdqk" />
|
||||
tools:text="Messages in this room are not end-to-end encrypted" />
|
||||
|
||||
|
||||
<ImageView
|
||||
|
23
vector/src/main/res/values/attr_behavior.xml
Normal file
23
vector/src/main/res/values/attr_behavior.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="PercentViewBehavior">
|
||||
<attr name="behavior_dependsOn" format="reference" />
|
||||
<attr name="behavior_dependType">
|
||||
<enum name="height" value="0" />
|
||||
<enum name="width" value="1" />
|
||||
<enum name="x" value="2" />
|
||||
<enum name="y" value="3" />
|
||||
</attr>
|
||||
|
||||
<attr name="behavior_dependTarget" format="dimension" />
|
||||
|
||||
<attr name="behavior_targetX" format="dimension" />
|
||||
<attr name="behavior_targetY" format="dimension" />
|
||||
<attr name="behavior_targetWidth" format="dimension" />
|
||||
<attr name="behavior_targetHeight" format="dimension" />
|
||||
<attr name="behavior_targetBackgroundColor" format="color" />
|
||||
<attr name="behavior_targetAlpha" format="float" />
|
||||
<attr name="behavior_targetRotateX" format="float" />
|
||||
<attr name="behavior_targetRotateY" format="float" />
|
||||
</declare-styleable>
|
||||
</resources>
|
@ -19,4 +19,8 @@
|
||||
|
||||
<string name="help_long_click_on_room_for_more_options">Long click on a room to see more options</string>
|
||||
|
||||
<string name="room_profile_not_encrypted_subtitle">Messages in this room are not end-to-end encrypted.</string>
|
||||
<string name="room_profile_encrypted_subtitle">Messages in this room are end-to-end encrypted.</string>
|
||||
<string name="room_profile_member_list_title">"%1$d people"</string>
|
||||
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user