Невозможно установить/снять флажок CheckedTextView внутри getView

Я загружаю телефонные контакты в пользовательский ListView. Каждая строка представляет собой проверяемый LinearLayout, содержащий CheckedTextView и другой TextView.

Я загружаю представление списка с помощью пользовательского ArrayAdapter. Моя проблема в том, что я не могу контролировать CheckedTextViews внутри getView(). Например, когда я пытаюсь сделать следующее

public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        if(row == null){            
            row = inflater.inflate(layout, parent, false);
        }

        CheckedTextView checkedTextView =  (CheckedTextView) row.findViewById(R.id.checkedTextView);
        checkedTextView.setText("A");
        checkedTextView.setChecked(true);
        return row;
    }

Это должно проверять каждое текстовое представление всякий раз, когда я прокручиваю представление списка, но этого не происходит. Кто-нибудь может сказать мне, как это сделать?

РЕДАКТИРОВАТЬ: важно проверить это внутри getView(), я не могу просто проверить все после setListAdapter()

EDIT2: это файл xml, показывающий представление каждой строки

<?xml version="1.0" encoding="utf-8"?>
<com.example.multiplecontacts.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <CheckedTextView
        android:id="@+id/checkedTextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:checkMark="?android:attr/listChoiceIndicatorMultiple"
        android:paddingBottom="0dp"
        android:text="CheckedTextView"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/subTextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Small Text"
        android:paddingTop="0dp"
        android:textAppearance="?android:attr/textAppearanceSmall" />

</com.example.multiplecontacts.CheckableLinearLayout>

CheckableLinearLayout — это настраиваемый макет, который расширяет LinearLayout и реализует Checkable, как я уже говорил. И я взял его из здесь


person Islam Hassan    schedule 28.09.2012    source источник
comment
Мне не нужно, чтобы он был проверен по умолчанию. На самом деле приведенный выше код не является моим фактическим кодом, это просто пример, демонстрирующий мою проблему. Все, что мне нужно, это иметь возможность переключать CheckedTextView внутри getView().   -  person Islam Hassan    schedule 28.09.2012
comment
У вас есть макет с checkbox, но когда вы нажимаете checkbox, он не проверяется?   -  person Trung Nguyen    schedule 28.09.2012
comment
После хорошего ответа Алекса Орлова я сделал так: public View getView(int position, View convertView, ViewGroup parent) {..... ((ListView) parent).setItemChecked(position, true);....}   -  person fox    schedule 22.07.2014


Ответы (3)


Вы установили свойство checkMark для вашего CheckedTextView в макете xml?

Например: android:checkMark="?android:attr/listChoiceIndicatorMultiple

CheckedTextView — это не просто флажок с текстом. Вы также должны отметить, что CheckedTextView нельзя сфокусировать или щелкнуть без каких-либо манипуляций (поскольку он был разработан для ListView, и поэтому его состояние должно контролироваться setOnItemClickListener ListView)

setChoiceMode должен быть установлен для ListView. И проверка строки внутри getView адаптера должна выполняться через: listView.setItemChecked(position, value)

person Alex Orlov    schedule 28.09.2012
comment
Я сделал. И он обычно проверяется / снимается, когда я сам нажимаю элемент. Это просто внутри getView(), которое ведет себя так. - person Islam Hassan; 28.09.2012
comment
Так можно управлять только в setOnItemClickListener?? нет способа переключить его вне его? - person Islam Hassan; 28.09.2012
comment
Где этот кусок кода должен быть написан? Я пытаюсь автоматически переключать checkedTextView, а не при выпуске события onClick. Я уже реализовал onListItemClick, и он работает хорошо. - person Islam Hassan; 28.09.2012
comment
Вероятно, CheckedTextView контролируется ListView, вы установилиChoiceMode на несколько для ListView? - person Alex Orlov; 28.09.2012
comment
Да, я сделал. И он ведет себя так, как предполагалось, и я могу выбрать несколько контактов. - person Islam Hassan; 28.09.2012
comment
если у вас есть доступ к экземпляру вашего ListView из адаптера, вы можете (и, вероятно, должны) использовать listView.setItemChecked(position, value) - person Alex Orlov; 28.09.2012
comment
Алексей Орлов, префект. Большое спасибо. Я передал экземпляр адаптеру и сделал то, что вы сказали. И теперь это работает как шарм. Пожалуйста, отредактируйте свой ответ и включите свой комментарий :) - person Islam Hassan; 28.09.2012
comment
Вы можете использовать ((ListView) parent).setItemChecked(position, true); из адаптера вместо передачи ссылки. - person Pier-Luc Gendreau; 13.03.2014

