fix #379, add search at Select Contacts screen
This commit is contained in:
parent
bc4013a221
commit
9d63d03d20
|
@ -118,7 +118,34 @@ class SelectContactActivity : SimpleActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onSearchQueryChanged(text: String) {
|
private fun onSearchQueryChanged(text: String) {
|
||||||
|
val adapter = select_contact_list.adapter
|
||||||
|
if (adapter != null && adapter is SelectContactsAdapter) {
|
||||||
|
val shouldNormalize = text.normalizeString() == text
|
||||||
|
val filtered = contactsIgnoringSearch.filter {
|
||||||
|
getProperText(it.getNameToDisplay(), shouldNormalize).contains(text, true) ||
|
||||||
|
getProperText(it.nickname, shouldNormalize).contains(text, true) ||
|
||||||
|
it.doesContainPhoneNumber(text, false) ||
|
||||||
|
it.emails.any { it.value.contains(text, true) } ||
|
||||||
|
it.addresses.any { getProperText(it.value, shouldNormalize).contains(text, true) } ||
|
||||||
|
it.IMs.any { it.value.contains(text, true) } ||
|
||||||
|
getProperText(it.notes, shouldNormalize).contains(text, true) ||
|
||||||
|
getProperText(it.organization.company, shouldNormalize).contains(text, true) ||
|
||||||
|
getProperText(it.organization.jobPosition, shouldNormalize).contains(text, true) ||
|
||||||
|
it.websites.any { it.contains(text, true) }
|
||||||
|
} as ArrayList
|
||||||
|
|
||||||
|
filtered.sortBy {
|
||||||
|
val nameToDisplay = it.getNameToDisplay()
|
||||||
|
!getProperText(nameToDisplay, shouldNormalize).startsWith(text, true) && !nameToDisplay.contains(text, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filtered.isEmpty()) {
|
||||||
|
select_contact_placeholder.text = getString(R.string.no_items_found)
|
||||||
|
}
|
||||||
|
|
||||||
|
select_contact_placeholder.beVisibleIf(filtered.isEmpty())
|
||||||
|
adapter.updateItems(filtered, text.normalizeString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onSearchOpened() {
|
private fun onSearchOpened() {
|
||||||
|
@ -126,9 +153,11 @@ class SelectContactActivity : SimpleActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onSearchClosed() {
|
private fun onSearchClosed() {
|
||||||
|
(select_contact_list.adapter as? SelectContactsAdapter)?.updateItems(contactsIgnoringSearch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getProperText(text: String, shouldNormalize: Boolean) = if (shouldNormalize) text.normalizeString() else text
|
||||||
|
|
||||||
private fun showSortingDialog() {
|
private fun showSortingDialog() {
|
||||||
ChangeSortingDialog(this) {
|
ChangeSortingDialog(this) {
|
||||||
initContacts()
|
initContacts()
|
||||||
|
@ -165,7 +194,7 @@ class SelectContactActivity : SimpleActivity() {
|
||||||
|
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
updatePlaceholderVisibility(contacts)
|
updatePlaceholderVisibility(contacts)
|
||||||
SelectContactsAdapter(this, contacts, ArrayList(), false, select_contact_list) {
|
SelectContactsAdapter(this, contacts, ArrayList(), false, select_contact_list, select_contact_fastscroller) {
|
||||||
confirmSelection(it)
|
confirmSelection(it)
|
||||||
}.apply {
|
}.apply {
|
||||||
select_contact_list.adapter = this
|
select_contact_list.adapter = this
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package com.simplemobiletools.contacts.pro.adapters
|
package com.simplemobiletools.contacts.pro.adapters
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.telephony.PhoneNumberUtils
|
||||||
|
import android.text.Spannable
|
||||||
|
import android.text.SpannableString
|
||||||
|
import android.text.style.ForegroundColorSpan
|
||||||
import android.util.SparseArray
|
import android.util.SparseArray
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -13,6 +17,8 @@ import com.bumptech.glide.signature.ObjectKey
|
||||||
import com.simplemobiletools.commons.extensions.beVisibleIf
|
import com.simplemobiletools.commons.extensions.beVisibleIf
|
||||||
import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor
|
import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor
|
||||||
import com.simplemobiletools.commons.extensions.getColoredDrawableWithColor
|
import com.simplemobiletools.commons.extensions.getColoredDrawableWithColor
|
||||||
|
import com.simplemobiletools.commons.extensions.highlightTextPart
|
||||||
|
import com.simplemobiletools.commons.views.FastScroller
|
||||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||||
import com.simplemobiletools.contacts.pro.R
|
import com.simplemobiletools.contacts.pro.R
|
||||||
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
|
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
|
||||||
|
@ -22,15 +28,19 @@ import com.simplemobiletools.contacts.pro.models.Contact
|
||||||
import kotlinx.android.synthetic.main.item_add_favorite_with_number.view.*
|
import kotlinx.android.synthetic.main.item_add_favorite_with_number.view.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class SelectContactsAdapter(val activity: SimpleActivity, val contacts: ArrayList<Contact>, private val selectedContacts: ArrayList<Contact>, private val allowPickMultiple: Boolean,
|
class SelectContactsAdapter(val activity: SimpleActivity, var contacts: ArrayList<Contact>, private val selectedContacts: ArrayList<Contact>, private val allowPickMultiple: Boolean,
|
||||||
private val recyclerView: MyRecyclerView, private val itemClick: ((Contact) -> Unit)? = null) : RecyclerView.Adapter<SelectContactsAdapter.ViewHolder>() {
|
recyclerView: MyRecyclerView, val fastScroller: FastScroller, private val itemClick: ((Contact) -> Unit)? = null) :
|
||||||
|
RecyclerView.Adapter<SelectContactsAdapter.ViewHolder>() {
|
||||||
private val itemViews = SparseArray<View>()
|
private val itemViews = SparseArray<View>()
|
||||||
private val selectedPositions = HashSet<Int>()
|
private val selectedPositions = HashSet<Int>()
|
||||||
private val config = activity.config
|
private val config = activity.config
|
||||||
private val textColor = config.textColor
|
private val textColor = config.textColor
|
||||||
|
private val adjustedPrimaryColor = activity.getAdjustedPrimaryColor()
|
||||||
|
|
||||||
private val contactDrawable = activity.resources.getColoredDrawableWithColor(R.drawable.ic_person_vector, textColor)
|
private val contactDrawable = activity.resources.getColoredDrawableWithColor(R.drawable.ic_person_vector, textColor)
|
||||||
private val showContactThumbnails = config.showContactThumbnails
|
private val showContactThumbnails = config.showContactThumbnails
|
||||||
private val itemLayout = if (config.showPhoneNumbers) R.layout.item_add_favorite_with_number else R.layout.item_add_favorite_without_number
|
private val itemLayout = if (config.showPhoneNumbers) R.layout.item_add_favorite_with_number else R.layout.item_add_favorite_without_number
|
||||||
|
private var textToHighlight = ""
|
||||||
|
|
||||||
private var smallPadding = activity.resources.getDimension(R.dimen.small_margin).toInt()
|
private var smallPadding = activity.resources.getDimension(R.dimen.small_margin).toInt()
|
||||||
private var bigPadding = activity.resources.getDimension(R.dimen.normal_margin).toInt()
|
private var bigPadding = activity.resources.getDimension(R.dimen.normal_margin).toInt()
|
||||||
|
@ -78,6 +88,25 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: ArrayLis
|
||||||
|
|
||||||
override fun getItemCount() = contacts.size
|
override fun getItemCount() = contacts.size
|
||||||
|
|
||||||
|
fun updateItems(newItems: ArrayList<Contact>, highlightText: String = "") {
|
||||||
|
if (newItems.hashCode() != contacts.hashCode()) {
|
||||||
|
contacts = newItems.clone() as ArrayList<Contact>
|
||||||
|
textToHighlight = highlightText
|
||||||
|
notifyDataSetChanged()
|
||||||
|
} else if (textToHighlight != highlightText) {
|
||||||
|
textToHighlight = highlightText
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
fastScroller.measureRecyclerView()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewRecycled(holder: ViewHolder) {
|
||||||
|
super.onViewRecycled(holder)
|
||||||
|
if (!activity.isDestroyed && !activity.isFinishing) {
|
||||||
|
Glide.with(activity).clear(holder.itemView.contact_tmb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
fun bindView(contact: Contact, contactDrawable: Drawable, config: Config, showContactThumbnails: Boolean,
|
fun bindView(contact: Contact, contactDrawable: Drawable, config: Config, showContactThumbnails: Boolean,
|
||||||
smallPadding: Int, bigPadding: Int): View {
|
smallPadding: Int, bigPadding: Int): View {
|
||||||
|
@ -86,13 +115,30 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: ArrayLis
|
||||||
contact_checkbox.setColors(config.textColor, context.getAdjustedPrimaryColor(), config.backgroundColor)
|
contact_checkbox.setColors(config.textColor, context.getAdjustedPrimaryColor(), config.backgroundColor)
|
||||||
val textColor = config.textColor
|
val textColor = config.textColor
|
||||||
|
|
||||||
contact_name.text = contact.getNameToDisplay()
|
val fullName = contact.getNameToDisplay()
|
||||||
|
contact_name.text = if (textToHighlight.isEmpty()) fullName else {
|
||||||
|
if (fullName.contains(textToHighlight, true)) {
|
||||||
|
fullName.highlightTextPart(textToHighlight, adjustedPrimaryColor)
|
||||||
|
} else {
|
||||||
|
highlightTextFromNumbers(fullName, textToHighlight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
contact_name.setTextColor(textColor)
|
contact_name.setTextColor(textColor)
|
||||||
contact_name.setPadding(if (showContactThumbnails) smallPadding else bigPadding, smallPadding, smallPadding, 0)
|
contact_name.setPadding(if (showContactThumbnails) smallPadding else bigPadding, smallPadding, smallPadding, 0)
|
||||||
|
|
||||||
contact_number?.text = contact.phoneNumbers.firstOrNull()?.value ?: ""
|
if (contact_number != null) {
|
||||||
contact_number?.setTextColor(textColor)
|
val phoneNumberToUse = if (textToHighlight.isEmpty()) {
|
||||||
contact_number?.setPadding(if (showContactThumbnails) smallPadding else bigPadding, 0, smallPadding, 0)
|
contact.phoneNumbers.firstOrNull()
|
||||||
|
} else {
|
||||||
|
contact.phoneNumbers.firstOrNull { it.value.contains(textToHighlight) } ?: contact.phoneNumbers.firstOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
val numberText = phoneNumberToUse?.value ?: ""
|
||||||
|
contact_number.text = if (textToHighlight.isEmpty()) numberText else numberText.highlightTextPart(textToHighlight, adjustedPrimaryColor, false, true)
|
||||||
|
contact_number.setTextColor(textColor)
|
||||||
|
contact_number.setPadding(if (showContactThumbnails) smallPadding else bigPadding, 0, smallPadding, 0)
|
||||||
|
}
|
||||||
|
|
||||||
contact_frame.setOnClickListener {
|
contact_frame.setOnClickListener {
|
||||||
if (itemClick != null) {
|
if (itemClick != null) {
|
||||||
|
@ -128,10 +174,18 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: ArrayLis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewRecycled(holder: ViewHolder) {
|
private fun highlightTextFromNumbers(name: String, textToHighlight: String): SpannableString {
|
||||||
super.onViewRecycled(holder)
|
val spannableString = SpannableString(name)
|
||||||
if (!activity.isDestroyed && !activity.isFinishing) {
|
val digits = PhoneNumberUtils.convertKeypadLettersToDigits(name)
|
||||||
Glide.with(activity).clear(holder.itemView.contact_tmb)
|
if (digits.contains(textToHighlight)) {
|
||||||
|
val startIndex = digits.indexOf(textToHighlight, 0, true)
|
||||||
|
val endIndex = Math.min(startIndex + textToHighlight.length, name.length)
|
||||||
|
try {
|
||||||
|
spannableString.setSpan(ForegroundColorSpan(adjustedPrimaryColor), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_INCLUSIVE)
|
||||||
|
} catch (ignored: IndexOutOfBoundsException) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return spannableString
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ class SelectContactsDialog(val activity: SimpleActivity, initialContacts: ArrayL
|
||||||
|
|
||||||
activity.runOnUiThread {
|
activity.runOnUiThread {
|
||||||
view.apply {
|
view.apply {
|
||||||
select_contact_list.adapter = SelectContactsAdapter(activity, allContacts, initiallySelectedContacts, true, select_contact_list)
|
select_contact_list.adapter = SelectContactsAdapter(activity, allContacts, initiallySelectedContacts, true, select_contact_list, select_contact_fastscroller)
|
||||||
select_contact_fastscroller.allowBubbleDisplay = activity.baseConfig.showInfoBubble
|
select_contact_fastscroller.allowBubbleDisplay = activity.baseConfig.showInfoBubble
|
||||||
select_contact_fastscroller.setViews(select_contact_list) {
|
select_contact_fastscroller.setViews(select_contact_list) {
|
||||||
select_contact_fastscroller.updateBubbleText(allContacts[it].getBubbleText())
|
select_contact_fastscroller.updateBubbleText(allContacts[it].getBubbleText())
|
||||||
|
|
|
@ -12,20 +12,18 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:scrollbars="none"
|
android:scrollbars="none"
|
||||||
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager"/>
|
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" />
|
||||||
|
|
||||||
<com.simplemobiletools.commons.views.FastScroller
|
<com.simplemobiletools.commons.views.FastScroller
|
||||||
android:id="@+id/select_contact_fastscroller"
|
android:id="@+id/select_contact_fastscroller"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignTop="@+id/select_contact_list"
|
||||||
android:layout_alignBottom="@+id/select_contact_list"
|
android:layout_alignBottom="@+id/select_contact_list"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_alignTop="@+id/select_contact_list"
|
|
||||||
android:paddingLeft="@dimen/normal_margin"
|
|
||||||
android:paddingStart="@dimen/normal_margin">
|
android:paddingStart="@dimen/normal_margin">
|
||||||
|
|
||||||
<include layout="@layout/fastscroller_handle_vertical"/>
|
<include layout="@layout/fastscroller_handle_vertical" />
|
||||||
|
|
||||||
</com.simplemobiletools.commons.views.FastScroller>
|
</com.simplemobiletools.commons.views.FastScroller>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
Loading…
Reference in New Issue