我正在尝试在另一个带有水平LinearLayoutManager的RecyclerView中使用带有水平LinearLayoutManager的RecyclerView。整个层次结构如下:RecyclerView,Recycler的子级是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(子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
}
}
}
如果您需要更多详细信息,请告诉我,我会更新。
答案 0 :(得分:0)
我已经在嵌套的 ScrollView 之前实现了,我认为子级滚动视图总是消耗触摸,而父级滚动视图将永远不会监听
这里是方法的作用
onInterceptTouchEvent
,用于控制视图是使用触摸还是将触摸传递给父视图。
所以计划是计算滚动方向,我是否到达子ScrollView的滚动结束。
这段代码是2年前编写的,因此如果不赞成使用,请原谅。
public class CustomScrollView extends ScrollView {
private boolean bottomReached = false;
private boolean topReached = true;
private float startTouch = -1;
private float distance = -1;
public CustomScrollView(Context context) {
super(context);
}
public CustomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startTouch = ev.getY();
break;
case MotionEvent.ACTION_UP:
startTouch = -1;
break;
case MotionEvent.ACTION_MOVE:
distance = ev.getY() - startTouch;
if (Math.abs(distance) < 10) {
boolean onIntercept = super.onInterceptTouchEvent(ev);
return onIntercept;
} else {
if (!bottomReached && !topReached) {
return true;
} else {
if (distance > 0) {
// Scrolling Up
return bottomReached;
} else {
// Scrolling Down
return topReached;
}
}
}
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startTouch = ev.getY();
break;
case MotionEvent.ACTION_UP:
startTouch = -1;
break;
case MotionEvent.ACTION_MOVE:
distance = ev.getY() - startTouch;
}
return super.onTouchEvent(ev);
}
}
答案 1 :(得分:-1)
在GitHub上查看此站点及其代码 Nested Recyclerview