@Pier-Luc Gendreau и @fox упомянули решение в комментариях, но не в ответе, поэтому опубликовали ответ от их имени.

Как упоминал @AlexOrlov, CheckedTextView не фокусируется и не щелкает без каких-либо манипуляций. Итак, что вам нужно сделать, это установить проверку элемента с помощью ListView, вы можете сделать это либо из самого адаптера, либо из действия/фрагмента, где у вас есть ListView.

Чтобы сделать это с адаптера,

public View getView(int position, View convertView, ViewGroup parent) 
{ 
if (//logic) {
((ListView) parent).setItemChecked(position, true);
}
}

Из активности/фрагмента

if (//logic) {
listView.setItemChecked(position, true);
}
person Rohan Kandwal    schedule 27.02.2017

Когда вы прокручиваете список, каждый раз он вызывает метод getview(). Итак, если у вас есть какой-либо флажок или поле редактирования в listcell, он повторно инициализирует его.

Моя идея состоит в том, чтобы сохранить статус флажка (отмечен или не отмечен). Итак, здесь я использовал ArrayList, сначала я заполнил его ложным значением, а затем в его событии щелчка я использовал его для сохранения фактического состояния.

 class MyAdapter extends BaseAdapter  implements OnClickListener   {

    private ArrayList<Boolean> checks=new ArrayList<Boolean>();//Boolean type array to   manage check box

  private static LayoutInflater inflater=null;

    public MyAdapter(Context context, ArrayList<HashMap<String, String>> d)
    {
              inflater =     (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

      //fill with false values
    for (int i = 0; i < d.size(); i++) 
    {
            checks.add(i, false);
    }
    }

    public int getCount()
    {
        return data.size();
    }

    public Object getItem(int position)
    {
        return position;
    }

    public long getItemId(int position) 
    {
        return position;
    }




        public View getView(int position, View convertView, ViewGroup parent)
       {

        View vi=convertView;

        if(convertView==null)

          vi = inflater.inflate(R.layout.<your layout>, null);

          //Checkbox is of button type----android:button="@drawable/btn_check"
          //make a selector xml for checkbox       

          checkBox=(CheckBox)vi.findViewById(R.id.check_box);


          checkBox.setTag(Integer.valueOf(position));
          checkBox.setOnClickListener(this);
          checkBox.setChecked(checks.get(position));


        return vi;
    }

        @Override
        public void onClick(View v) 
        {
          int viewId=v.getId();
          if(viewId== R.id.check_box)
          {
            Integer index = (Integer)v.getTag();
            boolean state = checks.get(index.intValue());
            checks.set(index.intValue(), !state);

          }
        }
     }

Обновление: Решение 2. Вы можете поместить логическую переменную в свой класс ViewHolder. Эта логическая переменная будет использоваться для определения того, выбран элемент или нет.

Надеюсь, это должно помочь вам.

person Akhilesh Mani    schedule 28.09.2012
comment
checkBox.setChecked (checks.get (позиция)); это у вас работает? CheckBox типа CheckedTextView или просто флажок? - person Islam Hassan; 28.09.2012
comment
@IslamHassan да, это работает на моей стороне. Здесь мой флажок имеет тип кнопки. - person Akhilesh Mani; 28.09.2012