mirror of
				https://github.com/SimpleMobileTools/Simple-Contacts.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	fix #379, add search at Select Contacts screen
This commit is contained in:
		| @@ -118,7 +118,34 @@ class SelectContactActivity : SimpleActivity() { | ||||
|     } | ||||
|  | ||||
|     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() { | ||||
| @@ -126,9 +153,11 @@ class SelectContactActivity : SimpleActivity() { | ||||
|     } | ||||
|  | ||||
|     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() { | ||||
|         ChangeSortingDialog(this) { | ||||
|             initContacts() | ||||
| @@ -165,7 +194,7 @@ class SelectContactActivity : SimpleActivity() { | ||||
|  | ||||
|             runOnUiThread { | ||||
|                 updatePlaceholderVisibility(contacts) | ||||
|                 SelectContactsAdapter(this, contacts, ArrayList(), false, select_contact_list) { | ||||
|                 SelectContactsAdapter(this, contacts, ArrayList(), false, select_contact_list, select_contact_fastscroller) { | ||||
|                     confirmSelection(it) | ||||
|                 }.apply { | ||||
|                     select_contact_list.adapter = this | ||||
|   | ||||
| @@ -1,6 +1,10 @@ | ||||
| package com.simplemobiletools.contacts.pro.adapters | ||||
|  | ||||
| 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.view.View | ||||
| 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.getAdjustedPrimaryColor | ||||
| 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.contacts.pro.R | ||||
| 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 java.util.* | ||||
|  | ||||
| class SelectContactsAdapter(val activity: SimpleActivity, val 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>() { | ||||
| class SelectContactsAdapter(val activity: SimpleActivity, var contacts: ArrayList<Contact>, private val selectedContacts: ArrayList<Contact>, private val allowPickMultiple: Boolean, | ||||
|                             recyclerView: MyRecyclerView, val fastScroller: FastScroller, private val itemClick: ((Contact) -> Unit)? = null) : | ||||
|         RecyclerView.Adapter<SelectContactsAdapter.ViewHolder>() { | ||||
|     private val itemViews = SparseArray<View>() | ||||
|     private val selectedPositions = HashSet<Int>() | ||||
|     private val config = activity.config | ||||
|     private val textColor = config.textColor | ||||
|     private val adjustedPrimaryColor = activity.getAdjustedPrimaryColor() | ||||
|  | ||||
|     private val contactDrawable = activity.resources.getColoredDrawableWithColor(R.drawable.ic_person_vector, textColor) | ||||
|     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 var textToHighlight = "" | ||||
|  | ||||
|     private var smallPadding = activity.resources.getDimension(R.dimen.small_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 | ||||
|  | ||||
|     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) { | ||||
|         fun bindView(contact: Contact, contactDrawable: Drawable, config: Config, showContactThumbnails: Boolean, | ||||
|                      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) | ||||
|                 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.setPadding(if (showContactThumbnails) smallPadding else bigPadding, smallPadding, smallPadding, 0) | ||||
|  | ||||
|                 contact_number?.text = contact.phoneNumbers.firstOrNull()?.value ?: "" | ||||
|                 contact_number?.setTextColor(textColor) | ||||
|                 contact_number?.setPadding(if (showContactThumbnails) smallPadding else bigPadding, 0, smallPadding, 0) | ||||
|                 if (contact_number != null) { | ||||
|                     val phoneNumberToUse = if (textToHighlight.isEmpty()) { | ||||
|                         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 { | ||||
|                     if (itemClick != null) { | ||||
| @@ -128,10 +174,18 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: ArrayLis | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override fun onViewRecycled(holder: ViewHolder) { | ||||
|         super.onViewRecycled(holder) | ||||
|         if (!activity.isDestroyed && !activity.isFinishing) { | ||||
|             Glide.with(activity).clear(holder.itemView.contact_tmb) | ||||
|     private fun highlightTextFromNumbers(name: String, textToHighlight: String): SpannableString { | ||||
|         val spannableString = SpannableString(name) | ||||
|         val digits = PhoneNumberUtils.convertKeypadLettersToDigits(name) | ||||
|         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 { | ||||
|             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.setViews(select_contact_list) { | ||||
|                     select_contact_fastscroller.updateBubbleText(allContacts[it].getBubbleText()) | ||||
|   | ||||
| @@ -12,20 +12,18 @@ | ||||
|         android:layout_height="wrap_content" | ||||
|         android:clipToPadding="false" | ||||
|         android:scrollbars="none" | ||||
|         app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager"/> | ||||
|         app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" /> | ||||
|  | ||||
|     <com.simplemobiletools.commons.views.FastScroller | ||||
|         android:id="@+id/select_contact_fastscroller" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="match_parent" | ||||
|         android:layout_alignTop="@+id/select_contact_list" | ||||
|         android:layout_alignBottom="@+id/select_contact_list" | ||||
|         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"> | ||||
|  | ||||
|         <include layout="@layout/fastscroller_handle_vertical"/> | ||||
|         <include layout="@layout/fastscroller_handle_vertical" /> | ||||
|  | ||||
|     </com.simplemobiletools.commons.views.FastScroller> | ||||
| </RelativeLayout> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user