FlexboxLayout - Показать количество тегов или чипов или меток в конце второй строки Android

Я использую FlexboxLayout для отображения чипов в Android, но застрял в пользовательском интерфейсе, где я хочу показать количество чипов в конце второй строки, как показано ниже на снимке экрана введите здесь описание изображения

В соответствии с приведенным выше дизайном я хочу показывать фишки до второй строки, а фишки, которые не помещаются во вторую строку, должны увеличивать количество фишек в конце фишек.

У меня есть чек

1- FlexboxLayout setMaxLine(2); Но в этом случае пользовательский интерфейс рисует только две строки, а вторая строка растягивается

2- FlexboxLayout getFlexLineInternel() — этот API дает неверный результат. Количество строк увеличивается после добавления 1 элемента в строку, затем он дает getFlexLineInternel().size() == 2, это означает, что представление уже добавлено в третью строку, но я хочу ограничить только 2 строки .

3- Попробуйте с материалом Chip and ChipGroup. Мне не дали количество линий, отрисованных в ChipGroup.

4. Попробуйте использовать Flowlayout, аналогичный ChipGroup. Не дал мне количество строк, отрисованных макетом, чтобы я мог показать счет в конце второй строки

Подскажите, пожалуйста, что может помочь в моей ситуации

Вот мой код

activity_search_label.xml

<com.google.android.flexbox.FlexboxLayout
      android:id="@+id/assetLabelsContainer"
      android:layout_width="match_parent"
      android:layout_marginLeft="@dimen/size_16"
      android:layout_marginRight="@dimen/size_16"
      android:layout_height="wrap_content"
      app:flexWrap="wrap"/>

