From ebd0823b3d24352e570913adb8b99c827ed1ef73 Mon Sep 17 00:00:00 2001 From: Aleksei Tiurin Date: Fri, 18 Feb 2022 00:01:10 +0300 Subject: [PATCH] bindViewHolder in UI thread --- .../tests/espresso/RecyclerViewTest.kt | 5 ++++ .../sampleapp/activity/MainActivity.kt | 2 +- .../sampleapp/adapters/ContactAdapter.kt | 26 ++++++++++++++++--- .../recyclerview/RecyclerViewUtils.kt | 6 ++++- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/sample-app/src/androidTest/java/com/atiurin/sampleapp/tests/espresso/RecyclerViewTest.kt b/sample-app/src/androidTest/java/com/atiurin/sampleapp/tests/espresso/RecyclerViewTest.kt index 8f22ea64..4a3c2874 100644 --- a/sample-app/src/androidTest/java/com/atiurin/sampleapp/tests/espresso/RecyclerViewTest.kt +++ b/sample-app/src/androidTest/java/com/atiurin/sampleapp/tests/espresso/RecyclerViewTest.kt @@ -386,4 +386,9 @@ class RecyclerViewTest : BaseTest() { .item(hasDescendant(allOf(withId(R.id.tv_name), withText(containsString(CONTACTS[2].name))))) .isDisplayed() } + + @Test + fun createHandlerFromUiTest(){ + page.recycler.getItemAdapterPositionAtIndex(hasDescendant(allOf(withId(R.id.tv_name), withText(containsString(CONTACTS.last().name)))), 0) + } } diff --git a/sample-app/src/main/java/com/atiurin/sampleapp/activity/MainActivity.kt b/sample-app/src/main/java/com/atiurin/sampleapp/activity/MainActivity.kt index 8685b33c..daf046ad 100644 --- a/sample-app/src/main/java/com/atiurin/sampleapp/activity/MainActivity.kt +++ b/sample-app/src/main/java/com/atiurin/sampleapp/activity/MainActivity.kt @@ -69,7 +69,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte viewManager = LinearLayoutManager(this) - viewAdapter = ContactAdapter(ArrayList(), + viewAdapter = ContactAdapter(this, ArrayList(), object : ContactAdapter.OnItemClickListener { override fun onItemClick(contact: Contact) { val intent = Intent(applicationContext, ChatActivity::class.java) diff --git a/sample-app/src/main/java/com/atiurin/sampleapp/adapters/ContactAdapter.kt b/sample-app/src/main/java/com/atiurin/sampleapp/adapters/ContactAdapter.kt index ca85d379..ee841e12 100644 --- a/sample-app/src/main/java/com/atiurin/sampleapp/adapters/ContactAdapter.kt +++ b/sample-app/src/main/java/com/atiurin/sampleapp/adapters/ContactAdapter.kt @@ -1,20 +1,29 @@ package com.atiurin.sampleapp.adapters +import android.content.Context +import android.view.GestureDetector import android.view.LayoutInflater +import android.view.MotionEvent import android.view.ViewGroup import android.widget.LinearLayout import android.widget.TextView +import androidx.core.view.GestureDetectorCompat import androidx.recyclerview.widget.RecyclerView import com.atiurin.sampleapp.R import com.atiurin.sampleapp.data.entities.Contact import com.atiurin.sampleapp.view.CircleImageView -class ContactAdapter(private var mDataset: ArrayList, val listener: OnItemClickListener) : - RecyclerView.Adapter() { +class ContactAdapter( + val context: Context, + private var mDataset: ArrayList, + val listener: OnItemClickListener +) : + RecyclerView.Adapter(), GestureDetector.OnGestureListener { interface OnItemClickListener { fun onItemClick(item: Contact) } + class MyViewHolder(val view: LinearLayout) : RecyclerView.ViewHolder(view) open fun updateData(data: ArrayList) { @@ -37,8 +46,19 @@ class ContactAdapter(private var mDataset: ArrayList, val listener: OnI val status = holder.view.findViewById(R.id.tv_status) as TextView tvTitle.text = mDataset[position].name status.text = mDataset[position].status - avatar.setImageDrawable(holder.view.context.getResources().getDrawable(mDataset[position].avatar)) + avatar.setImageDrawable( + holder.view.context.getResources().getDrawable(mDataset[position].avatar) + ) + GestureDetectorCompat(context, this) } override fun getItemCount() = mDataset.size + + // GestureDetector.OnGestureListener + override fun onDown(p0: MotionEvent?): Boolean = true + override fun onShowPress(p0: MotionEvent?) = Unit + override fun onSingleTapUp(p0: MotionEvent?): Boolean = true + override fun onScroll(p0: MotionEvent?, p1: MotionEvent?, p2: Float, p3: Float): Boolean = true + override fun onLongPress(p0: MotionEvent?) = Unit + override fun onFling(p0: MotionEvent?, p1: MotionEvent?, p2: Float, p3: Float): Boolean = true } \ No newline at end of file diff --git a/ultron/src/main/java/com/atiurin/ultron/core/espresso/recyclerview/RecyclerViewUtils.kt b/ultron/src/main/java/com/atiurin/ultron/core/espresso/recyclerview/RecyclerViewUtils.kt index bf3c987b..f79be737 100644 --- a/ultron/src/main/java/com/atiurin/ultron/core/espresso/recyclerview/RecyclerViewUtils.kt +++ b/ultron/src/main/java/com/atiurin/ultron/core/espresso/recyclerview/RecyclerViewUtils.kt @@ -4,6 +4,7 @@ import android.util.SparseArray import android.view.View import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.util.HumanReadables +import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread import org.hamcrest.Description import org.hamcrest.Matcher import org.hamcrest.TypeSafeMatcher @@ -26,7 +27,10 @@ internal fun itemsMatching( viewHolderCache.put(itemType, cachedViewHolder) } // Bind data to ViewHolder and apply matcher to view descendants. - adapter.bindViewHolder((cachedViewHolder as T?)!!, position) + runOnUiThread{ + //requires UI thread to create handler in some cases + adapter.bindViewHolder((cachedViewHolder as T?)!!, position) + } if (viewHolderMatcher.matches(cachedViewHolder)) { matchedItems.add(MatchedItem(position, HumanReadables.getViewHierarchyErrorMessage(