Як додавати елементи до спискуДінамічно переглядайте в Android


326

Хтось може пояснити чи запропонувати підручник для створення listView в android?

Ось мої вимоги:

  • Я повинен мати можливість динамічно додавати нові елементи, натискаючи кнопку.
  • Має бути досить простим, щоб зрозуміти (можливо, без будь-яких покращень продуктивності чи перегляду, наприклад, перегляду)

Я знаю, що на цю тему є досить багато питань, розміщених тут на StackOverflow, але не вдалося знайти жодного, який би відповів на моє запитання. Дякую!


3
Зараз відповідь «Шардул» з найбільш високим голосом вважається високою якістю, і користувачі висловлюють, що вважають, що це слід прийняти. Ви можете розглянути можливість прийняття?
Метт Уельк

Відповіді:


583

Створіть спочатку макет XML у res/layout/main.xmlпапці вашого проекту :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <Button
        android:id="@+id/addBtn"
        android:text="Add New Item"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:onClick="addItems"/>
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:drawSelectorOnTop="false"
    />
</LinearLayout>

Це простий макет з кнопкою вгорі і списком внизу. Зауважте, що ListViewмає ідентифікатор, @android:id/listякий визначає типовий ListViewзасіб, який ListActivityможе використовуватись.

public class ListViewDemo extends ListActivity {
    //LIST OF ARRAY STRINGS WHICH WILL SERVE AS LIST ITEMS
    ArrayList<String> listItems=new ArrayList<String>();

    //DEFINING A STRING ADAPTER WHICH WILL HANDLE THE DATA OF THE LISTVIEW
    ArrayAdapter<String> adapter;

    //RECORDING HOW MANY TIMES THE BUTTON HAS BEEN CLICKED
    int clickCounter=0;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);
        adapter=new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1,
            listItems);
        setListAdapter(adapter);
    }

    //METHOD WHICH WILL HANDLE DYNAMIC INSERTION
    public void addItems(View v) {
        listItems.add("Clicked : "+clickCounter++);
        adapter.notifyDataSetChanged();
    }
}

android.R.layout.simple_list_item_1 це макет елементів списку за замовчуванням, наданий Android, і ви можете використовувати цей макет запасів для складних речей.

listItemsце Список, який містить дані, показані в ListView. Все вставлення та видалення слід робити на listItems; зміни listItemsповинні відображатися в погляді. Це обробляється ArrayAdapter<String> adapter, про що слід повідомити, використовуючи:

adapter.notifyDataSetChanged();

Адаптер створений з 3 параметрами: контекст, який може бути вашим activity/listactivity; макет вашого окремого списку; і нарешті, список, який є фактичними даними, які відображатимуться у списку.


2
Я не розумію, як ListView приєднується до нашої діяльності тут.
Breedly

7
@Breedly Тому що це ListActivity, а не діяльність, яка має макет із ListView . Не потрібно знаходити подання ідентифікатора. Як ви можете прочитати на засланні: ListActivity is an activity that includes a ListView as its only layout element by default. [...] (it) hosts a ListView object. Отже, за замовчуванням методи (як setAdapter тощо) знаходяться "всередині" Класу.
fllo

Давайте покажемо щастя, коли буде отримана правильна відповідь: /
support_ms

1
Якщо елемент у ArrayList є складнішим, наприклад завантаженням з Інтернету, і кожен елемент містить відеозаписи та щось подібне, чи вдарить цей підхід до продуктивності?
zionpi

1
Як я міг реалізувати це у фрагменті?
Оамар Канджі

64

замість

listItems.add("New Item");
adapter.notifyDataSetChanged();

можна безпосередньо зателефонувати

adapter.add("New Item");

@gumuruh сам адаптер може змінюватися, тому ми можемо безпосередньо додавати або видаляти об'єкти, які викликають notifyDatasetChanged () та getView () listView автоматично. Це зменшує зайвий рядок коду.
venkat530

