RecyclerView在SlidingPaneLayout,如何实现下拉更新



我有一个SlidingPaneLayout,里面有一个RecyclerView和一个FragmentContainerView,如下所示。

我要实现的是"下拉刷新"的功能,但我有点卡住了。我发现的唯一的例子,是与SwipeRefreshLayout,但我真的很想保持SlidingPaneLayout。

有没有办法实现这个"下拉刷新"?功能吗?或者我应该接受我必须重做我的布局?

<?xml version="1.0" encoding="utf-8"?>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FeedBaseFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:padding="8dp"
android:layout_width="550dp"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:layout_gravity="start"/>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/detail_container"
android:layout_width="300dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:name="com.example.test.FeedDetailsFragment" />
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
class FeedBaseFragment : Fragment() {
private lateinit var currentView: View
private val feedItemsViewModel: FeedItemsViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_feed_base, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
currentView = view
super.onViewCreated(currentView, savedInstanceState)
val slidingPaneLayout = currentView.findViewById<SlidingPaneLayout>(R.id.sliding_pane_layout)
slidingPaneLayout.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
// Initialize the adapter and set it to the RecyclerView.
val adapter = FeedItemsAdapter {
feedItemsViewModel.updateCurrentFeedItem(it)
slidingPaneLayout.openPane()
}
currentView.findViewById<RecyclerView>(R.id.recycler_view).adapter = adapter
adapter.submitList(feedItemsViewModel.feedItemsData)
}
}

你绝对可以实现"下拉刷新"功能在你的SlidingPaneLayout与RecyclerView。你只需要在swiperrefreshlayout中包装你的RecyclerView。这不会影响你的SlidingPaneLayout,你仍然可以按预期使用它。你可以这样做:

  1. 在你的布局XML文件中,用SwipeRefreshLayout:
<androidx.slidingpanelayout.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
  1. 在您的Java或Kotlin代码中,设置SwipeRefreshLayout并实现刷新侦听器:

芬兰湾的科特林:

import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
class YourActivity : AppCompatActivity() {
private lateinit var swipeRefreshLayout: SwipeRefreshLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.your_activity_layout)
swipeRefreshLayout = findViewById(R.id.swipe_refresh_layout)
// Set up the refresh listener
swipeRefreshLayout.setOnRefreshListener {
// Refresh your data here
refreshData()
}
}
private fun refreshData() {
// Perform your data refreshing logic here
// ...
// Don't forget to call this method once the data is refreshed
swipeRefreshLayout.isRefreshing = false
}
}

这应该允许您实现"下拉刷新"。在你的RecyclerView功能,而不必改变你的SlidingPaneLayout

SlidingPaneLayout中的RecyclerView中实现下拉刷新功能

<androidx.slidingpanelayout.widget.SlidingPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FeedBaseFragment">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/detail_container"
android:layout_width="300dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:name="com.example.test.FeedDetailsFragment" />
</androidx.slidingpanelayout.widget.SlidingPaneLayout>

在你的活动

val swipeRefreshLayout = findViewById<SwipeRefreshLayout>(R.id.swipe_refresh_layout)
swipeRefreshLayout.setOnRefreshListener {
// Perform the data update operation here
// When the data update is complete, call `swipeRefreshLayout.isRefreshing = false` to hide the loading indicator
}

给RecyclerView添加一个OnScrollListener来禁用SlidingPaneLayout中当RecyclerView在顶部滚动时的滑动手势

val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val swipeRefreshLayout = findViewById<SwipeRefreshLayout>(R.id.swipe_refresh_layout)
val slidingPaneLayout = findViewById<SlidingPaneLayout>(R.id.sliding_pane_layout)
// Disable the swipe gesture of the SlidingPaneLayout when the RecyclerView is scrolled to the top
slidingPaneLayout.isEnabled = !recyclerView.canScrollVertically(-1)
// Enable the swipe gesture of the SwipeRefreshLayout when the RecyclerView is at the top and not refreshing
swipeRefreshLayout.isEnabled = !recyclerView.canScrollVertically(-1) && !swipeRefreshLayout.isRefreshing
}
})
class FeedBaseFragment : Fragment() {
private lateinit var currentView: View
private val feedItemsViewModel: FeedItemsViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_feed_base, container, false)
}
var newData = false
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
currentView = view
super.onViewCreated(currentView, savedInstanceState)
val slidingPaneLayout =
currentView.findViewById<SlidingPaneLayout>(R.id.sliding_pane_layout)
if (newData) {
slidingPaneLayout.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
// Initialize the adapter and set it to the RecyclerView.
val adapter = FeedItemsAdapter {
feedItemsViewModel.updateCurrentFeedItem(it)
slidingPaneLayout.openPane()
}
currentView.findViewById<RecyclerView>(R.id.recycler_view).adapter = adapter
adapter.submitList(feedItemsViewModel.feedItemsData)
newData = false
} else {
val adapter = FeedItemsAdapter {
feedItemsViewModel.updateCurrentFeedItem(it)
slidingPaneLayout.openPane()
}
currentView.findViewById<RecyclerView>(R.id.recycler_view).adapter = adapter
adapter.submitList(feedItemsViewModel.feedItemsData)
newData = true
}
}
}

我给你的建议是使用这个方法,我希望它也适用于你。

最新更新