mirror of https://github.com/tasks/tasks
Convert edit screen to use compose scaffold
Remove collapsing toolbar and fabpull/3145/head
parent
82ceda7108
commit
bfcff55854
@ -0,0 +1,106 @@
|
|||||||
|
package org.tasks.compose.edit
|
||||||
|
|
||||||
|
import android.content.Context.INPUT_METHOD_SERVICE
|
||||||
|
import android.graphics.Paint
|
||||||
|
import android.text.InputType
|
||||||
|
import android.util.TypedValue
|
||||||
|
import android.view.View
|
||||||
|
import android.view.inputmethod.EditorInfo
|
||||||
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import android.widget.EditText
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
|
import androidx.core.widget.addTextChangedListener
|
||||||
|
import com.todoroo.andlib.utility.AndroidUtilities
|
||||||
|
import org.tasks.R
|
||||||
|
import org.tasks.dialogs.Linkify
|
||||||
|
import org.tasks.markdown.MarkdownProvider
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun EditTextView(
|
||||||
|
text: String?,
|
||||||
|
hint: String?,
|
||||||
|
onChanged: (CharSequence?) -> Unit,
|
||||||
|
linkify: Linkify?,
|
||||||
|
markdownProvider: MarkdownProvider?,
|
||||||
|
strikethrough: Boolean = false,
|
||||||
|
requestFocus: Boolean = false,
|
||||||
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
var shouldRequestFocus by remember { mutableStateOf(false) }
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
AndroidView(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.padding(end = 16.dp)
|
||||||
|
.focusRequester(focusRequester),
|
||||||
|
factory = { context ->
|
||||||
|
EditText(context).apply {
|
||||||
|
setText(text)
|
||||||
|
val textWatcher =
|
||||||
|
markdownProvider?.markdown(linkify != null)?.textWatcher(this)
|
||||||
|
addTextChangedListener(
|
||||||
|
onTextChanged = { text, _, _, _ -> onChanged(text) },
|
||||||
|
afterTextChanged = { editable -> textWatcher?.invoke(editable) }
|
||||||
|
)
|
||||||
|
setBackgroundColor(context.getColor(android.R.color.transparent))
|
||||||
|
textAlignment = View.TEXT_ALIGNMENT_VIEW_START
|
||||||
|
imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
|
||||||
|
inputType =
|
||||||
|
InputType.TYPE_CLASS_TEXT or
|
||||||
|
InputType.TYPE_TEXT_FLAG_CAP_SENTENCES or
|
||||||
|
InputType.TYPE_TEXT_FLAG_MULTI_LINE or
|
||||||
|
InputType.TYPE_TEXT_FLAG_AUTO_CORRECT
|
||||||
|
isSingleLine = false
|
||||||
|
maxLines = Int.MAX_VALUE
|
||||||
|
if (AndroidUtilities.atLeastOreo()) {
|
||||||
|
importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_NO
|
||||||
|
}
|
||||||
|
isVerticalScrollBarEnabled = true
|
||||||
|
freezesText = true
|
||||||
|
setHorizontallyScrolling(false)
|
||||||
|
isHorizontalScrollBarEnabled = false
|
||||||
|
setHint(hint)
|
||||||
|
setHintTextColor(context.getColor(R.color.text_tertiary))
|
||||||
|
setTextSize(
|
||||||
|
TypedValue.COMPLEX_UNIT_PX,
|
||||||
|
context.resources.getDimension(R.dimen.task_edit_text_size)
|
||||||
|
)
|
||||||
|
linkify?.linkify(this)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
update = { view ->
|
||||||
|
if (shouldRequestFocus) {
|
||||||
|
view.requestFocus()
|
||||||
|
val imm = context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
|
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
|
||||||
|
shouldRequestFocus = false
|
||||||
|
}
|
||||||
|
view.paintFlags = if (strikethrough) {
|
||||||
|
view.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
|
||||||
|
} else {
|
||||||
|
view.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
if (requestFocus) {
|
||||||
|
shouldRequestFocus = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,111 @@
|
|||||||
|
package org.tasks.compose.edit
|
||||||
|
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import org.tasks.R
|
||||||
|
import org.tasks.compose.CheckBox
|
||||||
|
import org.tasks.compose.TaskEditRow
|
||||||
|
import org.tasks.dialogs.Linkify
|
||||||
|
import org.tasks.markdown.MarkdownProvider
|
||||||
|
import org.tasks.themes.TasksTheme
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TitleRow(
|
||||||
|
text: String?,
|
||||||
|
onChanged: (CharSequence?) -> Unit,
|
||||||
|
linkify: Linkify?,
|
||||||
|
markdownProvider: MarkdownProvider?,
|
||||||
|
desaturate: Boolean,
|
||||||
|
isCompleted: Boolean,
|
||||||
|
isRecurring: Boolean,
|
||||||
|
priority: Int,
|
||||||
|
onComplete: () -> Unit,
|
||||||
|
requestFocus: Boolean,
|
||||||
|
) {
|
||||||
|
TaskEditRow(
|
||||||
|
icon = {
|
||||||
|
CheckBox(
|
||||||
|
isCompleted = isCompleted,
|
||||||
|
isRecurring = isRecurring,
|
||||||
|
priority = priority,
|
||||||
|
onCompleteClick = onComplete,
|
||||||
|
desaturate = desaturate,
|
||||||
|
modifier = Modifier.padding(
|
||||||
|
start = 4.dp,
|
||||||
|
end = 20.dp,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
content = {
|
||||||
|
Column(verticalArrangement = Arrangement.Center) {
|
||||||
|
Spacer(modifier = Modifier.height(3.dp))
|
||||||
|
EditTextView(
|
||||||
|
text = text,
|
||||||
|
hint = stringResource(R.string.TEA_title_hint),
|
||||||
|
onChanged = onChanged,
|
||||||
|
linkify = linkify,
|
||||||
|
markdownProvider = markdownProvider,
|
||||||
|
strikethrough = isCompleted,
|
||||||
|
requestFocus = requestFocus,
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(11.dp))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalComposeUiApi
|
||||||
|
@Preview(showBackground = true, widthDp = 320)
|
||||||
|
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
|
||||||
|
@Composable
|
||||||
|
fun EmptyTitlePreview() {
|
||||||
|
TasksTheme {
|
||||||
|
TitleRow(
|
||||||
|
text = null,
|
||||||
|
onChanged = {},
|
||||||
|
linkify = null,
|
||||||
|
markdownProvider = null,
|
||||||
|
desaturate = true,
|
||||||
|
isCompleted = false,
|
||||||
|
isRecurring = false,
|
||||||
|
priority = 0,
|
||||||
|
onComplete = {},
|
||||||
|
requestFocus = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalComposeUiApi
|
||||||
|
@Preview(showBackground = true, widthDp = 320)
|
||||||
|
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
|
||||||
|
@Composable
|
||||||
|
fun TitlePreview() {
|
||||||
|
TasksTheme {
|
||||||
|
TitleRow(
|
||||||
|
text = """
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||||
|
|
||||||
|
Eleifend quam adipiscing vitae proin sagittis. Faucibus a pellentesque sit amet porttitor eget dolor.
|
||||||
|
""".trimIndent(),
|
||||||
|
onChanged = {},
|
||||||
|
linkify = null,
|
||||||
|
markdownProvider = null,
|
||||||
|
desaturate = true,
|
||||||
|
isCompleted = false,
|
||||||
|
isRecurring = false,
|
||||||
|
priority = 0,
|
||||||
|
onComplete = {},
|
||||||
|
requestFocus = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,108 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!--
|
|
||||||
** Copyright (c) 2012 Todoroo Inc
|
|
||||||
**
|
|
||||||
** See the file "LICENSE" for the full license governing this code.
|
|
||||||
-->
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
|
||||||
android:id="@+id/appbarlayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
|
||||||
android:id="@+id/collapsingtoolbarlayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@color/content_background"
|
|
||||||
app:collapsedTitleTextAppearance="?attr/textAppearanceHeadline6"
|
|
||||||
app:expandedTitleGravity="top"
|
|
||||||
app:expandedTitleMarginTop="?attr/actionBarSize"
|
|
||||||
app:expandedTitleMarginStart="@dimen/keyline_first"
|
|
||||||
app:expandedTitleTextAppearance="?attr/textAppearanceHeadline5"
|
|
||||||
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/title"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingTop="?attr/actionBarSize"
|
|
||||||
android:paddingStart="@dimen/keyline_first"
|
|
||||||
android:paddingEnd="@dimen/keyline_first"
|
|
||||||
android:paddingBottom="@dimen/keyline_second"
|
|
||||||
android:layout_gravity="top"
|
|
||||||
android:background="@null"
|
|
||||||
android:gravity="start"
|
|
||||||
android:textAppearance="?attr/textAppearanceHeadline5"
|
|
||||||
android:hint="@string/TEA_title_hint"
|
|
||||||
android:imeOptions="flagNoExtractUi"
|
|
||||||
android:importantForAutofill="no"
|
|
||||||
android:inputType="textCapSentences|textAutoCorrect"
|
|
||||||
android:scrollbars="vertical"
|
|
||||||
android:textAlignment="viewStart" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:elevation="@dimen/elevation_toolbar"
|
|
||||||
android:theme="@style/ToolbarTheme"
|
|
||||||
app:layout_collapseMode="pin"
|
|
||||||
app:navigationIconTint="@color/text_primary"
|
|
||||||
app:toolbarStyle="@style/Widget.MaterialComponents.Toolbar"
|
|
||||||
app:popupTheme="@style/popup_overlay"
|
|
||||||
tools:ignore="UnusedAttribute" />
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
|
||||||
|
|
||||||
<androidx.compose.ui.platform.ComposeView
|
|
||||||
android:id="@+id/banner"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
|
||||||
android:scrollbarStyle="outsideOverlay"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="100"
|
|
||||||
android:elevation="0dp"
|
|
||||||
android:overScrollMode="never">
|
|
||||||
|
|
||||||
<androidx.compose.ui.platform.ComposeView
|
|
||||||
android:id="@+id/compose_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
|
||||||
android:id="@+id/comment_bar"
|
|
||||||
android:name="org.tasks.fragments.CommentBarFragment"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:elevation="8dp"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
||||||
android:id="@+id/fab"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="@dimen/keyline_first"
|
|
||||||
android:src="@drawable/ic_outline_check_box_24px"
|
|
||||||
android:soundEffectsEnabled="false"
|
|
||||||
app:layout_anchor="@id/appbarlayout"
|
|
||||||
app:layout_anchorGravity="bottom|end" />
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/task_edit_comment_bar"
|
||||||
|
android:name="org.tasks.fragments.CommentBarFragment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
@ -1,15 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_discard"
|
|
||||||
android:icon="@drawable/ic_outline_clear_24px"
|
|
||||||
android:title="@string/menu_discard_changes"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_delete"
|
|
||||||
android:icon="@drawable/ic_outline_delete_24px"
|
|
||||||
android:title="@string/delete_task"
|
|
||||||
app:showAsAction="never"/>
|
|
||||||
</menu>
|
|
||||||
Loading…
Reference in New Issue