在RecyclerView中放大项目以重叠2个相邻项目Android

时间:2015-04-07 08:42:48

标签: android android-recyclerview

我正在使用RecyclerView和GridLayoutManager。我想要达到的目标是当我点击一个项目时,它会向上扩展并重叠相邻的项目。如下图所示(在Android TV中) enter image description here

触发onClick事件时,我调用

v.animate().scaleX(1.2f).scaleY(1.2f).setDuration(500).start();

但结果如下: enter image description here

它只能重叠位置低于自身的项目 我该怎么做才能重叠所有相邻的项目。提前谢谢。
修改
我已经尝试过了:

v.bringToFront();

(v.getParent()).bringChildToFront(v);

但他们两个都不起作用。

5 个答案:

答案 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"
}

注意一个错误。