为什么我的自定义行为在 Android 中效果不佳
Why my custom Behavior doesn't work well in Android
我在布局的顶部有一个 ImageView
,在它下面有一个 RecyclerView
;这就是我在自定义行为步骤 1 中所需要的;但是,它似乎效果不佳。
代码如下:
Behavior.java
public class Depency extends CoordinatorLayout.Behavior<RecyclerView> {
private String TAG = "tag";
public Depency() {
}
public Depency(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, RecyclerView child, View
dependency) {
int delta = (int) (dependency.getTranslationY() + dependency.getBottom());
delta -= child.getTop();
child.offsetTopAndBottom(delta);
Log.i(TAG,
"onDependentViewChanged: " + delta + "," + child.getTop() + dependency.getClass().getSimpleName());
return true;
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, RecyclerView child, View dependency) {
return dependency instanceof AppCompatImageView;
}
}
layout.xml
<android.support.design.widget.CoordinatorLayout
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"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.example.kenchan.fullypjo.MainActivity"
tools:showIn="@layout/activity_main">
<android.support.v7.widget.AppCompatImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_girl"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.example.kenchan.fullypjo.view.Depency"/>
</android.support.design.widget.CoordinatorLayout>
xml中的预览:
似乎工作正常。
但是当我 运行 我手机上的项目 phone 时,我出错了:
有人可以帮助我或对我的代码提出建议吗?
这个问题困扰了我一段时间;
我尝试阅读 android.support.design.widget.AppBarLayout$ScrollingViewBehavior
中的源代码
我发现代码逻辑完全不同:
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child,
View dependency) {
offsetChildAsNeeded(parent, child, dependency);
return false;
}
private void offsetChildAsNeeded(CoordinatorLayout parent, View child, View dependency) {
final CoordinatorLayout.Behavior behavior =
((CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior();
if (behavior instanceof Behavior) {
// Offset the child, pinning it to the bottom the header-dependency, maintaining
// any vertical gap and overlap
final Behavior ablBehavior = (Behavior) behavior;
ViewCompat.offsetTopAndBottom(child, (dependency.getBottom() - child.getTop())
+ ablBehavior.mOffsetDelta
+ getVerticalLayoutGap()
- getOverlapPixelsForOffset(dependency));
}
}
RecyclerView
位于顶部 z-index,这就是为什么您会看到它覆盖在 ImageView
之上。在预览中您只看到 9 个项目。
您需要将 RecyclerView
top when inside your Behavior 的 onLayoutChild()
方法更改为 ImageView
的底部。这种方法让您有机会自己布置 child,而不是让 CoordinatorLayout
故意布置。如果您 return 为真,CoordinatorLayout
将不会尝试布局该视图。
我在布局的顶部有一个 ImageView
,在它下面有一个 RecyclerView
;这就是我在自定义行为步骤 1 中所需要的;但是,它似乎效果不佳。
代码如下:
Behavior.java
public class Depency extends CoordinatorLayout.Behavior<RecyclerView> {
private String TAG = "tag";
public Depency() {
}
public Depency(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, RecyclerView child, View
dependency) {
int delta = (int) (dependency.getTranslationY() + dependency.getBottom());
delta -= child.getTop();
child.offsetTopAndBottom(delta);
Log.i(TAG,
"onDependentViewChanged: " + delta + "," + child.getTop() + dependency.getClass().getSimpleName());
return true;
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, RecyclerView child, View dependency) {
return dependency instanceof AppCompatImageView;
}
}
layout.xml
<android.support.design.widget.CoordinatorLayout
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"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.example.kenchan.fullypjo.MainActivity"
tools:showIn="@layout/activity_main">
<android.support.v7.widget.AppCompatImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_girl"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.example.kenchan.fullypjo.view.Depency"/>
</android.support.design.widget.CoordinatorLayout>
xml中的预览:
似乎工作正常。
但是当我 运行 我手机上的项目 phone 时,我出错了:
有人可以帮助我或对我的代码提出建议吗?
这个问题困扰了我一段时间;
我尝试阅读 android.support.design.widget.AppBarLayout$ScrollingViewBehavior
中的源代码
我发现代码逻辑完全不同:
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child,
View dependency) {
offsetChildAsNeeded(parent, child, dependency);
return false;
}
private void offsetChildAsNeeded(CoordinatorLayout parent, View child, View dependency) {
final CoordinatorLayout.Behavior behavior =
((CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior();
if (behavior instanceof Behavior) {
// Offset the child, pinning it to the bottom the header-dependency, maintaining
// any vertical gap and overlap
final Behavior ablBehavior = (Behavior) behavior;
ViewCompat.offsetTopAndBottom(child, (dependency.getBottom() - child.getTop())
+ ablBehavior.mOffsetDelta
+ getVerticalLayoutGap()
- getOverlapPixelsForOffset(dependency));
}
}
RecyclerView
位于顶部 z-index,这就是为什么您会看到它覆盖在 ImageView
之上。在预览中您只看到 9 个项目。
您需要将 RecyclerView
top when inside your Behavior 的 onLayoutChild()
方法更改为 ImageView
的底部。这种方法让您有机会自己布置 child,而不是让 CoordinatorLayout
故意布置。如果您 return 为真,CoordinatorLayout
将不会尝试布局该视图。