public StickerAdapter(Context context, EmojiKeyboard keyboard, final ScrollTo scrollTo) {
    super(context);
    this.context = context;
    this.keyboard = keyboard;
    if (stickersCache == null) {
      stickersCache = new HashMap<Long, StickerView>();
    }
    this.scrollTo = scrollTo;

    // Build sticker lines
    stickerIndicatorContainer = keyboard.getStickerIndicatorContainer();
    stickerIndicatorContainer.setTag(TAG_KEY, 0);

    stickerInLine = (Screen.getWidth() / STICKER_SIZE);
    leftPadding = (Screen.getWidth() - (stickerInLine * STICKER_SIZE)) / 2;

    packFirstLineMap = new HashMap<Integer, Integer>();

    stickerSwitchLp = new LinearLayout.LayoutParams(Screen.dp(48), Screen.dp(48));
    padding = Screen.dp(8);

    packs = messenger().getOwnStickerPacks();

    ((BaseActivity) context)
        .bind(
            packs,
            new ValueChangedListener<ArrayList<StickerPackVM>>() {
              @Override
              public void onChanged(
                  ArrayList<StickerPackVM> val, Value<ArrayList<StickerPackVM>> valueModel) {
                buildStickerLines(scrollTo);
                notifyDataSetChanged();
              }
            });
  }
  private void buildStickerLines(final ScrollTo scrollTo) {

    // BUILD SWITCH
    keyboard.getStickerIndicatorContainer().removeAllViews();

    // Add pack switch buttons
    int packCount = 0;
    totalLines = 0;
    for (final StickerPackVM pack : packs.get()) {
      ((BaseActivity) context)
          .bind(
              pack.getStickers(),
              new ValueChangedListener<ArrayList<Sticker>>() {
                @Override
                public void onChanged(
                    ArrayList<Sticker> val, Value<ArrayList<Sticker>> valueModel) {
                  buildStickerLines(scrollTo);
                  notifyDataSetChanged();
                }
              },
              false);
      if (pack.getStickers().get().size() < 1) {
        continue;
      }
      // Count lines
      int linesInPack = (int) Math.ceil((double) pack.getStickers().get().size() / stickerInLine);
      totalLines += linesInPack;

      // Build packs buttons
      final StickerView sv = new StickerView(context);

      sv.bind(pack.getStickers().get().get(0).getFileReference128(), Screen.dp(48));
      sv.setPadding(padding, padding, padding, padding);
      sv.setOnClickListener(
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              scrollTo.requestScroll(packFirstLineMap.get(pack.getId()));
              selectCurrentPack((Integer) sv.getTag(TAG_KEY));
            }
          });
      sv.setTag(TAG_KEY, packCount);
      keyboard.getStickerIndicatorContainer().addView(sv, stickerSwitchLp);
      packCount++;
    }
    if (stickerIndicatorContainer.getChildAt(0) != null) {
      stickerIndicatorContainer
          .getChildAt(0)
          .setBackgroundColor(context.getResources().getColor(R.color.selector_selected));
    }

    // BUILD LINES
    // All lines stored here
    stickerLines = new StickerLine[totalLines];

    // Fill lines with packs stickers
    int allLinesCount = 0;
    int linePackCount = 0;
    for (StickerPackVM pack : packs.get()) {
      if (pack.getStickers().get().size() < 1) {
        continue;
      }
      int stickerInPack = 0;
      int linesInPack = (int) Math.ceil((double) pack.getStickers().get().size() / stickerInLine);

      // Loop pack lines
      for (int lineInPackCount = 0;
          lineInPackCount < linesInPack;
          lineInPackCount++, allLinesCount++) {
        StickerLine line = new StickerLine(new Sticker[stickerInLine], linePackCount);
        // Remember pack first line position
        if (lineInPackCount == 0) {
          packFirstLineMap.put(pack.getId(), allLinesCount);
        }
        // Fill line with stickers
        for (int stickerInLine = 0;
            stickerInLine < this.stickerInLine;
            stickerInLine++, stickerInPack++) {
          if (stickerInPack < pack.getStickers().get().size()) {
            line.getLine()[stickerInLine] = pack.getStickers().get().get(stickerInPack);
          } else {
            break;
          }
        }
        stickerLines[allLinesCount] = line;
      }
      linePackCount++;
    }
  }