Google Map + конфликт просмотра ViewPager2 - PullRequest
0 голосов
/ 04 апреля 2020

Кто-нибудь имеет дело с ViewPager2 + Fragments + GoogleMap?

Я столкнулся с действительно интересной проблемой, внутри моего viewpager у меня есть две вкладки, каждая из которых отображает фрагменты.

Один из фрагментов порождает карту Google.

Когда я пытаюсь выполнить маневрирование по этой карте, я получаю эффект viewpager2, пытающегося провести пальцем влево и вправо, это действительно раздражает, поэтому то, что я сделал, чтобы решить его, было не очень приятно.

Я открыл окно просмотра одному из фрагментов с помощью конструктора и вызвал обратный вызов для верхнего действия окна просмотра.

Там я выполнил простую isUserInputEnabled с логи c, пока карта Активное отключение смахивания.

Как только фрагмент присоединяется к этому обратному вызову, регистрируется и вызывает логи c.

Как только фрагмент отсоединяется, этот обратный вызов вызывает logi c для повторного включения.

Это решение, но, думаю, это нехорошо. Есть идеи получше?

Проведение совмещения с представлениями кажется мне ошибкой.

/* top activity that hosts viewpager2 and it's tabs(fragments) */
class ViewTap extends AppCompatActivity
all the good stuff about viewpager2: ViewPager2
fun registerUi(){
...TapPagerAdapter(...this)
}
override fun fireSensitivityResolver(fragment: Fragment, flag: Boolean){
 if(fragment is ViewMapLoader){
  this.mViewPager2.isUserInputEnabled = !flag
 }
}

/* callback defintion fo handling events about Tab Capale thingies */
interface TabCapableIf {
 fun fireSensitivityResolver(fragment: Fragment, flag: Boolean)
}

/* the adapter for viewpager2 */
class TapPagerAdapter(...private val vt: ViewTap) : FragmentStateAdapter(fm,lc){
override fun createFragment(position: Int): Fragment {
return when(position) {
 ....
  CROWD_FRAGMENT -> { ViewCrowd(vmf, vt) }
 }
}

/* the fragment where the recycler view shows */
class ViewCrowd(...,val vt: ViewTap) : Fragment(){
 fun subscribeUi(){
   some recycler adapter = ItemViewCrowdsAdapter(...,this)
 }
}

/* the card adapter for the recycler view , when a card is clicked transition to map view */
class ItemViewCrowdsAdapter(...,private val vc: ViewCrowd) : AdapterFragmentRecyclerView(vm) {
 override fun onBindViewHolder(holder: ItemHolder, position: Int){
  ...holder.itemView.setOnClickListener{
   ...                    fragmentTransaction.replace(R.id.layout_view_crowd_root, ViewMapLoader(...,vc.vt))
  }
 }
}

/* the map loader context that shows the map and handles adjusting the sensitivity so that viewpager2 swipe doesn't overlap with map swipe functionality. otherwise as i try swiping on the map the viewpager2 also swipes. */
class class ViewMapLoader(...,private val vt: ViewTap) : Fragment() {
 private lateinit var mTabCapableIf: TabCapableIf
 override fun onAttach(...){
  this.mTabCapableIf = this.vt
  mTabCapableIf.fireSensitivityResolver(this,true)
 }

 override fun onDetach(){
  mTabCapableIf.fireSensitivityResolver(this,false)
 }
}

1 Ответ

1 голос
/ 15 апреля 2020

Попробуйте переопределить MapView, чтобы подавить сенсорные события

public class MapViewInScroll extends MapView {
public MapViewInScroll(Context context) {
    super(context);
}

public MapViewInScroll(Context context, AttributeSet attributeSet) {
    super(context, attributeSet);
}

public MapViewInScroll(Context context, AttributeSet attributeSet, int i) {
    super(context, attributeSet, i);
}

public MapViewInScroll(Context context, GoogleMapOptions googleMapOptions) {
    super(context, googleMapOptions);
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    getParent().requestDisallowInterceptTouchEvent(true);
    return super.dispatchTouchEvent(ev);
}

}

и использовать его в макете xml вместо исходного MapView

                    <YOUR_PACKAGE.SOME_PATH_TO_VIEW.MapViewInScroll
                    android:id="@+id/map"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
...