Повторное использование одного и того же ListView для отображения разных данных - PullRequest
2 голосов
/ 01 апреля 2012

ListViews всегда был моим слабым местом, и сейчас я практикую ставить Listview в пределах Listview. В любом случае, я сначала вызываю мой ListView в начале моей программы, и он загружает его с массивом, сохраненным в моем strings.xml:

String[] departments = getResources().getStringArray(
                R.array.departments_array);
        setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item,
                departments));
        setContentView(R.layout.main);

        ListView lv = getListView();
        lv.setTextFilterEnabled(true);

Я хочу обновить ListView новым массивом значений при каждом нажатии элемента списка. Причина, по которой я пытаюсь сделать это таким образом, заключается в том, что я планирую иметь 27 разных массивов с разными значениями для каждой позиции, и я чувствую, что это будет легче для моих ресурсов, если вместо ListView для каждого массива элементов Я бы обновил этот ListView. Я знаю, что, возможно, я делаю это не самым эффективным способом, но если есть другой способ реализации моей идеи, пожалуйста, сообщите мне.

   lv.setOnItemClickListener(new OnItemClickListener() {
                public void onItemClick(AdapterView<?> parent, View view,
                        int position, long id) {
                    // When clicked, show a toast with the TextView text
                    switch (position) {
                    case 0:
                        try {


    //It is here that i dont know what to do, I was going to call 
//the Listview the same way i did previously using my setlistadapter, 
//but i kept getting errors about the code being undefined


                            String[] listitems1 = getResources().getStringArray(
                                    R.array.items_array);

                        } catch (ClassCastException e) {
                            Toast.makeText(getApplicationContext(), "Error",
                                    Toast.LENGTH_SHORT).show();
                        }
                        break;
                    case 1:
                        try {
                      //The listview will be changed again here
                        } catch (ClassCastException e) {
                            Toast.makeText(getApplicationContext(), "Error",
                                    Toast.LENGTH_SHORT).show();
                        }
                        break;
                    }
                };

            });

Ответы [ 3 ]

2 голосов
/ 01 апреля 2012

Задумывались ли вы об использовании BaseAdapter и установке его в качестве адаптера списка http://developer.android.com/reference/android/widget/BaseAdapter.html

1 голос
/ 02 апреля 2012

Ответ Luksprog действительно верный, и он очень полезен для списков с несколькими уровнями глубины (вы не устанавливаете лимиты, просто продолжаете создавать новые экземпляры действий с соответствующим загруженным списком)

НО

Если ваш список не превышает 2 уровня, вы можете использовать ExpandableListActivity вместо ListActivity, который в основном представляет собой расширенную версию одноуровневого списка, который вы используете, который изначально обрабатывает свертывание / развертывание групп, и поэтому вам не требуется порождениенового действия для каждого подуровня.

еще раз обратите внимание, что этот подход работает только для списков, которые не идут глубже, чем 2 уровня

И вот у вас есть некоторые хорошиепример из самого Google:

public class ExpandableList3 extends ExpandableListActivity {
    private static final String NAME = "NAME";
    private static final String IS_EVEN = "IS_EVEN";

    private ExpandableListAdapter mAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
        List<List<Map<String, String>>> childData = new ArrayList<List<Map<String, String>>>();
        for (int i = 0; i < 20; i++) {
            Map<String, String> curGroupMap = new HashMap<String, String>();
            groupData.add(curGroupMap);
            curGroupMap.put(NAME, "Group " + i);
            curGroupMap.put(IS_EVEN, (i % 2 == 0) ? "This group is even" : "This group is odd");
            //filling with dummy data...
            List<Map<String, String>> children = new ArrayList<Map<String, String>>();
            for (int j = 0; j < 15; j++) {
                Map<String, String> curChildMap = new HashMap<String, String>();
                children.add(curChildMap);
                curChildMap.put(NAME, "Child " + j);
                curChildMap.put(IS_EVEN, (j % 2 == 0) ? "This child is even" : "This child is odd");
            }
            childData.add(children);
        }

        // Set up our adapter
        mAdapter = new SimpleExpandableListAdapter(
            this,
            groupData,
            android.R.layout.simple_expandable_list_item_1,
            new String[] { NAME, IS_EVEN },
            new int[] { android.R.id.text1, android.R.id.text2 },
            childData,
            android.R.layout.simple_expandable_list_item_2,
            new String[] { NAME, IS_EVEN },
            new int[] { android.R.id.text1, android.R.id.text2 }
            );
        setListAdapter(mAdapter);
    }

}
1 голос
/ 01 апреля 2012

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

Небольшой пример:

Основной класс:

/**
 * The main class with the initial 27 items array.
 */
public class Class1 extends ListActivity {

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        // start the second activity that will show our array depending on the
        // position clicked
        Intent i = new Intent(this, Class2.class);
        // put the position in the Intent so we can know in the other activity
        // what array to load.
        i.putExtra("pos", position);
        startActivity(i);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // I just used a simple array of 2 items, you'll load your 27 items
        // array
        String[] items = { "1", "2" };
        setListAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, items));
    }

}

Вторичное действие, которое будет отображать массив на основеранее выбранная позиция:

public class Class2 extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // get the Intent that started the activity
        Intent i = getIntent();
        // find out what position did that other activity send to us.
        int position = i.getIntExtra("pos", -1);
        // load the ListView with an adapter based on the array that you
        // want(according to that position)
        if (position == 0) {
            // the first element in the main list
            String[] items = getResources().getStringArray(R.array.a1);
            setListAdapter(new ArrayAdapter<String>(this,
                    android.R.layout.simple_list_item_1, items));
        } else if (position == 1) {
            // the second element in the main list
            String[] items = getResources().getStringArray(R.array.a2);
            setListAdapter(new ArrayAdapter<String>(this,
                    android.R.layout.simple_list_item_1, items));
        } else {
            // etc
        }
    }

}
...