Динамически добавлять и скрывать текстовые представления

У меня есть цикл "для каждого", который создает textView для каждого объекта из списка и добавляет их в линейный макет. Работает отлично. Затем я хочу скрыть все textViews, когда пользователь нажимает на кнопку переключения, но здесь у меня есть проблема - скрывается только последний textView из списка, остальные все еще видны. Я пытался решить эту проблему с помощью многих решений (например, с помощью getChild()), но ничего не работает.

final List<FilterItem> filterItemList = filterData.getFilterItemList();
for (FilterItem filterItem : filterItemList) {
    final TextView filter = new TextView(MainPanelActivity.this);
    filter.setText(filterItem.getFilterItemName());
    filter.setTextColor(R.color.black);
    linearLayout.addView(filter);
    filter.setVisibility(View.GONE);
    textLine.setOnCheckedChangeListener(
            new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (isChecked) {
                       filter.setVisibility(View.VISIBLE);
                    } else {
                       filter.setVisibility(View.GONE);             
                    }
                }
    });

3 ответа

Решение

Обратите внимание, что вы устанавливаете слушателя для textLine внутри цикла for - поэтому для каждой итерации вы устанавливаете нового слушателя, который изменяет видимость TextView создан в текущем итераторе.

Переехать textLine.setOnCheckedChangeListener() вне цикла for; и внутри onCheckedChanged - перебрать всех детей linearLayout и установить видимость для каждого ребенка.

textLine.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    for (View v : linearLayout.getChildren()) {
                        if (v instanceof TextView) {
                            if (isChecked) {
                                v.setVisibility(View.VISIBLE);
                            } else {
                                v.setVisibility(View.GONE);                
                            }
                        }
                    }

Вы можете сохранить список TextViews при их создании. Затем установите прослушиватель щелчков вне цикла for, как говорит Дмитрий, который будет перебирать список TextViews и устанавливать видимость GONE.

private void setup() {
    List<View> textViews = new ArrayList<>();
    for (FilterItem filterItem : filterData.getFilterItemList()) {
        View view = createTextViewFor(filterItem);
        linearLayout.addView(filter);

        textViews.add(view);
    }

    updateVisibility(textViews, View.GONE);

    textLine.setOnCheckedChangeListener(
            new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    int visibility = isChecked ? View.VISIBLE : View.GONE;
                    updateVisibility(textViews, visibility);
                }
            }
    );
}

private View createTextViewFor(FilterItem filterItem) {
    TextView view = new TextView(MainPanelActivity.this);
    view.setText(filterItem.getFilterItemName());
    view.setTextColor(R.color.black);
    view.addFilter(filterItem);
    return view;
}

private void updateVisibility(List<View> views, int visibility) {
    for (View view : views) {
        view.setVisibility(visibility);
    }
}

Если вы хотите отобразить textView динамически, я думаю, положить textView внутри RecyclerView будет лучшей идеей. RecyclerView имеет свой Adapter что позволит легко играть с данными и textViews, Дать recyclerView попытка RecycerView то, что вы пытаетесь сделать, может быть изучено за несколько часов, а небо - это предел того, что вы можете сделать с recyclerView:)

Другие вопросы по тегам