mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-04-14 19:56:32 +00:00
Allow notes to expand and expand notes edittext. Fixes #1037
This commit is contained in:
parent
81f41f95da
commit
9cf2b1a71b
8 changed files with 201 additions and 65 deletions
|
|
@ -20,9 +20,8 @@
|
|||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="72dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/emoji.toggle.btn0"
|
||||
android:layout_width="48dp"
|
||||
|
|
@ -33,49 +32,49 @@
|
|||
android:focusable="true"
|
||||
android:focusableInTouchMode="true" />
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:hintTextAppearance="@style/TextAppearance.AppCompat">
|
||||
|
||||
<net.pherth.android.emoji_library.EmojiEditText
|
||||
android:id="@+id/task_text_edittext"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:hintTextAppearance="@style/TextAppearance.AppCompat">
|
||||
|
||||
<net.pherth.android.emoji_library.EmojiEditText
|
||||
android:id="@+id/task_text_edittext"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:hint="@string/text"
|
||||
android:textColor="@android:color/black"
|
||||
android:inputType="textCapSentences" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:hint="@string/text"
|
||||
android:textColor="@android:color/black"
|
||||
android:inputType="textCapSentences|textMultiLine"
|
||||
android:maxLines="3"/>
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="72dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/emoji.toggle.btn1"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:src="@drawable/ic_emoticon_grey600_24dp"
|
||||
android:background="@drawable/md_transparent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="Toogle Emoji" />
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="72dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:hintTextAppearance="@style/TextAppearance.AppCompat">
|
||||
|
||||
<net.pherth.android.emoji_library.EmojiEditText
|
||||
android:id="@+id/task_notes_edittext"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:hint="@string/notes"
|
||||
android:textColor="@android:color/black"
|
||||
android:inputType="textCapSentences|textMultiLine" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:hint="@string/notes"
|
||||
android:textColor="@android:color/black"
|
||||
android:inputType="textCapSentences|textMultiLine" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
|
|
@ -145,27 +144,27 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/actions"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/task_positive_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="11dp"
|
||||
android:text="@string/positive_habit_form"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
android:id="@+id/task_positive_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="11dp"
|
||||
android:text="@string/positive_habit_form"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/task_negative_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="11dp"
|
||||
android:text="@string/negative_habit_form"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
<CheckBox
|
||||
android:id="@+id/task_negative_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="11dp"
|
||||
android:text="@string/negative_habit_form"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
@ -403,11 +402,11 @@
|
|||
android:layout_marginTop="20dp"
|
||||
android:id="@+id/task_tags_wrapper">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/tags"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/tags"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -416,7 +415,7 @@
|
|||
android:id="@+id/task_tags_checklist">
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
android:paddingStart="@dimen/task_text_padding"
|
||||
android:paddingTop="@dimen/task_top_bottom_padding">
|
||||
|
||||
<net.pherth.android.emoji_library.EmojiTextView
|
||||
<com.habitrpg.android.habitica.ui.views.EllipsisTextView
|
||||
android:id="@+id/checkedTextView"
|
||||
style="@style/Subheader3"
|
||||
android:textColor="#000"
|
||||
|
|
@ -61,14 +61,22 @@
|
|||
android:layout_height="wrap_content"
|
||||
tools:text="Daily Title" />
|
||||
|
||||
<net.pherth.android.emoji_library.EmojiTextView
|
||||
<com.habitrpg.android.habitica.ui.views.EllipsisTextView
|
||||
android:id="@+id/notesTextView"
|
||||
style="@style/Caption2.Regular"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="3"
|
||||
android:ellipsize="end"
|
||||
tools:text="Notes" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/expand_notes_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
style="@style/Base.Widget.AppCompat.Button.Borderless"
|
||||
android:text="@string/expand_notes"
|
||||
android:padding="0dp"
|
||||
android:textColor="@color/brand_400"/>
|
||||
<TextView
|
||||
android:id="@+id/approvalRequiredTextField"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
android:paddingStart="@dimen/task_text_padding"
|
||||
android:paddingTop="@dimen/task_top_bottom_padding">
|
||||
|
||||
<net.pherth.android.emoji_library.EmojiTextView
|
||||
<com.habitrpg.android.habitica.ui.views.EllipsisTextView
|
||||
android:id="@+id/checkedTextView"
|
||||
style="@style/Subheader3"
|
||||
android:textColor="#000"
|
||||
|
|
@ -62,14 +62,23 @@
|
|||
android:layout_height="wrap_content"
|
||||
tools:text="Habit Title" />
|
||||
|
||||
<net.pherth.android.emoji_library.EmojiTextView
|
||||
<com.habitrpg.android.habitica.ui.views.EllipsisTextView
|
||||
android:id="@+id/notesTextView"
|
||||
style="@style/Caption2.Regular"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="3"
|
||||
android:ellipsize="end"
|
||||
tools:text="Notes"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/expand_notes_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
style="@style/Base.Widget.AppCompat.Button.Borderless"
|
||||
android:text="@string/expand_notes"
|
||||
android:padding="0dp"
|
||||
android:textColor="@color/brand_400"/>
|
||||
<TextView
|
||||
android:id="@+id/approvalRequiredTextField"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
android:paddingRight="@dimen/reward_spacing"
|
||||
android:paddingTop="@dimen/task_top_bottom_padding">
|
||||
|
||||
<net.pherth.android.emoji_library.EmojiTextView
|
||||
<com.habitrpg.android.habitica.ui.views.EllipsisTextView
|
||||
android:id="@+id/checkedTextView"
|
||||
style="@style/Subheader3"
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -41,13 +41,21 @@
|
|||
android:textColor="#000"
|
||||
tools:text="Title" />
|
||||
|
||||
<net.pherth.android.emoji_library.EmojiTextView
|
||||
<com.habitrpg.android.habitica.ui.views.EllipsisTextView
|
||||
android:id="@+id/notesTextView"
|
||||
style="@style/Caption2.Regular"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Notes"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/expand_notes_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
style="@style/Base.Widget.AppCompat.Button.Borderless"
|
||||
android:text="@string/expand_notes"
|
||||
android:padding="0dp"
|
||||
android:textColor="@color/brand_400"/>
|
||||
<TextView
|
||||
android:id="@+id/approvalRequiredTextField"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
android:paddingStart="@dimen/task_text_padding"
|
||||
android:paddingTop="@dimen/task_top_bottom_padding">
|
||||
|
||||
<net.pherth.android.emoji_library.EmojiTextView
|
||||
<com.habitrpg.android.habitica.ui.views.EllipsisTextView
|
||||
android:id="@+id/checkedTextView"
|
||||
style="@style/Subheader3"
|
||||
android:textColor="#000"
|
||||
|
|
@ -61,14 +61,23 @@
|
|||
android:layout_height="wrap_content"
|
||||
tools:text="To-Do Title" />
|
||||
|
||||
<net.pherth.android.emoji_library.EmojiTextView
|
||||
<com.habitrpg.android.habitica.ui.views.EllipsisTextView
|
||||
android:id="@+id/notesTextView"
|
||||
style="@style/Caption2.Regular"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="3"
|
||||
android:ellipsize="end"
|
||||
tools:text="Notes" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/expand_notes_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
style="@style/Base.Widget.AppCompat.Button.Borderless"
|
||||
android:text="@string/expand_notes"
|
||||
android:padding="0dp"
|
||||
android:textColor="@color/brand_400"/>
|
||||
<TextView
|
||||
android:id="@+id/approvalRequiredTextField"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -805,4 +805,6 @@
|
|||
<string name="daily_tip_9">If you\'re having a tough time, try breaking your tasks down into smaller parts.</string>
|
||||
<string name="moderator">Moderator</string>
|
||||
<string name="staff">Staff</string>
|
||||
<string name="expand_notes">Read More</string>
|
||||
<string name="collapse_notes">Show Less</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ package com.habitrpg.android.habitica.ui.viewHolders.tasks
|
|||
|
||||
import android.content.Context
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
|
|
@ -15,6 +17,7 @@ import com.habitrpg.android.habitica.models.tasks.Task
|
|||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindColor
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindOptionalView
|
||||
import com.habitrpg.android.habitica.ui.views.EllipsisTextView
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.functions.Consumer
|
||||
|
|
@ -27,8 +30,8 @@ abstract class BaseTaskViewHolder constructor(itemView: View) : RecyclerView.Vie
|
|||
|
||||
var task: Task? = null
|
||||
protected var context: Context
|
||||
private val titleTextView: EmojiTextView by bindView(itemView, R.id.checkedTextView)
|
||||
private val notesTextView: EmojiTextView by bindView(itemView, R.id.notesTextView)
|
||||
private val titleTextView: EllipsisTextView by bindView(itemView, R.id.checkedTextView)
|
||||
private val notesTextView: EllipsisTextView by bindView(itemView, R.id.notesTextView)
|
||||
internal val rightBorderView: View? by bindOptionalView(itemView, R.id.rightBorderView)
|
||||
protected val specialTaskTextView: TextView? by bindOptionalView(itemView, R.id.specialTaskText)
|
||||
private val iconViewChallenge: ImageView? by bindView(itemView, R.id.iconviewChallenge)
|
||||
|
|
@ -36,10 +39,12 @@ abstract class BaseTaskViewHolder constructor(itemView: View) : RecyclerView.Vie
|
|||
private val iconViewTag: ImageView? by bindView(itemView, R.id.iconviewTag)
|
||||
private val taskIconWrapper: LinearLayout? by bindView(itemView, R.id.taskIconWrapper)
|
||||
private val approvalRequiredTextView: TextView? by bindView(itemView, R.id.approvalRequiredTextField)
|
||||
private val expandNotesButton: Button by bindView(R.id.expand_notes_button)
|
||||
protected val taskGray: Int by bindColor(itemView.context, R.color.task_gray)
|
||||
|
||||
private var openTaskDisabled: Boolean = false
|
||||
private var taskActionsDisabled: Boolean = false
|
||||
private var notesExpanded = false
|
||||
|
||||
protected open val taskIconWrapperIsVisible: Boolean
|
||||
get() {
|
||||
|
|
@ -69,16 +74,47 @@ abstract class BaseTaskViewHolder constructor(itemView: View) : RecyclerView.Vie
|
|||
itemView.isClickable = true
|
||||
|
||||
//Re enable when we find a way to only react when a link is tapped.
|
||||
//notesTextView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
//titleTextView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
//notesTextView.movementMethod = LinkMovementMethod.getInstance()
|
||||
//titleTextView.movementMethod = LinkMovementMethod.getInstance()
|
||||
|
||||
expandNotesButton.setOnClickListener { expandTask() }
|
||||
notesTextView.addEllipsesListener(object : EllipsisTextView.EllipsisListener {
|
||||
override fun ellipsisStateChanged(ellipses: Boolean) {
|
||||
Single.just(ellipses)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(Consumer{ hasEllipses ->
|
||||
expandNotesButton.visibility = if (hasEllipses || notesExpanded) View.VISIBLE else View.GONE
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
|
||||
}
|
||||
})
|
||||
context = itemView.context
|
||||
}
|
||||
|
||||
open fun bindHolder(newTask: Task, position: Int) {
|
||||
private fun expandTask() {
|
||||
notesExpanded = !notesExpanded
|
||||
if (notesExpanded) {
|
||||
notesTextView.maxLines = 100
|
||||
expandNotesButton.text = context.getString(R.string.collapse_notes)
|
||||
} else {
|
||||
notesTextView.maxLines = 3
|
||||
expandNotesButton.text = context.getString(R.string.expand_notes)
|
||||
}
|
||||
}
|
||||
|
||||
open fun bindHolder(newTask: Task, position: Int) {
|
||||
task = newTask
|
||||
itemView.setBackgroundResource(R.color.white)
|
||||
|
||||
if (newTask.notes?.isNotEmpty() == true) {
|
||||
notesTextView.visibility = View.VISIBLE
|
||||
//expandNotesButton.visibility = if (notesTextView.hadEllipses() || notesExpanded) View.VISIBLE else View.GONE
|
||||
} else {
|
||||
notesTextView.visibility = View.GONE
|
||||
expandNotesButton.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (canContainMarkdown()) {
|
||||
if (newTask.parsedText != null) {
|
||||
titleTextView.text = newTask.parsedText
|
||||
|
|
@ -94,8 +130,8 @@ abstract class BaseTaskViewHolder constructor(itemView: View) : RecyclerView.Vie
|
|||
newTask.parsedText = parsedText
|
||||
titleTextView.text = newTask.parsedText
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
newTask.notes.notNull {
|
||||
Single.just(it)
|
||||
newTask.notes.notNull {notes ->
|
||||
Single.just(notes)
|
||||
.map { MarkdownParser.parseMarkdown(it) }
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
|
@ -110,11 +146,6 @@ abstract class BaseTaskViewHolder constructor(itemView: View) : RecyclerView.Vie
|
|||
titleTextView.text = newTask.text
|
||||
notesTextView.text = newTask.notes
|
||||
}
|
||||
if (newTask.notes?.isNotEmpty() == true) {
|
||||
notesTextView.visibility = View.VISIBLE
|
||||
} else {
|
||||
notesTextView.visibility = View.GONE
|
||||
}
|
||||
|
||||
rightBorderView?.setBackgroundResource(newTask.lightTaskColor)
|
||||
iconViewReminder?.visibility = if (newTask.reminders?.size ?: 0 > 0) View.VISIBLE else View.GONE
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
package com.habitrpg.android.habitica.ui.views
|
||||
|
||||
/**
|
||||
* Author: Michael Ritchie, ThanksMister LLC
|
||||
* Date: 10/16/12
|
||||
* Web: thanksmister.com
|
||||
*
|
||||
* Extension of <code>TextView</code> that adds listener for ellipses changes. This can be used to determine
|
||||
* if a TextView has an ellipses or not.
|
||||
*
|
||||
* Derived from discussion on StackOverflow:
|
||||
*
|
||||
* http://stackoverflow.com/questions/4005933/how-do-i-tell-if-my-textview-has-been-ellipsized
|
||||
*/
|
||||
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import net.pherth.android.emoji_library.EmojiTextView
|
||||
|
||||
class EllipsisTextView : EmojiTextView {
|
||||
|
||||
private val ellipsesListeners = ArrayList<EllipsisListener>()
|
||||
|
||||
private var ellipses: Boolean = false
|
||||
|
||||
interface EllipsisListener {
|
||||
fun ellipsisStateChanged(ellipses: Boolean)
|
||||
}
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
|
||||
|
||||
fun addEllipsesListener(listener: EllipsisListener?) {
|
||||
if (listener == null) {
|
||||
throw NullPointerException()
|
||||
}
|
||||
ellipsesListeners.add(listener)
|
||||
}
|
||||
|
||||
fun removeEllipsesListener(listener: EllipsisListener) {
|
||||
ellipsesListeners.remove(listener)
|
||||
}
|
||||
|
||||
fun hadEllipses(): Boolean {
|
||||
return ellipses
|
||||
}
|
||||
|
||||
override fun layout(l: Int, t: Int, r: Int, b: Int) {
|
||||
super.layout(l, t, r, b)
|
||||
|
||||
ellipses = false
|
||||
val layout = layout
|
||||
if (layout != null) {
|
||||
val lines = layout.lineCount
|
||||
if (lines > 0) {
|
||||
if (layout.getEllipsisCount(lines - 1) > 0) {
|
||||
ellipses = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (listener in ellipsesListeners) {
|
||||
listener.ellipsisStateChanged(ellipses)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue