Только 1 кнопка включена в ListView, пользовательский адаптер

Я столкнулся с проблемой, когда мне нужно включить мою кнопку в ListView. Странная вещь:

 public class CookingStepAdapter extends ArrayAdapter<CookingStep> {

...
       private void addButtonToList(Button clock, Button skip){
            if (list_clock_button == null) {
                list_clock_button = new ArrayList<Button>();
                iterate = 0;
            }
            if (list_skip_button == null)
                list_skip_button = new ArrayList<Button>();
            list_clock_button.add(clock);
            list_skip_button.add(skip);

            clock.setEnabled(true);
            skip.setEnabled(true);

            list_clock_button.get(0).setEnabled(true);
            list_clock_button.get(0).setFocusable(true);
            list_clock_button.get(0).setFocusableInTouchMode(true);
            list_clock_button.get(0).invalidate();

            list_skip_button.get(0).setEnabled(true);
            list_skip_button.get(0).setFocusable(true);
            list_skip_button.get(0).setFocusableInTouchMode(true);
            list_skip_button.get(0).postInvalidate();
        }
}

Когда я устанавливаю enable с помощью list_clock_button.get(0), он вообще не работает. Но clock.setEnabled(true); действительно сработало.

Но тогда я хочу, чтобы была включена только первая кнопка ListView, что делает первый вариант более подходящим в этой ситуации. Второй вариант работает, но он сделал все кнопки включенными, это не то, что я хочу. Я перепроверил адрес первой кнопки, и он совпал с list_clock_button.get(0), почему он не работает.

РЕДАКТИРОВАТЬ :

Вот моя функция getView:

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.cooking_steps_and_timer, parent, false);

        final Button button = (Button) rowView.findViewById(R.id.button_timer);
        final TextView timer = (TextView) rowView.findViewById(R.id.cooking_timer);
        final Button skipButton = (Button) rowView.findViewById(R.id.button_skip);
        TextView stepContent = (TextView) rowView.findViewById(R.id.cooking_step_content);

        final CookingStep step = list.get(position);
        String stepOrder = (String) context.getResources().getText(R.string.step_order) + " " + step.getOrder();
        String content = "<b>" + stepOrder + ":</b>" + " " + step.getContent() + "\n";
        stepContent.setText(Html.fromHtml(content));

        if (step.getTimer() == null || step.getTimer() == 0){
            timer.setVisibility(View.GONE);
            button.setVisibility(View.GONE);
            skipButton.setVisibility(View.GONE);
        } else {

            //myTimer = new CookingTimer(step.getTimer());
            timer.setText(step.getMyTimer().toString());
            step.setCountDown(new CountDownTimer(step.getTimer() * 60000, 1000) {
                @Override
                public void onTick(long millisUntilFinished) {
                    step.getMyTimer().tick();
                    timer.setText(step.getMyTimer().toString());
                }

                @Override
                public void onFinish() {
                    nextButtonEnable();
                }
            });

            button.setText(R.string.button_available);
            skipButton.setText(R.string.skip_button_content);

            addButtonToList(button, skipButton);
            //button.setEnabled(true);

            list_clock_button.get(0).setEnabled(true);

            button.requestFocusFromTouch();
            button.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if (event.getAction() == MotionEvent.ACTION_UP) {

                        if (!button.isPressed()) {
                            button.setPressed(true);
                            button.setText(R.string.button_available);
                            step.getCountDown().start();
                        } else {
                            button.setPressed(false);
                            button.setText(R.string.button_pressed);
                            step.getCountDown().cancel();

                        }
                    }
                    return true;
                }
            });

            skipButton.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        step.getCountDown().cancel();
                        nextButtonEnable();
                    }
                    return true;
                }
            });
        }
        return rowView;
    }

person Nguyen Quang Anh    schedule 04.09.2015    source источник


Ответы (1)


Причина, по которой все кнопки становятся активными, заключается в том, что вы настраиваете их все самостоятельно. Чтобы включить какую-либо конкретную кнопку, вы должны проверить идентификатор или позицию элемента, чтобы включить эту конкретную кнопку. Вот так например:-

if(clock.getID == R.id.some_id_in_xml){
    clock.setEnabled(true);
}

Но перед этим вы должны проверить положение элемента, чтобы выбрать нужный элемент в списке.

person Bilal Haider    schedule 04.09.2015
comment
Но я сохранил их в списке, и ссылки внутри этого списка совпадают со ссылками на кнопки. И (Кнопочные часы, Кнопочный пропуск), приобретенные final Button button = (Button) rowView.findViewById(R.id.button_timer); И, если то, что вы указали, является проблемой, то первые варианты тоже не должны работать. - person Nguyen Quang Anh; 04.09.2015
comment
можете ли вы предоставить код функции getView() вашего адаптера. - person Bilal Haider; 04.09.2015
comment
Я добавил свой getView в свой вопрос - person Nguyen Quang Anh; 04.09.2015
comment
Вам не нужно добавлять кнопки в список только для того, чтобы включить или отключить их. просто добавьте два члена данных в свой класс CookingStep, такие как isButtonEnable и isSkipButtonEnable, и установите там значения в соответствии с вашими потребностями, а затем установите свойства кнопок в соответствии с этими флагами. Потому что ListView всегда обновляет свой вид при прокрутке, и вам нужно сбросить все свойства в соответствии с массивом данных. в вашем случае CookingStep. - person Bilal Haider; 04.09.2015
comment
Это странно, даже если ListView сбрасывает все свойства, так как я сделал этот список статическим. То есть вы имеете в виду, что я не могу манипулировать данными внутри адаптера? Потому что я даже не знаю, где мне это сделать, как не внутри адаптера, так как только так я могу настроить прослушиватель кнопок. В списке много элементов, между этими элементами есть те, у кого есть кнопка, и те, у кого ее нет, поэтому я хочу, чтобы в начале была включена только одна кнопка, а затем, когда пользователь нажмет ее, она будет отключена и следующая кнопка будет включен. - person Nguyen Quang Anh; 04.09.2015
comment
Кое-как у меня получилось, но это не то, чего я хочу. Что я сделал, так это добавил 2 кнопки в свой объект данных, который является CookingStep, а затем вручную установил состояние включения кнопки внутри действия :( Есть ли еще какой-нибудь метод? Это не совсем чисто, мне кажется чушью , но это сработало! - person Nguyen Quang Anh; 04.09.2015
comment
Дело в том, что. ListView не меняет своих свойств, но элементы удаляются и добавляются при прокрутке вверх и вниз. Таким образом, должно быть какое-то место, где свойства элементов списка могут быть сохранены и могут быть доступны ListView при создании его элемента. То, что вы делаете, правильно, потому что вам нужно только изменить значения CookingStep, и listView установит свои элементы в соответствии с предоставленными данными. - person Bilal Haider; 07.09.2015
comment
подождите, я имею в виду, что я должен включить весь объект кнопки в свой класс данных CookingStep. Я пытался изменить состояние, используя только логическую переменную, но это не сработало. Я даже звонил invalidate() и postInvalidate, но кнопка не меняла состояния. Поэтому я должен включить кнопку внутри класса данных и включить ее вручную. - person Nguyen Quang Anh; 07.09.2015
comment
Ой. Вам не нужно этого делать. просто поместите логические переменные, и когда вы их измените, вызовите yourAdapter.notifyDataSetChanged(). Это обновит listView, и ваши элементы списка изменят свои свойства в соответствии с логическими значениями. - person Bilal Haider; 07.09.2015