2010-12-27 15 views
274

Czy ktoś może wyjaśnić lub zaproponować samouczek, aby utworzyć listę w Androidzie?Dynamicznie dodawaj elementy do listyView Android

Oto moje wymagania:

  • powinienem być w stanie dynamicznie dodawać nowe elementy przez naciśnięcie przycisku.
  • Powinien być na tyle prosty, aby zrozumieć (ewentualnie bez żadnych ulepszeń wydajności lub convertview, na przykład)

Wiem, że istnieje sporo pytań na ten temat, zamieszczone tutaj na StackOverflow, ale nie mógł znaleźć wszystko, co mogłoby odpowiedzieć na moje pytanie. Dzięki!

+0

aktualnie najwyższej głosowało odpowiedź od Shardul jest uważana za wysoką jakość i użytkownicy wyrazili czują powinien zostać zaakceptowany. Czy możesz rozważyć akceptację? – Welkie

Odpowiedz

549

Utwórz układ XML pierwszy w res/layout/main.xml folderze Twojego projektu:

<?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> 

Jest to prosty układ z przycisku na górze i widoku listy na dole. Zauważ, że ListView ma identyfikator @android:id/list, który definiuje domyślny ListView, który może być użyty przez ListView.

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 jest domyślny układ lista element dostarczany przez Androida, można użyć tego układu dla non-free skomplikowanych rzeczy.

listItems to lista, która przechowuje dane wyświetlane w ListView. Cała operacja wstawiania i usuwania powinna odbywać się pod numerem listItems; zmiany w listItems powinny zostać odzwierciedlone w widoku. Który jest obsługiwany przez ArrayAdapter<String> adapter, które powinny być zgłaszane przy użyciu:

adapter.notifyDataSetChanged();

adaptera jest tworzony z 3 parametrów: kontekstu, który może być Twoja activity/listactivity; układ twojego indywidualnego elementu listy; i wreszcie listę, która jest faktycznymi danymi, które mają być wyświetlane na liście.

+21

wydaje się, że nie jest zadowolony ;-) – Saqib

+2

Nie rozumiem, w jaki sposób ListView przywiązuje się do naszej aktywności tutaj. – Breedly

+7

@Breedly Ponieważ jest to aktywność ** ListActivity **, a nie **, która ma układ z ListView **. Nie musisz szukać widoku identyfikatora. Jak można przeczytać w Reference: "ListActivity to działanie, które domyślnie zawiera ListView jako jedyny element układu. [...] (it) hostuje obiekt ListView'. Domyślnie metody (jako * setAdapter *, itp.) Są "wewnątrz" klasy. – Fllo

50

zamiast

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

można wywołać bezpośrednio

adapter.add("New Item"); 
+0

jaka jest różnica @ venkat530? Czy to najlepsza praktyka czy ... coś? – gumuruh

+0

@gumuruh sam adapter jest zmienny, dzięki czemu możemy bezpośrednio dodawać lub usuwać obiekty, które będą automatycznie wywoływać notifyDatasetChanged() i getView() listView. Zmniejsza to dodatkowy wiersz kodu. – venkat530

+0

, więc dodając do adaptera automatycznie wywołaj funkcję notifyDatasetChanged()? Rozumiem. Dzięki @ venkat530. Ale co z samą listą? Mam na myśli, powiedzmy, że najpierw stworzył listę tablicową, która służyła jako kontener danych dla adaptera. A teraz po prostu dodaj element bezpośrednio do adaptera zamiast do listy tablic. Czy dane z tablicy zostały zaktualizowane/nietknięte? – gumuruh

39

Po pierwsze, trzeba dodać ListView, takie EditText i przycisk do swojej activity_main.xml.

Teraz, w swojej ActivityMain:

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(); 
     } 
    }); 
} 

Działa to dla mnie, mam nadzieję, że pomógł Ci

+2

Bardzo dobre wyjaśnienie i podziękowania, szczególnie za wyjaśnienie elementu adaptera - który wydaje się magicznie pojawiać się we wszystkich innych przykładach. :) – raddevus

16

Jeśli chcesz mieć ListView w AppCompatActivity zamiast ListActivity, można wykonać następujące czynności (Modyfikacja @ odpowiedź Shardul za):

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; 
     } 
    } 
} 

A wy układ zamiast korzystania android:id="@android:id/list" można użyć android:id="@+id/listDemo"

Teraz możesz mieć ListView wewnątrz normalnego AppCompatActivity.

5

Kod pliku 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(); 
      } 
     }); 
    } 
} 

Kod activity_main.xml pliku układu.

<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

enter image description here

Powiązane problemy