【发布时间】:2019-01-20 00:48:31
【问题描述】:
我正在尝试在另一个带有水平 LinearLayoutManager 的 RecyclerView 中使用带有水平 LinearLayoutManager 的 RecyclerView。整个层次结构是这样的:RecyclerView,Recycler的child是一个ScrollView,它包含一个TextView和另一个RecyclerView。为了更好地理解,我希望第一个回收器像 ViewPager 一样工作,但不完全相同(我不想使用 ViewPager)。问题是当我尝试在子回收器上水平滚动时,运动事件被父回收器捕获,导致滚动到下一页而无法滚动子回收器。
MainActivityLayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/RVpage"
android:descendantFocusability="blocksDescendants"
android:focusableInTouchMode="false"
android:focusable="false"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRecycler();
}
private void setRecycler() {
recyclerView=(RecyclerView) findViewById(R.id.RVpage);
SnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
BigRecyclerAdapter bigRecyclerAdapter=new BigRecyclerAdapter(this);
recyclerView.setAdapter(bigRecyclerAdapter);
//recyclerView.setNestedScrollingEnabled(true);
recyclerView.setLayoutManager(new LinearLayoutManager(
this, LinearLayoutManager.HORIZONTAL, false)
);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
//Toast.makeText(MainActivity.this, "CHANGED BIG", Toast.LENGTH_SHORT).show();
super.onScrollStateChanged(recyclerView, newState);
}
});
}
}
PageRecycler 布局:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="nskjdnaskdn \n sudbadbak
\n sudbadbak
\n sudbadbak
\n sudbadbak
\n sudbadbak\n sudbadbak
v
\n sudbadbak
\n sudbadbak
\n sudbadbak
\n sudbadbak
\n sudbadbak
\n sudbadbak
\n sudbadbak
\n sudbadbak
v
v
\n sudbadbak
\n sudbadbak
v
v
\n sudbadbak
vv
\n sudbadbak
v
v
\n sudbadbak"
android:textColor="@android:color/black"
android:textSize="50sp"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusableInTouchMode="true"
android:focusedByDefault="true"
android:descendantFocusability="afterDescendents"
android:focusable="true"
android:padding="20dp" />
</LinearLayout>
</ScrollView>
在 relativeLayout 中我留下了我尝试过的所有东西,从 clickable=true 到 descendentFocusability。
PageRecycler 适配器:
class BigRecyclerAdapter(private val context: MainActivity) : RecyclerView.Adapter<BigRecyclerAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent?.context)
.inflate(R.layout.raw, parent, false)
return ViewHolder(v)
}
/* override fun onViewAttachedToWindow(holder: ViewHolder?) {
var parent = holder?.recycler?.parent
val DEBUG_TAG_SCROLL = "DEBUG_TAG_SCROLL"
Log.d(DEBUG_TAG_SCROLL, "NESTED_SCROLL_VALUE: ${holder?.recycler?.hasNestedScrollingParent()}")
if (holder?.recycler?.parent is RecyclerView) {
Log.d(DEBUG_TAG_SCROLL, "Good parent")
}
super.onViewAttachedToWindow(holder)
}*/
override fun getItemCount(): Int {
return 5
}
override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
holder?.bind()
// val DEBUG_TAG_SCROLL = "DEBUG_TAG_SCROLL"
//// Log.d(DEBUG_TAG_SCROLL, "NESTED_SCROLL_VALUE: ${holder?.recycler?.hasNestedScrollingParent()}")
//
// if(holder?.recycler?.parent is RecyclerView){
// Log.d(DEBUG_TAG_SCROLL, "Good parent")
// }
}
inner class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
var recycler: RecyclerView
init {
recycler = v.findViewById(R.id.photo) as RecyclerView
}
fun bind() {
recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
Toast.makeText(context, "CHANGED SMALL", Toast.LENGTH_SHORT).show()
super.onScrollStateChanged(recyclerView, newState)
}
// override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
// super.onScrolled(recyclerView, dx, dy)
// }
})
val smallRecyclerAdapter = SmallRecyclerAdapter(context)
recycler.adapter = smallRecyclerAdapter
recycler.layoutManager = LinearLayoutManager(
context, LinearLayoutManager.HORIZONTAL, false
)
recycler.scrollToPosition(5)
}
}
}
PhotoRecycler raw(子recyclerView):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/photoView"/>
</LinearLayout>
PhotoRecycler 适配器:
class SmallRecyclerAdapter(private val context: MainActivity): RecyclerView.Adapter<SmallRecyclerAdapter.ViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent?.context)
.inflate(R.layout.raw_small, parent, false)
// set the view's size, margins, paddings and layout parameters
return ViewHolder(v)
}
override fun getItemCount(): Int {
return 10
}
override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
//TODO here
var drawableName="p"+((position%4)+1)
val drawable = context.getResources().getDrawable(context.getResources()
.getIdentifier(drawableName, "drawable", context.getPackageName()))
holder?.imageView?.setImageDrawable(drawable)
}
inner class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
var imageView: ImageView
init {
imageView=v.findViewById(R.id.photoView) as ImageView
}
}
}
如果您需要更多详细信息,请告诉我,我会更新。
【问题讨论】:
-
你为什么要这个?在同一方向上的嵌套滚动通常会出现问题。应用程序应该如何知道它应该滚动哪个元素?
-
为什么要问问题?它应该基本上可以工作,它可以与 ViewPager 一起工作,并且是相同的想法。我猜它知道在水平回收器内滚动垂直回收器的方式相同。我可以通过扩展 Recycler 或 LayoutManager 让它在很长一段时间内工作,但它是矫枉过正的。在尝试之前我想我应该问一下是否存在更简单的解决方案
-
它知道在水平回收器中滚动垂直回收器 - 这很容易区分,因为它的滚动方向不同。我的 2 美分是更简单的解决方案是制作不需要嵌套水平滚动的不同设计
-
设计不是我可以改变的。容易或不区分它应该。它只是一个滚动监听器,应该传播到视图的子视图
-
如果滚动事件传播给孩子会发生什么?他们都滚动?还是只有孩子?只有父母?它是怎么知道的
标签: java android android-recyclerview kotlin