Snippets

Oleg Chulakov Studio Android Picker

Created by Владимир Самсонов last modified
pickerRecycler.setLayoutManager(
  new SlideLayoutManager(
      getContext(), pickerRecycler, layoutPosition -> {}));
SnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(pickerRecycler);
PickerAdapter pickerAdapter = new PickerAdapter(new ArrayList<String>() {{
    add("РАЗ");
    add("ДВА");
  }}
);
pickerRecycler.setAdapter(pickerAdapter);
pickerRecycler.scrollToPosition(Integer.MAX_VALUE / 2);
public class PickerAdapter extends RecyclerView.Adapter<PickerItemHolder> {

  private List<String> items;

  public PickerAdapter(List<String> items) {
    this.items = items;
  }

  @NonNull
  @Override
  public PickerItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new PickerItemHolder(
            DataBindingUtil.inflate(
                LayoutInflater.from(parent.getContext()),
                R.layout.picker_item,
                parent,
                false));
  }

  @Override
  public void onBindViewHolder(@NonNull PickerItemHolder holder, int position) {
    int arrayPosition = position % items.size();
    holder.binding.text.setText(items.get(arrayPosition));
  }

  @Override
  public int getItemCount() {
    return Integer.MAX_VALUE;
  }

  public List<String> getItems() {
    return items;
  }

  public class PickerItemHolder extends RecyclerView.ViewHolder {
    PickerItemBinding binding;
    public PickerItemHolder(@NonNull PickerItemBinding binding) {
      super(binding.getRoot());
      this.binding = binding;
    }
  }
}
public class SlideLayoutManager extends LinearLayoutManager {

  private Context context;
  private RecyclerView recyclerView;
  private OnItemSelectedListener listener;

  public SlideLayoutManager(
      Context context,
      RecyclerView recyclerView,
      OnItemSelectedListener listener) {
    super(context);
    this.context = context;
    this.listener = listener;
    this.recyclerView = recyclerView;
  }

  @Override
  public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
    super.onLayoutChildren(recycler, state);
    scaleDownView();
  }

  @Override
  public void onScrollStateChanged(int state) {
    super.onScrollStateChanged(state);
    if (state == RecyclerView.SCROLL_STATE_IDLE) {
      float minDistance = recyclerView.getHeight();
      int position = -1;
      for (int i = 0; i < recyclerView.getChildCount(); i++) {
        View child = recyclerView.getChildAt(i);
        float distanceFromCenter = distanceFromCenter(child);
        if (distanceFromCenter < minDistance) {
          minDistance = distanceFromCenter;
          position = recyclerView.getChildLayoutPosition(child);
        }
        listener.onItemSelected(position);
      }
    }
  }

  @Override
  public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
    if (getOrientation() == LinearLayoutManager.VERTICAL) {
      int scrolled = super.scrollVerticallyBy(dy, recycler, state);
      scaleDownView();
      return scrolled;
    } else {
      return 0;
    }
  }

  private float distanceFromCenter(View child) {
      float mid = getHeight() / 2.0f;
      float childMid = (getDecoratedBottom(child) + getDecoratedTop(child)) / 2.0f;
      return Math.abs(mid - childMid);
  }

  private void scaleDownView() {
    for (int i = 0; i < getChildCount(); i++) {
      View child = getChildAt(i);
      TextView textView = child.findViewById(R.id.text);
      float distanceFromCenter = distanceFromCenter(child);
      float scale = (float) (1 - Math.sqrt(distanceFromCenter / getHeight()) * 0.33f);
      textView.setScaleX(scale);
      textView.setScaleY(scale);
    }
  }

  public interface OnItemSelectedListener {
    void onItemSelected(int layoutPosition);
  }
}

Comments (0)