2

I am trying to create a layout similar to this, using RecyclerView for a TV-like application.

enter image description here

The first element indicates how the focused item should look like. The solutions I've tried are:

  • Using cardView as parent layout for elements. Problem: When I'm making the focused element bigger by modifying it's layout params, the whole row gets bigger and the rest of the rows are pushed down
  • Using VerticalGridView from leanback library - The column where the focused element is located is pushed down
  • Trying to play with elevation and Z-translation, but still the rows are pushed down
  • Making RecyclerView height fixed, still the same behaviour
  • Playing with the clipChildren attribute, still the rows are pushed down

The only thing that worked is to scale the focused element, but this is not a solution, as all the children are being scaled, like TextViews, etc. and the text doesn't look right. Does anyone have any solution for this, a view of an approach? Thank you!

Phantom
  • 968
  • 3
  • 14
  • 32

1 Answers1

0

API 21+ Just use in your views

 @Override
public void onFocusChange(View v, boolean hasFocus) {
    ViewCompat.setElevation(this, hasFocus?1:0);
}

API 16+ Here is my extended TvRecyclerView:

public class TvRecyclerView extends android.support.v7.widget.RecyclerView {

public TvRecyclerView(Context context) {
    super(context);
    setChildrenDrawingOrderEnabled(true);
}

public TvRecyclerView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setChildrenDrawingOrderEnabled(true);
}

public TvRecyclerView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    setChildrenDrawingOrderEnabled(true);
    setClipToPadding(false);
}

@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);
}
}

Basically it just reorder items, so focused item is always on top.

Also in your views you need to use

@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);
}
}
dipcore
  • 190
  • 2
  • 8