привет, дорогие зрители.
Моя ситуация:
У меня есть окно просмотра, которое позволяет пользователю проводить пальцем влево и вправо. У меня есть экран (фрагмент), который я хочу, чтобы пользователь завершил, прежде чем он сможет провести.
РЕДАКТИРОВАТЬ 4: РЕШЕНИЕ
Поскольку ViewPager2 работает как RecyclerView, я добавил a MutableList для моего адаптера:
var fragmentList = mutableListOf<Fragment>(
BasicInfoFragment.newInstance(
activity
),
BondsFragment.newInstance(
activity
),
...
В начале в списке есть только фрагменты, отображаемые до «блокировки». Когда мое условие выполнено или выполнено, я добавляю следующие фрагменты в список адаптера, чтобы они были доступны для считывания
Ниже приведены старые вещи, которые не работают:
What I сделали:
Я настроил окно просмотра для блокировки пролистывания, когда я хочу, чтобы он был заблокирован (см. мой код), но он отключает оба направления.
В идеале я хочу отключить только смахивание слева направо: я хочу, чтобы пользователь мог смахнуть назад (справа налево). Я просто хочу отключить прокрутку вперед (слева направо).
Я попытался реализовать onTouchListener на моем пейджере просмотра для определения направления прокрутки, но он работает только тогда, когда ViewPager разблокирован.
Можете ли вы мне помочь?
Редактировать 3: Новые проблемы
Я пытался реализовать viewpager2, но теперь у меня проблемы с дочерним макетом.
Когда мне нужно чтобы отобразить фрагмент в другом фрагменте, я использую метод расширения, который я написал на основе этого: how-to-add-a-fragment-in- kotlin -way
Выглядит это так:
inline fun FragmentManager.doTransaction(func: FragmentTransaction.() -> Unit) {
Log.d(TAG, "doTransaction")
val fragmentTransaction = beginTransaction()
fragmentTransaction.func()
fragmentTransaction.commit()
}
fun AppCompatActivity.replaceFragment(frameId: Int, fragment: Fragment) {
Log.d(TAG, "replaceFragment")
supportFragmentManager.doTransaction { replace(frameId, fragment) }
}
Итак, у меня есть несколько фрагментов с такими вещами:
companion object : CustomCompanion() {
@JvmStatic
override fun newInstance(activity: Activity): IdealsFragment {
val fragment =
IdealsFragment(
activity
)
(activity as NewCharacterActivity).replaceFragment(
R.id.fragmentIdeals_container_ideals,
IdealsRecyclerViewFragment.newInstance(
activity
)
)
return fragment
}
}
Дело в том, что с ViewPager2 я получил сообщение «no view found for id "исключение.
Я понял, что это произошло потому, что я использовал диспетчер фрагментов вместо ChildSupportFragmentManager, поэтому я заменил диспетчер фрагментов на хороший, но теперь у меня есть ошибка sh для:« Фрагмент не еще прикреплены. ".
* 1 047 * Еще раз, вы можете мне помочь?
Большое спасибо!
Код:
/**
* Class "LockableViewPager" :
* Custom viewpager that allows or not to swipe between fragments.
**/
class LockableViewPager : ViewPager {
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
companion object {
private const val TAG = "LockableViewPager"
}
/**
* Is swiping enabled ?
*/
private var swipeEnabled = true
/**
* Intercept all touch screen motion events.
* Allows to watch events as they are dispatched, and
* take ownership of the current gesture at any point.
*
* @param event : The motion event being dispatched down the hierarchy.
* @return Return true to steal motion events from the children and have
* them dispatched to this ViewGroup through onTouchEvent().
* The current target will receive an ACTION_CANCEL event, and no further
* messages will be delivered here.
*/
override fun onTouchEvent(event: MotionEvent): Boolean {
return when (swipeEnabled) {
true -> super.onTouchEvent(event)
false -> // Do nothing.
return false
}
}
/**
* Implement this method to intercept all touch screen motion events. This
* allows you to watch events as they are dispatched to your children, and
* take ownership of the current gesture at any point.
*
* @param event : The motion event being dispatched down the hierarchy.
* @return Return true to steal motion events from the children and have
* them dispatched to this ViewGroup through onTouchEvent().
* The current target will receive an ACTION_CANCEL event, and no further
* messages will be delivered here.
*/
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
return when (swipeEnabled) {
true -> super.onInterceptTouchEvent(event)
false -> swipeEnabled
}
}
/**
* Sets the swipeEnabled value to lock or unlock swiping
*/
fun setSwipeEnabled(swipeEnabled: Boolean) {
this.swipeEnabled = swipeEnabled
}
}
Редактировать 2: Может быть, решение?
Я помещаю необработанный вид в нижнюю часть макета активности, который содержит пейджер вида:
<View
android:id="@+id/touch_layer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" />
Я создал абстрактный класс который реализует View.OnTouchListener:
abstract class OverlayTouchListener : View.OnTouchListener {
companion object{
private const val TAG = "OverlayTouchListener"
}
}
Десериализовал представление наложения в моем действии:
var touchLayer = this.findViewById<View>(R.id.touch_layer)
Добавил OverlayTouchListener в touchLayer:
touchLayer?.setOnTouchListener(object : OverlayTouchListener() {
/**
* Called when a touch event is dispatched to a view. This allows listeners to
* get a chance to respond before the target view.
*
* @param v The view the touch event has been dispatched to.
* @param event The MotionEvent object containing full information about
* the event.
* @return True if the listener has consumed the event, false otherwise.
*/
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
Log.d(TAG, "onTouch")
if(event != null){
// Check the swiping direction and ViewPager.isSwipeEnabled
viewPager?.setSwipeEnabled(true)
viewPager?.onTouchEvent(event)
}
return true
}
})
Теперь , мне просто нужно проверить, включена ли прокрутка. Если нет, вызывайте viewPager.onTouchEvent только в том случае, если смахивание идет справа налево.
Это немного сложно, поэтому, если у вас есть какие-либо предложения ...