LabelSearchActivity.java

   public class LabelSearchActivity extends SearchActivity {

  @BindView(R.id.assetLabelsContainer)
  public FlexboxLayout assetLabelsContainer;

  private int COUNTER_LABEL_ID = -1;
  private ArrayList<LabelModelParcelableItem> selectedLabels;
  private ArrayList<LabelModelParcelableItem> visibleSelectedList;
  private CompositeDisposable disposables;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ButterKnife.bind(this);
    clearLabelList();
    showSelectedLabel();
  }

  public void hideSearchTitleCountView() {
    if (null != searchTitle) {
      searchTitle.setVisibility(View.GONE);
    }
  }

  private void clearLabelList() {
    selectedLabels = new ArrayList<>();
    visibleSelectedList = new ArrayList<>();
    assetLabelsContainer.getFlexLinesInternal().clear();
    assetLabelsContainer.removeAllViews();
  }

  private void showSelectedLabel() {
    if (getIntent() != null) {
      Bundle bundle = getIntent().getExtras();
      if (bundle.getParcelableArrayList(SELECTED_LABEL_ITEMS) != null) {
        ArrayList<LabelModelParcelableItem> selectedLabels = bundle
            .getParcelableArrayList(SELECTED_LABEL_ITEMS);
        showLabelList(selectedLabels);
      }
    }
  }

  public void addViewToFlex(final LabelModelParcelableItem labelModelParcelableItem) {
    if (!selectedLabels.contains(labelModelParcelableItem)) {
      selectedLabels.add(labelModelParcelableItem);
      final View view = getChipView(labelModelParcelableItem);
      if (shouldShowCount()) {
        View countView = getCounterView();
        if (null != countView) {
          LabelModelParcelableItem tag = (LabelModelParcelableItem) countView.getTag();
          LabelModelParcelableItem updatedTag =
              new LabelModelParcelableItem(
                  tag.getLabelId(), String.valueOf(getInvisibleItemCount()), tag.getAssetCount());
          TextView textView = (TextView) countView.findViewById(R.id.labelNameText);
          textView.setText(" + " + updatedTag.getLabelName());
          countView.setTag(updatedTag);
          assetLabelsContainer.requestLayout();
        } else {
          addCounterView();
        }
      } else {
        visibleSelectedList.add(labelModelParcelableItem);
        assetLabelsContainer.addView(view);
      }
    }
  }

  public int getInvisibleItemCount() {
    ArrayList<LabelModelParcelableItem> itemList = new ArrayList<>(selectedLabels);
    itemList.removeAll(visibleSelectedList);
    return itemList.size();
  }

  private void addCounterView() {
    final View view =
        LayoutInflater.from(LabelSearchActivity.this)
            .inflate(R.layout.label, assetLabelsContainer, false);
    LabelModelParcelableItem item =
        new LabelModelParcelableItem(
            COUNTER_LABEL_ID, String.valueOf(getInvisibleItemCount()), COUNTER_LABEL_ID);
    view.setTag(item);
    TextView textView = (TextView) view.findViewById(R.id.labelNameText);
    textView.setText(" + " + item.getLabelName());
    view.setOnClickListener(v -> showLabelContainerScreen(getSelectedLabels()));
    if (getInvisibleItemCount() > 0) {
      assetLabelsContainer.addView(view);
    }
  }

  public View getChipView(final LabelModelParcelableItem item) {
    final View view =
        LayoutInflater.from(LabelSearchActivity.this)
            .inflate(R.layout.label, assetLabelsContainer, false);
    TextView textView = (TextView) view.findViewById(R.id.labelNameText);
    textView.setText(item.getLabelName());
    view.setOnClickListener(v -> removeViewFormFlex(view, item));
    return view;
  }

  private boolean shouldShowCount() {
    if (assetLabelsContainer.getFlexLinesInternal().size() > 2) {
      return true;
    }
    return false;
  }

  private void updatedLabelAfterRemove() {
    if (null != getCounterView()) {
      if (getInvisibleItemCount() > 0) {
        ArrayList<LabelModelParcelableItem> itemList = new ArrayList<>(selectedLabels);
        itemList.removeAll(visibleSelectedList);
        Collections.sort(itemList, (o1, o2) -> o2.getLabelName().compareTo(o1.getLabelName()));
        if (!itemList.isEmpty()) {
          addViewAfterRemove(itemList.get(0));
        }
      } else {
        assetLabelsContainer.removeView(getCounterView());
      }
    }
  }

  private void addViewAfterRemove(LabelModelParcelableItem item) {
    final View labelView = getChipView(item);
    View countView = getCounterView();
    if (countView != null) {
      assetLabelsContainer.removeView(countView);
      visibleSelectedList.add(item);
      assetLabelsContainer.addView(labelView);
      addCounterView();
    } else {
      visibleSelectedList.add(item);
      assetLabelsContainer.addView(labelView);
    }
  }

  private View getCounterView() {
    View countView =
        assetLabelsContainer.getFlexItemAt(assetLabelsContainer.getFlexItemCount() - 1);
    if (null != countView) {
      LabelModelParcelableItem item = (LabelModelParcelableItem) countView.getTag();
      if (item != null && item.getLabelId() == -1) {
        return countView;
      }
    }
    return null;
  }

  private void showLabelList(ArrayList<LabelModelParcelableItem> selectedLabels) {
    for (LabelModelParcelableItem item : selectedLabels) {
      addViewToFlex(item);
      assetLabelsContainer.post(() -> assetLabelsContainer.requestLayout());
    }
  }

  public void addSelectedLabel(Parcelable label) {
    addViewToFlex((LabelModelParcelableItem) label);
  }

  public ArrayList<LabelModelParcelableItem> getSelectedLabels() {
    return selectedLabels;
  }

  public List<Parcelable> getUpdatedLabelList(List<? extends Parcelable> newParcelableList) {
    if (null != newParcelableList && !newParcelableList.isEmpty()) {
      newParcelableList.removeAll(getSelectedLabels());
      return new ArrayList<>(newParcelableList);
    } else {
      return new ArrayList<>();
    }
  }

  public void labelUpdateList(List dataList) {
    getSearchAdapter().clearAndUpdateList(dataList);
  }

  @Override
  public void onBackButtonPressed() {
    setActivityResult(getSelectedLabels());
  }

  public void setActivityResult(ArrayList<? extends Parcelable> searchableItem) {
    setResult(RESULT_OK, new Intent().putParcelableArrayListExtra(SEARCH_RESULT, searchableItem));
    super.onBackButtonPressed();
  }

  public void addDisposable(Disposable disposable) {
    if (null == disposables) {
      disposables = new CompositeDisposable();
    }
    disposables.add(disposable);
  }

  @Override
  public void onDestroy() {
    if (disposables != null && !disposables.isDisposed()) {
      disposables.clear();
    }
    super.onDestroy();
  }

  private void showLabelContainerScreen(List<? extends Parcelable> labels) {
    Intent intent = new Intent(this, ViewLabelsActivity.class);
    Bundle bundle = new Bundle();
    bundle.putParcelableArrayList(
        LabelSelectionActivity.ARGUMENT_KEY, (ArrayList<? extends Parcelable>) labels);
    intent.putExtras(bundle);
    startActivityForResult(intent, LabelSelectionActivity.VIEW_ALL_LABEL_CODE);
  }

  @Override
  public void onBackPressed() {
    if (!getSelectedLabels().isEmpty()) {
      Intent intent = new Intent();
      intent.putParcelableArrayListExtra(
          SELECTED_LABEL_ITEMS, (ArrayList<? extends Parcelable>) getSelectedLabels());
      setResult(Activity.RESULT_OK, intent);
    } else {
      this.finish();
    }
    super.onBackPressed();
  }

  @OnClick(R.id.navBarBack)
  public void onBackButton() {
    onBackPressed();
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode != LabelSelectionActivity.VIEW_ALL_LABEL_CODE) {
      return;
    }
    if (data == null) {
      return;
    }
    if (resultCode != RESULT_OK) {
      return;
    }
    if (!data.hasExtra(SELECTED_LABEL_ITEMS)) {
      return;
    }
    clearLabelList();
    ArrayList<LabelModelParcelableItem> selectedLabels =
        data.getParcelableArrayListExtra(SELECTED_LABEL_ITEMS);
    showLabelList(selectedLabels);
    updateAfterViewAllLabels(selectedLabels);
  }

  private void updateAfterViewAllLabels(ArrayList<LabelModelParcelableItem> labelsAfterRemoved) {
    ArrayList<LabelModelParcelableItem> listOfRemovedLabels = new ArrayList<>(getSelectedLabels());
    listOfRemovedLabels.removeAll(labelsAfterRemoved);
    for (LabelModelParcelableItem item :  labelsAfterRemoved) {
      //removeViewFormFlex(item);
    }
  }

  public void removeViewFormFlex(View view, LabelModelParcelableItem item) {
    if (selectedLabels.remove(item)) {
      if (selectedLabels.isEmpty()) {
        assetLabelsContainer.removeAllViews();
      } else {
        visibleSelectedList.remove(item);
        assetLabelsContainer.removeView(view);
      }
      updatedLabelAfterRemove();
      Comparator<LabelModelParcelableItem> compareByName =
          (o1, o2) -> o1.getLabelName().compareTo(o2.getLabelName());
      getSearchAdapter().addLabelItemToList(item, compareByName);
    }
  }
}

