我正在使用RecyclerView和GridLayoutManager。我想要达到的目标是当我点击一个项目时,它会向上扩展并重叠相邻的项目。如下图所示(在Android TV中)
触发onClick事件时,我调用
v.animate().scaleX(1.2f).scaleY(1.2f).setDuration(500).start();
但结果如下:
它只能重叠位置低于自身的项目
我该怎么做才能重叠所有相邻的项目。提前谢谢。
的修改
我已经尝试过了:
v.bringToFront();
或
(v.getParent()).bringChildToFront(v);
但他们两个都不起作用。
答案 0 :(得分:4)
根据 aga的回答,我使用 ViewCompat.setElevation(查看视图,浮动高程)来支持21之前的API,它就像一个迷人的。
static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View root) {
// bind views
// ...
// bind focus listener
root.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
// run scale animation and make it bigger
ViewCompat.setElevation(root, 1);
} else {
// run scale animation and make it smaller
ViewCompat.setElevation(root, 0);
}
}
});
}
}
项目布局文件非常简单,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"
android:background="@drawable/sl_live_item" />
答案 1 :(得分:3)
1.Override getChildDrawingOrder方法。
@Override
protected int getChildDrawingOrder(int childCount, int i) {
View view = getLayoutManager().getFocusedChild();
if (null == view) {
return super.getChildDrawingOrder(childCount, i);
}
int position = indexOfChild(view);
if (position < 0) {
return super.getChildDrawingOrder(childCount, i);
}
if (i == childCount - 1) {
return position;
}
if (i == position) {
return childCount - 1;
}
return super.getChildDrawingOrder(childCount, i);
}
2.RecyclerView setChildrenDrawingOrderEnabled true 。
setChildrenDrawingOrderEnabled(true);
3.当项目视图具有焦点时,使其父项无效。
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
v.setScaleX(1.5f);
v.setScaleY(1.5f);
mRecyclerView.invalidate();
} else {
v.setScaleX(1.0f);
v.setScaleY(1.0f);
}
}
答案 2 :(得分:0)
在运行动画之前尝试调用v.bringToFront()
如果它不起作用,另一个变体是使用View#setElevation(float val)
,其中val&gt; 0.缺点是当您取消选择项目时,您需要将高程设置为0.
答案 3 :(得分:0)
val zoom = resources.getFraction(...) // Your zoom fraction in %
override fun onFocusChanged(gainFocus: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect)
val viewPropertyAnimator: ViewPropertyAnimator
val f: Float
if(gainFocus) {
tvAppName.visibility = VISIBLE
f = this.zoom;
viewPropertyAnimator = animate().z(2.0f).scaleX(this.zoom);
} else {
tvAppName.visibility = INVISIBLE
ivAppIcon.strokeWidth = 0f
f = 1.0f;
viewPropertyAnimator = animate().z(0.0f).scaleX(1.0f);
}
viewPropertyAnimator.scaleY(f).duration = 150;
}
您可以将此示例代码添加到任何布局中以达到预期效果。
答案 4 :(得分:-2)
您需要按照常规ViewGroups的旧方式执行此操作,从而覆盖子项的绘制顺序。此示例强制始终最后绘制第一个视图 - 您需要根据用例进行自定义。
public TopForcingRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setChildrenDrawingOrderEnabled(true);
}
@Override protected int getChildDrawingOrder(int childCount, int i) {
if (i >= childCount - 1) return 0;
//when asked for the last view to draw, answer ZERO
else return i + 1;
//when asked for the i-th view to draw, answer "the next one"
}
注意一个错误。