CheckedTextViews будут случайным образом отображаться в списке, если я нажму еще один вверх по списку - PullRequest
2 голосов
/ 18 марта 2012

Хорошо, так что на этом сайте много было сказано, однако я не верю, какая именно проблема в том, что использует мой код.Я заполняю listView с CheckedTextViews, который работает полностью.Однако, когда я нажимаю на элемент, он проверяется, но когда я прокручиваю вверх и вниз, случайные строки также проверяются.Я понимаю, что это должно быть связано с тем, как ListView отслеживает элементы.Я сталкиваюсь с некоторыми ошибками в данный момент.Я попытался заполнить хэш-карту списком строк, чтобы я мог отслеживать, какой из них установлен в true, а какие в false.Однако я не уверен, где реализовать карту и попытаться заполнить ее.

Вот мой OnCreate

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.viewmenu);

    //Get table name of menu clicked. 
    Bundle extras = getIntent().getExtras();
    tableName = extras.getString("table");

    // map each contact's name to a TextView in the ListView layout
    String[] from = new String[] { "name" };
    int[] to = new int[] { R.id.toppingCheckedTextView };

    for(int i=0; i< from.length; i++){
        map.put(i, false);
    }

    contactAdapter = new SimpleCursorAdapter(
            ViewToppingListing.this, R.layout.toppings_list_item, null, from, to);
    setListAdapter(contactAdapter); // set contactView's adapter
 } 

Я пытаюсь поместить карту в onCreate, чтобы заполнить ее, однако она жалуется на нулевой указатель.

Здесь я попробовал использовать метод OnListItemClick

 @Override
protected void onListItemClick(ListView arg0, View arg1, int arg2, long arg3){      
    final int index = arg2 - arg0.getFirstVisiblePosition();
    View v = arg0.getChildAt(index);
    CheckedTextView ctv = (CheckedTextView) v.findViewById(R.id.toppingCheckedTextView);

    if((Boolean)map.get(index) == true){
        ctv.setChecked(true);
        ctv.setVisibility(View.VISIBLE);

    } else{
        ctv.setVisibility(View.GONE);
    }   

} 

Я много читал об этом, и кажется, что многие решения включают использование getView (), однако я не знаюесли это относится к моей ситуации.Любая помощь будет принята с благодарностью!

1 Ответ

1 голос
/ 18 марта 2012

Прежде всего вам нужен SimpleCursorAdapter? Вы устанавливаете адаптер с помощью курсора null:

contactAdapter = new SimpleCursorAdapter(
            ViewToppingListing.this, R.layout.toppings_list_item, null, from, to); // the third parameter is the cursor and you set it to null!

Поведение, которое вы видите из-за ListView, перерабатывает представления, и да, вам придется реализовать собственный адаптер и переопределить bindView(). Приведенный ниже код основан на другом ответе на аналогичный вопрос, может быть, вы захотите посмотреть на него ( Получение выбранного представления из ListView ). Вот пример:

public class TestCursorAdapter extends ListActivity {

    MySimpleAdapter adapter;
    private HashMap<Long, Boolean> positionHide = new HashMap<Long, Boolean>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String[] columns = new String[] { "_id", "name" };
        MatrixCursor mc = new MatrixCursor(columns); // cursor for testing
        for (int i = 1; i < 35; i++) {
            long id = i;
            mc.addRow(new Object[] { id, "Name" + i });
        }
        String[] from = new String[] { "name" };
        int[] to = new int[] { R.id.checked_text };
        adapter = new MySimpleAdapter(this,
                R.layout.adapter_mysimpleadapter_row, mc, from, to);
        setListAdapter(adapter);
    }

    private class MySimpleAdapter extends SimpleCursorAdapter {

        public MySimpleAdapter(Context context, int layout, Cursor c,
                String[] from, int[] to) {
            super(context, layout, c, from, to);
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            super.bindView(view, context, cursor);
            CheckedTextView ctv = (CheckedTextView) view
                    .findViewById(R.id.checked_text);
            long pos = cursor.getLong(0); // the id from the cursor
            if (positionHide.get(pos) == null) {
                ctv.setChecked(false);
                // we don't have this id in the hashmap so the value is by
                // default false, the TextView is GONE
            } else {
                // we have the value in the Hashmap so see what it is and set
                // the textview visibility from this value
                Boolean tmp = positionHide.get(pos);
                if (tmp.booleanValue()) {
                    ctv.setChecked(true);
                } else {
                    ctv.setChecked(false);
                }
            }

        }

    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Boolean tmp = positionHide.get(id);
        if (tmp == null) {
            // if null we don't have this key in the hashmap so
            // we add it with the value true
            positionHide.put(id, true);
        } else {
            positionHide.put(id, !tmp.booleanValue());
            // if the value exists in the map then inverse it's value
        }
        adapter.notifyDataSetChanged(); // notify the adapter that something has
                                        // changed
    }
}
...