тож додавши в адаптер автоматично виклик notifyDatasetChanged ()? О Я бачу. Дякую @ venkat530. А як щодо самого списку? Я маю на увазі, якщо скажімо, по-перше, він створив масив архітектури, який використовував як контейнер даних для адаптера. А тепер ви просто додаєте елемент безпосередньо до адаптера, а не до масиву. Чи оновлюються / недоторкаються дані масиву?
gumuruh

1
@gumuruh другий - найкраща практика, оскільки він синхронізований.
Рікардо

1
@gumuruh з експериментального експерименту та вихідного коду ArrayAdapter [ github.com/android/platform_frameworks_base/blob/master/core/… , схоже, базовий набір даних також буде змінено.
CCJ

Я отримав відповідь Шардула, потім зламав її і не міг зрозуміти, як її відремонтувати. За примхою, я думав, що спробую це, і вуаля, це знову працює! Дуже дякую! Хоча я поняття не маю, як і чому це виправили. Будь-яка ідея?
donutguy640

55

По-перше, вам слід додати ListView, EditText та кнопку у свою Activity_main.xml.

Тепер у вашій Основній діяльності:

private EditText editTxt;
private Button btn;
private ListView list;
private ArrayAdapter<String> adapter;
private ArrayList<String> arrayList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    editTxt = (EditText) findViewById(R.id.editText);
    btn = (Button) findViewById(R.id.button);
    list = (ListView) findViewById(R.id.listView);
    arrayList = new ArrayList<String>();

    // Adapter: You need three parameters 'the context, id of the layout (it will be where the data is shown),
    // and the array that contains the data
    adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, arrayList);

    // Here, you set the data in your ListView
    list.setAdapter(adapter);

    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            // this line adds the data of your EditText and puts in your array
            arrayList.add(editTxt.getText().toString());
            // next thing you have to do is check if your adapter has changed
            adapter.notifyDataSetChanged();
        }
    });
}

Це працює для мене, сподіваюся, я вам допомогла


4
Дуже гарне пояснення та дякую особливо за пояснення елемента адаптера - який, здається, магічним чином з’являється у всіх інших прикладах. :)
raddevus

1
Це найкращий приклад, який я знайшов для цього :)
Dinuka Salwathura

Ця відповідь задовольняла те, що людина просила. Простий та чистий без складних удосконалень. Верхня відповідь насправді вводить ListActivity, про яку знають лише великі майстри. Моя єдина проблема зараз полягає в тому, як додати малюнки та речі до представлень у списку. Мені здається, я додаю лише рядки.

Оптимізацією може бути створення безіменного об'єкта List у Adapter, ніж створення 16-бітового вказівника на об’єкт списку. Що не потрібно після створення адаптера, оскільки адаптер має метод додавання.

17

Якщо ви хочете мати ListView в AppCompatActivity замість ListActivity, ви можете зробити наступне (Модифікація відповіді @ Шардула):

public class ListViewDemoActivity extends AppCompatActivity {
    //LIST OF ARRAY STRINGS WHICH WILL SERVE AS LIST ITEMS
    ArrayList<String> listItems=new ArrayList<String>();

    //DEFINING A STRING ADAPTER WHICH WILL HANDLE THE DATA OF THE LISTVIEW
    ArrayAdapter<String> adapter;

    //RECORDING HOW MANY TIMES THE BUTTON HAS BEEN CLICKED
    int clickCounter=0;
    private ListView mListView;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.activity_list_view_demo);

        if (mListView == null) {
            mListView = (ListView) findViewById(R.id.listDemo);
        }

        adapter=new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1,
                listItems);
        setListAdapter(adapter);
    }

    //METHOD WHICH WILL HANDLE DYNAMIC INSERTION
    public void addItems(View v) {
        listItems.add("Clicked : "+clickCounter++);
        adapter.notifyDataSetChanged();
    }

    protected ListView getListView() {
        if (mListView == null) {
            mListView = (ListView) findViewById(R.id.listDemo);
        }
        return mListView;
    }

    protected void setListAdapter(ListAdapter adapter) {
        getListView().setAdapter(adapter);
    }

    protected ListAdapter getListAdapter() {
        ListAdapter adapter = getListView().getAdapter();
        if (adapter instanceof HeaderViewListAdapter) {
            return ((HeaderViewListAdapter)adapter).getWrappedAdapter();
        } else {
            return adapter;
        }
    }
}

