สวัสดีท่านผู้ชมที่รัก
สถานการณ์ของฉัน :
ฉันมีเพจเจอร์ที่อนุญาตให้ผู้ใช้ปัดไปทางซ้ายและขวา ฉันมีหน้าจอ (ส่วนย่อย) ที่ผู้ใช้ต้องการให้ทำให้เสร็จก่อนจึงจะปัดนิ้วได้
แก้ไข 4: วิธีแก้ปัญหา
เนื่องจาก ViewPager2 ทำงานเหมือนกับ RecyclerView ฉันจึงเพิ่ม MutableList ให้กับอะแดปเตอร์ของฉัน:
var fragmentList = mutableListOf<Fragment>(
BasicInfoFragment.newInstance(
activity
),
BondsFragment.newInstance(
activity
),
...
ในตอนเริ่มต้น ในรายการมีเพียงชิ้นส่วนที่แสดงก่อนการล็อค เมื่อเงื่อนไขของฉันเป็นไปตามหรือพอใจ ฉันจะเพิ่มส่วนถัดไปในรายการของอะแดปเตอร์ เพื่อให้พร้อมสำหรับการปัด
ด้านล่างนี้เป็นสิ่งเก่าที่ใช้งานไม่ได้:
สิ่งที่ฉันได้ทำไปแล้ว :
ฉันปรับแต่งวิวเพจเจอร์เพื่อล็อคการปัดเมื่อฉันต้องการล็อค (ดูรหัสของฉัน) แต่มันปิดการใช้งานทั้งสองทิศทาง
ตามหลักการแล้ว ฉันต้องการปิดการใช้งานการปัดจากซ้ายไปขวาเท่านั้น : ฉันต้องการให้ผู้ใช้สามารถปัดกลับ (จากขวาไปซ้าย) ฉันแค่ต้องการปิดการใช้งานการปัดไปข้างหน้า (จากซ้ายไปขวา)
ฉันพยายามใช้ onTouchListener บนเพจเจอร์มุมมองของฉันเพื่อตรวจจับทิศทางการปัด แต่จะใช้งานได้เฉพาะเมื่อ ViewPager ถูกปลดล็อคเท่านั้น
คุณสามารถช่วยฉันได้ไหม ?
แก้ไข 3: ปัญหาใหม่
ฉันได้ลองใช้ viewpager2 แล้ว แต่ตอนนี้ฉันมีปัญหากับเลย์เอาต์ลูก ๆ
เมื่อฉันต้องการแสดงแฟรกเมนต์เป็นส่วนอื่น ฉันจะใช้วิธีการขยายที่ฉันเขียนโดยยึดตามสิ่งนี้: วิธีเพิ่ม-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 ฉันไม่พบมุมมองสำหรับข้อยกเว้นรหัส
ฉันเข้าใจว่าเป็นเพราะฉันใช้ตัวจัดการแฟรกเมนต์แทน ChildSupportFragmentManager ดังนั้นฉันจึงแทนที่ตัวจัดการแฟรกเมนต์ด้วยอันที่ดี แต่ตอนนี้ฉันพบข้อขัดข้องสำหรับ: ยังไม่ได้แนบ Fragment
อีกครั้งคุณช่วยฉันได้ไหม?
ขอบคุณมาก !
รหัส :
/**
* 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 แบบดิบไว้ที่ด้านล่างของเค้าโครงกิจกรรมที่มี view pager :
<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 เฉพาะในกรณีที่การปัดจากขวาไปซ้าย
มันยุ่งยากนิดหน่อย ดังนั้นหากคุณมีข้อเสนอแนะใดๆ ...