В соответствии с приведенным выше кодом это выглядит как изображение ниже

введите здесь описание изображения


person sushant gosavi    schedule 11.06.2019    source источник


Ответы (1)


попробуйте измерить высоту FlexboxLayout после каждого flexboxLayout.addView(view), и если ширина увеличилась, это означает, что вы находитесь во второй строке.

person Mohammad Sommakia    schedule 11.06.2019
comment
тот же код присутствует в API getFlexLineInternel() после вызова addView() означает, что представление уже добавлено в третью строку, я не хочу добавлять третью строку, я хочу проверить, прежде чем представление будет добавлено в третью строку после добавления строки представления увеличивается или нет - person sushant gosavi; 11.06.2019
comment
во-первых, извините, я имею в виду высоту, а не ширину, я обновил ответ - person Mohammad Sommakia; 11.06.2019
comment
во-вторых, когда вы измеряете гибкий макет и когда высота увеличивается в первый раз, вы находитесь во второй строке, хорошо? - person Mohammad Sommakia; 11.06.2019
comment
затем вы получите ширину каждого вида, который вы добавляете, и вы получите ширину экрана и подставите его из представлений во вторых строках, и если результат отрицательный, это означает, что вы дойдете до конца строки, надеюсь, что это поможет вам - person Mohammad Sommakia; 11.06.2019
comment
так это помощь? - person Mohammad Sommakia; 11.06.2019
comment
Не помогайте, это усложняется, отступы для просмотра и пространство между представлениями не позволяли мне это сделать. - person sushant gosavi; 13.06.2019
comment
уверен, что вы должны учитывать отступы и поля для каждого представления - person Mohammad Sommakia; 13.06.2019