І у вас макет замість використання android:id="@android:id/list"ви можете використовуватиandroid:id="@+id/listDemo"

Тож тепер у вас може бути ListViewвнутрішня норма AppCompatActivity.


12

Код для файлу MainActivity.java.

public class MainActivity extends Activity {

    ListView listview;
    Button Addbutton;
    EditText GetValue;
    String[] ListElements = new String[] {
        "Android",
        "PHP"
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listview = (ListView) findViewById(R.id.listView1);
        Addbutton = (Button) findViewById(R.id.button1);
        GetValue = (EditText) findViewById(R.id.editText1);

        final List < String > ListElementsArrayList = new ArrayList < String >
            (Arrays.asList(ListElements));


        final ArrayAdapter < String > adapter = new ArrayAdapter < String >
            (MainActivity.this, android.R.layout.simple_list_item_1,
                ListElementsArrayList);

        listview.setAdapter(adapter);

        Addbutton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                ListElementsArrayList.add(GetValue.getText().toString());
                adapter.notifyDataSetChanged();
            }
        });
    }
}

Код файлу макета Activity_main.xml.

<RelativeLayout 
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context="com.listviewaddelementsdynamically_android_examples
    .com.MainActivity" >

  <Button
    android:id="@+id/button1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/editText1"
    android:layout_centerHorizontal="true"
    android:text="ADD Values to listview" />

  <EditText
    android:id="@+id/editText1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="26dp"
    android:ems="10"
    android:hint="Add elements listView" />

  <ListView
    android:id="@+id/listView1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/button1"
    android:layout_centerHorizontal="true" >
  </ListView>

</RelativeLayout>

ScreenShot

введіть тут опис зображення


0

Коротка відповідь: коли ви створюєте ListView, ви передаєте йому посилання на дані. Тепер, коли ці дані будуть змінені, це вплине на подання списку і, таким чином, додасть його до нього, після того, як ви зателефонуєте на adapter.notifyDataSetChanged () ;.

Якщо ви використовуєте RecyclerView, оновіть лише останній елемент (якщо ви його додали в кінці списку objs), щоб зберегти пам'ять за допомогою: mAdapter.notifyItemInserted (mItems.size () - 1);


0

Це проста відповідь, як динамічно додавати дані в listview android kotlin

class MainActivity : AppCompatActivity(){

    var listItems = arrayListOf<String>()
    val array = arrayOf("a","b","c","d","e")
    var listView: ListView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.scrollview_layout)

        listItems.add("a")
        listItems.add("b")
        listItems.add("c")
        listItems.add("d")
        listItems.add("e")

        //if you want to add array items to a list you can try this for each loop
        for(items in array)
            listItems.add(items)
        Log.e("TAG","listItems array: $listItems")

    }
}

Тут я просто пояснив два способи, ми можемо це зробити багатьма способами.


Де частина, яку ви додали до ListView?
Onie Maniego

@OnieManiego тут я додав елементи до перегляду списку двома способами, ви бачите, що вище 1. listItems.add ("a") listItems.add ("b") listItems.add ("c") listItems.add ("d ") listItems.add (" e ") Це перший спосіб, який я додав 2. для (елементів у масиві) listItems.add (items) другий спосіб я додав усі елементи з масиву
sirajudheen tk

@ OnieManiego Я сподіваюся, що ви зрозумієте, якщо це корисно вам pls upvote
sirajudheen tk
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.